Repository: Kinnay/NintendoClients Branch: master Commit: 55e85dd25b5e Files: 186 Total size: 3.1 MB Directory structure: gitextract_9qevxi15/ ├── .github/ │ ├── FUNDING.yml │ └── workflows/ │ └── testing.yml ├── .gitignore ├── .readthedocs.yml ├── LICENSE ├── README.md ├── docs/ │ ├── changelog.md │ ├── index.md │ ├── reference/ │ │ ├── miis.md │ │ ├── nasc.md │ │ ├── nex/ │ │ │ ├── aauser.md │ │ │ ├── account.md │ │ │ ├── authentication.md │ │ │ ├── backend.md │ │ │ ├── common.md │ │ │ ├── datastore.md │ │ │ ├── datastore_miitopia_3ds.md │ │ │ ├── datastore_smm.md │ │ │ ├── datastore_smm2.md │ │ │ ├── debug.md │ │ │ ├── errors.md │ │ │ ├── friends.md │ │ │ ├── friends_3ds.md │ │ │ ├── health.md │ │ │ ├── hpp.md │ │ │ ├── kerberos.md │ │ │ ├── matchmaking.md │ │ │ ├── matchmaking_eagle.md │ │ │ ├── matchmaking_mhxx.md │ │ │ ├── matchmaking_mk8.md │ │ │ ├── matchmaking_mk8d.md │ │ │ ├── messaging.md │ │ │ ├── monitoring.md │ │ │ ├── natcheck.md │ │ │ ├── nattraversal.md │ │ │ ├── nintendonotification.md │ │ │ ├── notification.md │ │ │ ├── prudp.md │ │ │ ├── ranking.md │ │ │ ├── ranking2.md │ │ │ ├── ranking2_eagle.md │ │ │ ├── ranking_mk8.md │ │ │ ├── ranking_mk8d.md │ │ │ ├── remotelog.md │ │ │ ├── rmc.md │ │ │ ├── screening.md │ │ │ ├── secure.md │ │ │ ├── settings.md │ │ │ ├── streams.md │ │ │ ├── subscriber.md │ │ │ └── utility.md │ │ ├── nnas.md │ │ ├── switch/ │ │ │ ├── aauth.md │ │ │ ├── atumn.md │ │ │ ├── baas.md │ │ │ ├── dauth.md │ │ │ ├── dragons.md │ │ │ ├── five.md │ │ │ └── sun.md │ │ └── switch.md │ └── style.css ├── examples/ │ ├── 3ds/ │ │ └── friends.py │ ├── custom/ │ │ ├── server.py │ │ └── server_login.py │ ├── switch/ │ │ ├── animalcrossing.py │ │ ├── smm2_level.py │ │ ├── smm2_ninji.py │ │ └── system_update.py │ └── wiiu/ │ ├── donkeykong.py │ ├── friends.py │ ├── mariokart.py │ └── miis.py ├── generate_protocols.py ├── mkdocs.yml ├── nintendo/ │ ├── __init__.py │ ├── files/ │ │ ├── cert/ │ │ │ ├── CTR_Common_Prod_1.der │ │ │ ├── CTR_Common_Prod_1.key │ │ │ ├── Nintendo_CA_G3.der │ │ │ ├── Nintendo_Class_2_CA_G3.der │ │ │ ├── Nintendo_Root_CA_G4.der │ │ │ ├── Wii_U_Common_Prod_1.der │ │ │ └── Wii_U_Common_Prod_1.key │ │ ├── config/ │ │ │ ├── 3ds.cfg │ │ │ ├── default.cfg │ │ │ ├── friends.cfg │ │ │ └── switch.cfg │ │ └── proto/ │ │ ├── aauser.proto │ │ ├── account.proto │ │ ├── authentication.proto │ │ ├── datastore.proto │ │ ├── datastore_miitopia_3ds.proto │ │ ├── datastore_smm.proto │ │ ├── datastore_smm2.proto │ │ ├── debug.proto │ │ ├── friends.proto │ │ ├── health.proto │ │ ├── matchmaking.proto │ │ ├── matchmaking_eagle.proto │ │ ├── matchmaking_mhxx.proto │ │ ├── matchmaking_mk8.proto │ │ ├── matchmaking_mk8d.proto │ │ ├── messaging.proto │ │ ├── monitoring.proto │ │ ├── nattraversal.proto │ │ ├── nintendonotification.proto │ │ ├── notification.proto │ │ ├── ranking.proto │ │ ├── ranking2.proto │ │ ├── ranking2_eagle.proto │ │ ├── ranking_mk8.proto │ │ ├── ranking_mk8d.proto │ │ ├── remotelog.proto │ │ ├── screening.proto │ │ ├── secure.proto │ │ ├── subscriber.proto │ │ └── utility.proto │ ├── miis.py │ ├── nasc.py │ ├── nex/ │ │ ├── __init__.py │ │ ├── aauser.py │ │ ├── account.py │ │ ├── authentication.py │ │ ├── backend.py │ │ ├── common.py │ │ ├── datastore.py │ │ ├── datastore_miitopia_3ds.py │ │ ├── datastore_smm.py │ │ ├── datastore_smm2.py │ │ ├── debug.py │ │ ├── errors.py │ │ ├── friends.py │ │ ├── health.py │ │ ├── hpp.py │ │ ├── kerberos.py │ │ ├── matchmaking.py │ │ ├── matchmaking_eagle.py │ │ ├── matchmaking_mhxx.py │ │ ├── matchmaking_mk8.py │ │ ├── matchmaking_mk8d.py │ │ ├── messaging.py │ │ ├── monitoring.py │ │ ├── natcheck.py │ │ ├── nattraversal.py │ │ ├── nintendonotification.py │ │ ├── notification.py │ │ ├── prudp.py │ │ ├── ranking.py │ │ ├── ranking2.py │ │ ├── ranking2_eagle.py │ │ ├── ranking_mk8.py │ │ ├── ranking_mk8d.py │ │ ├── remotelog.py │ │ ├── rmc.py │ │ ├── screening.py │ │ ├── secure.py │ │ ├── settings.py │ │ ├── streams.py │ │ ├── subscriber.py │ │ └── utility.py │ ├── nnas.py │ ├── resources.py │ └── switch/ │ ├── __init__.py │ ├── aauth.py │ ├── atumn.py │ ├── baas.py │ ├── common.py │ ├── dauth.py │ ├── dragons.py │ ├── five.py │ └── sun.py ├── setup.py └── tests/ ├── nex/ │ ├── test_backend.py │ ├── test_common.py │ ├── test_errors.py │ ├── test_kerberos.py │ ├── test_nex_streams.py │ ├── test_prudp.py │ ├── test_rmc.py │ └── test_settings.py └── switch/ ├── test_aauth.py ├── test_atumn.py ├── test_baas.py ├── test_dauth.py ├── test_dragons.py ├── test_five.py └── test_sun.py ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/FUNDING.yml ================================================ # These are supported funding model platforms github: [kinnay] ================================================ FILE: .github/workflows/testing.yml ================================================ name: Pytest on: push: branches: [master, main] pull_request: branches: [master, main] jobs: pytest: runs-on: ubuntu-latest name: Check code with Pytest steps: - uses: actions/checkout@v4 - name: Install Python uses: actions/setup-python@v5 with: python-version: "3.11" - name: Install dependencies run: | python -m pip install --upgrade pip pip install pytest trio pip install . - name: Run Pytest run: pytest ================================================ FILE: .gitignore ================================================ /*.egg-info/ __pycache__/ /build/ /dist/ /site/ /private/ /*.bin /*.jpg ================================================ FILE: .readthedocs.yml ================================================ # Read the Docs configuration file for MkDocs projects # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details # Required version: 2 # Set the version of Python and other tools you might need build: os: ubuntu-22.04 tools: python: "3.11" mkdocs: configuration: mkdocs.yml ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2017 Yannik Marchand Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # Nintendo Clients > :warning: Keep in mind that Nintendo bans Switch devices that show suspicious behavior. This package tries to mimic the behavior of a real Switch as closely as possible, but using it is at your own risk. Make sure that you know what you are doing. This package implements a client for various 3DS, Wii U and Switch servers. Check out the [documentation](https://nintendoclients.readthedocs.io) for the list of servers that are currently supported. For Switch servers, the latest system version that is currently supported is **22.1.0**. For talk about research, feel free to join the [Discord server](https://discord.gg/x8np6Hhxwk) or open a [discussion](https://github.com/kinnay/NintendoClients/discussions) on GitHub. ### Installation This package requires Python 3.8 or later and can be installed with pip: `pip install nintendoclients`. This package uses [semantic versioning](https://semver.org/). ### Documentation * [Nintendo's servers and protocols](https://github.com/Kinnay/NintendoClients/wiki) * [The classes and functions in this package](https://nintendoclients.readthedocs.io) ### Example scripts * **switch/** * **smm2_level.py:** Downloads a Super Mario Maker 2 level and its thumbnails, and prints information about both the level and its creator. * **smm2_ninji.py:** Requests the list of ninji courses and downloads a replay file. * **animalcrossing.py:** Searches for an island by dodo code and prints information about it. * **system_update.py:** Downloads the latest system update and unpacks it into exefs and romfs.

* **wiiu/** * **donkeykong.py:** Downloads DKC Tropical Freeze rankings and the replay file of the world record. * **mariokart.py:** Downloads Mario Kart 8 rankings and the replay file of whoever is in 500th place. * **miis.py:** Requests all kinds of information about the primary mii associated with a NNID. * **friends.py:** Requests your friend list, incoming and outgoing friend requests, and blacklist.

* **3ds/** * **friends.py:** Changes your comment to 'Hello World'.

* **custom/** * **server.py:** Shows how to create a simple game server with both an authentication server and a secure server. * **server_login.py:** Logs in on a game server and disconnects immediately. This can be used to test custom servers. ### Sponsorship Consider becoming a [sponsor](https://github.com/sponsors/kinnay) if you would like to support this project. If you become a sponsor, I will be able to spend more time on this project, which will lead to faster updates. In addition, you will be given priority for personal support and feature suggestions. ================================================ FILE: docs/changelog.md ================================================ ## Changelog ### 4.4.0 * Added support for Switch system version 22.0.0 and 22.1.0. *Released on 2026-04-14* ### 4.3.0 * Added support for Switch system version 21.2.0. *Released on 2026-01-15* ### 4.2.0 * **Bug fix:** fix `MatchmakeSession` structure being parsed incorrectly on Nintendo Switch. * **Bug fix:** make a distinction between `AnyDataHolder` and `GatheringHolder` structures in NEX. * Added support for Switch system version 20.5.0 up to 21.1.0. * Added names for previously unknown fields in the `SimpleSearchObject` structure of MK8D. *Released on 2026-01-02* ### 4.1.0 * Added support for Switch system version 20.2.0 up to 20.4.0. * Added support for the matchmaking protocol of Monster Hunter XX (3DS). * Implemented RankingClient::GetScorePack for MK8D. * Minor bug fixes. *Released on 2025-09-19* ### 4.0.2 * Disable `device_token` and `edge_token` on system version 20.0.0 and later to avoid accidental usage. *Released on 2025-06-21* ### 4.0.1 * **Bug fix:** using `device_token` or `edge_token` on system version 20.0.0 and later would send an invalid request to the server. This is now fixed. **NOTE:** It is recommended to use one of the `preload_*` functions or the `DAuthCache` class on system version 20.0.0 and later, to mimic the behavior of a real Switch. *Released on 2025-06-21* ### 4.0.0 * **Breaking change:** some unknown fields in the `nintendo.nex.friends` module were given a name. If you were using the placeholder names in your code, update your code to use the new names. * Added support for Switch system version 20.0.0 up to 20.1.5. * Added various client ids for dauth, such as `er`, `sprofile` and `penne`. * Implemented a dauth cache that mimics the preloading behavior that was introduced in 20.0.0. * Added support for the ranking and matchmaking protocols of Mario Kart 8 (Wii U). *Released on 2025-06-21* ### 3.0.3 * **Bug fix:** fixed typo, changed `BANNED_DEIVCE` to `BANNED_DEVICE` in `DAuthError` class. *Released on 2024-12-28* ### 3.0.2 * **Bug fix:** fixed base64 decoding of dauth challenge. This fixes a bug that caused dauth to fail after a recent server update. *Released on 2024-12-26* ### 3.0.1 * **Bug fix:** 19.0.1 support was missing in the previous release. *Released on 2024-12-02* ### 3.0.0 * **Breaking change:** replaced `pkg_resources` by `importlib.resources`. This increases the minimum Python version to 3.11. * **Bug fix**: removed ampersand before `device_auth_token` parameter in aauth challenge requests for 18.0.0+. * **Bug fix**: added missing `naCountry` parameter to baas login requests for 18.0.0+. * Added support for system version 19.0.0 and 19.0.1. *Released on 2024-12-02* ### 2.2.1 * Fixed the header order in the dauth flow for system version 18.0.0 and later. *Released on 2024-08-06* ### 2.2.0 * Added support for system version 18.1.0. *Released on 2024-06-29* ### 2.1.0 * Added support for system version 17.0.1, 18.0.0 and 18.0.1. * Added support for Switch gamecard authentication. * Added support for the data store protocol of Miitopia 3DS. *Released on 2024-05-04* ### 2.0.1 * **Bug fix**: added `nintendo.switch` to setup.py. The whole `nintendo.switch` folder was missing in the previous release. *Released on 2023-11-12* ### 2.0.0 * **Breaking change:** moved all Switch-related clients into their own namespace. For example, `nintendo.dauth` is now `nintendo.switch.dauth`. * **Breaking change:** dauth client ids are now global constants instead of members of `DAuthClient`. * Implemented a client for the sun server (system update metadata). * Implemented a client for the atumn server (system update content). *Released on 2023-10-29* ### 1.1.0 * Added support for system version 17.0.0. * Added default values to `RankingOrderParam.offset` and `RankingOrderParam.count`. *Released on 2023-10-19* ### 1.0.0 First release with a changelog. Currently, the package implements everything that is required to communicate with NEX servers. *Released on 2023-10-13* ================================================ FILE: docs/index.md ================================================ ## Welcome to NintendoClients This package lets you communicate with various 3DS, Wii U and Switch servers. For documentation about the servers and protocols click [here](https://github.com/kinnay/nintendo/wiki). * [Features](#features) * [Contributing](#contributing) * [API Reference](#api-reference) * [Changelog](changelog.md) ## Features This package is able to do everything that's required to access a game server. It also provides a framework to host your own game servers. For example scripts, check out the [github repository](https://github.com/kinnay/nintendo). The following servers are currently supported: * Switch: * Game servers (`nex`) * https://dauth-lp1.ndas.srv.nintendo.net * https://aauth-lp1.ndas.srv.nintendo.net * https://aauth.hac.lp1.ndas.srv.nintendo.net * https://dragons.hac.lp1.dragons.nintendo.net * https://e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com * https://app.lp1.five.nintendo.net * https://sun.hac.lp1.d4c.nintendo.net * https://atumn.hac.lp1.d4c.nintendo.net * Wii U: * Game servers (`nex`) * https://account.nintendo.net * 3DS: * Game servers (`nex`) * https://nasc.nintendowifi.net ## Contributing Feel free to open a pull request or issue on [github](https://github.com/kinnay/nintendo). If you open a pull request, please try to follow the current code style as much as possible, and consider writing a test for new features and bug fixes. ## API Reference * nex * [aauser](reference/nex/aauser.md) * [account](reference/nex/account.md) * [authentication](reference/nex/authentication.md) * [backend](reference/nex/backend.md) * [common](reference/nex/common.md) * [datastore](reference/nex/datastore.md) * [datastore_smm](reference/nex/datastore_smm.md) * [datastore_smm2](reference/nex/datastore_smm2.md) * [debug](reference/nex/debug.md) * [errors](reference/nex/errors.md) * [friends](reference/nex/friends.md) * [health](reference/nex/health.md) * [hpp](reference/nex/hpp.md) * [kerberos](reference/nex/kerberos.md) * [matchmaking](reference/nex/matchmaking.md) * [matchmaking_eagle](reference/nex/matchmaking_eagle.md) * [messaging](reference/nex/messaging.md) * [monitoring](reference/nex/monitoring.md) * [nattraversal](reference/nex/nattraversal.md) * [nintendonotification](reference/nex/nintendonotification.md) * [notification](reference/nex/notification.md) * [prudp](reference/nex/prudp.md) * [ranking](reference/nex/ranking.md) * [ranking2](reference/nex/ranking2.md) * [remotelog](reference/nex/remotelog.md) * [rmc](reference/nex/rmc.md) * [screening](reference/nex/screening.md) * [secure](reference/nex/secure.md) * [streams](reference/nex/streams.md) * [subscriber](reference/nex/subscriber.md) * [utility](reference/nex/utility.md) * [switch](reference/switch.md) * [aauth](reference/switch/aauth.md) * [atumn](reference/switch/atumn.md) * [baas](reference/switch/baas.md) * [dauth](reference/switch/dauth.md) * [dragons](reference/switch/dragons.md) * [five](reference/switch/five.md) * [sun](reference/switch/sun.md) * [miis](reference/miis.md) * [nasc](reference/nasc.md) * [nnas](reference/nnas.md) ================================================ FILE: docs/reference/miis.md ================================================ # Module: nintendo.miis Provides a parser for FFL mii data. **class** [MiiData](#miidata)
The mii data class. ## MiiData `birth_platform: int`
`mii_version: int`
`font_region: int`
`region_move: int`
`copyable: bool`
`local_only: bool`
`author_id: list[int]`
`mii_id: list[int]`
`color: int`
`birth_day: int`
`birth_month: int`
`gender: bool`
`mii_name: str`
`creator_name: str`
`size: int`
`fatness: int`
`blush_type: int`
`face_style: int`
`face_color: int`
`face_type: int`
`hair_mirrored: bool`
`hair_color: int`
`hair_type: int` `eye_thickness: int`
`eye_scale: int`
`eye_color: int`
`eye_type: int`
`eye_height: int`
`eye_distance: int`
`eye_rotation: int` `eyebrow_thickness: int`
`eyebrow_scale: int`
`eyebrow_color: int`
`eyebrow_type: int`
`eyebrow_height: int`
`eyebrow_distance: int`
`eyebrow_rotation: int` `nose_height: int`
`nose_scale: int`
`nose_type: int` `mouth_thickness: int`
`mouth_scale: int`
`mouth_color: int`
`mouth_type: int`
`mouth_height: int` `mustache_type: int`
`mustache_height: int`
`mustache_scale: int` `beard_color: int`
`beard_type: int` `glass_height: int`
`glass_scale: int`
`glass_color: int`
`glass_type: int` `mole_ypos: int`
`mole_xpos: int`
`mole_scale: int`
`mole_enabled: bool` **def _\_init__**()
Creates a new mii instance. **def build**() -> bytes
Encodes the mii data. @classmethod
**def parse**(data: bytes) -> [MiiData](#miidata)
Parses the given mii data. ================================================ FILE: docs/reference/nasc.md ================================================ # Module: nintendo.nasc Provides a client for [nasc.nintendowifi.net](https://github.com/kinnay/nintendo/wiki/NASC-Server). **class** [NASCError](#nascerror)(Exception)
Raised when the server returns an error code. **class** [NASCClient](#nascclient)
The NASC client. ## Global Constants `MEDIA_TYPE_SYSTEM = 0`
`MEDIA_TYPE_DIGITAL = 1`
`MEDIA_TYPE_CARTRIDGE = 2` ## NASCError This exception is raised when the server returns an error code. `status_code: int`
`return_code: int | None`
`retry: bool`
`datetime: datetime.datetime` ## NASCClient **def _\_init__**()
Creates a new NASC client. **def set_context**(context: [TLSContext](https://anynet.readthedocs.io/en/latest/reference/tls/#tlscontext)) -> None
Changes the TLS context. By default, the server certificate is verified with `Nintendo CA - G3`, and `CTR Common Prod 1` is used as the client certificate. **def set_url**(url: str) -> None
Changes the server to which requests are sent. The default is `nasc.nintendowifi.net`. **def set_environment**(environment: str) -> None
Changes the `servertype` parameter. The default is `"L1"` (production). **def set_title**(title_id: int, title_version: int, product_code: str = "----", maker_code: str = "00", media_type: int = MEDIA_TYPE_SYSTEM, rom_id: bytes = None) -> None
Configures the current title. The `rom_id` is required only for cartridges. This is required for calls to `login`. **def set_device**(serial_number: str, mac_address: str, fcd_cert: bytes, name: str = "", unit_code: str = "2") -> None
Configures the device. This is required for calls to `login`. **def set_network**(bss_id: str, ap_info: str) -> None
Changes the `bssid` and `ap_info` parameters. By default, the `bssid` is random and `ap_info` is `01:0000000000`. **def set_locale**(region: int, language: int) -> None
Changes the `region` and `language` parameters. **def set_user**(pid: int, pid_hmac: str) -> None
Configures the user for logging in. Either `set_user` or `set_password` must be called before `login`. **def set_password**(password: str) -> None
Configures the `passwd` parameter. Either `set_user` or `set_password` must be called before `login`. **def set_sdk_version**(major_version: int, minor_version: int) -> None
Changes the content of the `sdkver` parameter. The default is `000000`. **def set_fpd_version**(version: int) -> None
Changes the content of the `fpdver` parameter and user agent. The default is `15`. **async def login**(game_server_id: int, nickname: str = "") -> [LoginResponse](#loginresponse)
Calls the `LOGIN` action on the server and returns the response or raises an exception. ## LoginResponse `host: str`
`port: int`
`token: str`
`datetime: datetime.datetime` ================================================ FILE: docs/reference/nex/aauser.md ================================================ # Module: nintendo.nex.aauser Provides a client and server for the `AAUserProtocol`. This page was generated automatically from `aauser.proto`. **class** [AAUserClient](#aauserclient)
The client for the `AAUserProtocol`. **class** [AAUserServer](#aauserserver)
The server for the `AAUserProtocol`. **class** [ApplicationInfo](#applicationinfo)([Structure](common.md))
## AAUserClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`AAUserClient`](#aauserclient). **async def register_application**(title_id: int) -> None
Calls method `1` on the server. **async def unregister_application**(title_id: int) -> None
Calls method `2` on the server. **async def set_application_info**(application_info: list[[ApplicationInfo](#applicationinfo)]) -> None
Calls method `3` on the server. **async def get_application_info**() -> list[[ApplicationInfo](#applicationinfo)]
Calls method `4` on the server. ## AAUserServer **def _\_init__**()
Creates a new [`AAUserServer`](#aauserserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def register_application**(client: [RMCClient](rmc.md#rmcclient), title_id: int) -> None
Handler for method `1`. This method should be overridden by a subclass. **async def unregister_application**(client: [RMCClient](rmc.md#rmcclient), title_id: int) -> None
Handler for method `2`. This method should be overridden by a subclass. **async def set_application_info**(client: [RMCClient](rmc.md#rmcclient), application_info: list[[ApplicationInfo](#applicationinfo)]) -> None
Handler for method `3`. This method should be overridden by a subclass. **async def get_application_info**(client: [RMCClient](rmc.md#rmcclient)) -> list[[ApplicationInfo](#applicationinfo)]
Handler for method `4`. This method should be overridden by a subclass. ## ApplicationInfo **def _\_init__**()
Creates a new `ApplicationInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
title_id: int
title_version: int

================================================ FILE: docs/reference/nex/account.md ================================================ # Module: nintendo.nex.account Provides a client and server for the `AccountProtocol`. This page was generated automatically from `account.proto`. **class** [AccountClient](#accountclient)
The client for the `AccountProtocol`. **class** [AccountServer](#accountserver)
The server for the `AccountProtocol`. **class** [AccountData](#accountdata)([Structure](common.md))
**class** [BasicAccountInfo](#basicaccountinfo)([Structure](common.md))
## AccountClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`AccountClient`](#accountclient). **async def create_account**(name: str, key: str, groups: int, email: str) -> [Result](common.md#result)
Calls method `1` on the server. **async def delete_account**(pid: int) -> None
Calls method `2` on the server. **async def disable_account**(pid: int, until: [DateTime](common.md#datetime), message: str) -> [Result](common.md#result)
Calls method `3` on the server. **async def change_password**(new_key: str) -> bool
Calls method `4` on the server. **async def test_capability**(capability: int) -> bool
Calls method `5` on the server. **async def get_name**(pid: int) -> str
Calls method `6` on the server. **async def get_account_data**() -> [RMCResponse](common.md)
Calls method `7` on the server. The RMC response has the following attributes:
result: [Result](common.md#result)
data: [AccountData](#accountdata)
**async def get_private_data**() -> [RMCResponse](common.md)
Calls method `8` on the server. The RMC response has the following attributes:
result: bool
data: [Data](common.md)
**async def get_public_data**(pid: int) -> [RMCResponse](common.md)
Calls method `9` on the server. The RMC response has the following attributes:
result: bool
data: [Data](common.md)
**async def get_multiple_public_data**(pids: list[int]) -> [RMCResponse](common.md)
Calls method `10` on the server. The RMC response has the following attributes:
result: bool
data: list[[Data](common.md)]
**async def update_account_name**(name: str) -> [Result](common.md#result)
Calls method `11` on the server. **async def update_account_email**(email: str) -> [Result](common.md#result)
Calls method `12` on the server. **async def update_custom_data**(public_data: [Data](common.md), private_data: [Data](common.md)) -> [Result](common.md#result)
Calls method `13` on the server. **async def find_by_name_regex**(groups: int, regex: str, range: [ResultRange](common.md#resultrange)) -> list[[BasicAccountInfo](#basicaccountinfo)]
Calls method `14` on the server. **async def update_account_expiry_date**(pid: int, expiry: [DateTime](common.md#datetime), message: str) -> None
Calls method `15` on the server. **async def update_account_effective_date**(pid: int, effective_from: [DateTime](common.md#datetime), message: str) -> None
Calls method `16` on the server. **async def update_status**(status: str) -> None
Calls method `17` on the server. **async def get_status**(pid: int) -> str
Calls method `18` on the server. **async def get_last_connection_stats**(pid: int) -> [RMCResponse](common.md)
Calls method `19` on the server. The RMC response has the following attributes:
last_session_login: [DateTime](common.md#datetime)
last_session_logout: [DateTime](common.md#datetime)
current_session_login: [DateTime](common.md#datetime)
**async def reset_password**() -> bool
Calls method `20` on the server. **async def create_account_with_custom_data**(name: str, key: str, groups: int, email: str, public_data: [Data](common.md), private_data: [Data](common.md)) -> None
Calls method `21` on the server. **async def retrieve_account**() -> [RMCResponse](common.md)
Calls method `22` on the server. The RMC response has the following attributes:
account_data: [AccountData](#accountdata)
public_data: [Data](common.md)
private_data: [Data](common.md)
**async def update_account**(key: str, email: str, public_data: [Data](common.md), private_data: [Data](common.md)) -> None
Calls method `23` on the server. **async def change_password_by_guest**(name: str, email: str, key: str) -> None
Calls method `24` on the server. **async def find_by_name_like**(groups: int, like: str, range: [ResultRange](common.md#resultrange)) -> list[[BasicAccountInfo](#basicaccountinfo)]
Calls method `25` on the server. **async def custom_create_account**(name: str, key: str, groups: int, email: str, auth_data: [Data](common.md)) -> int
Calls method `26` on the server. **async def nintendo_create_account**(name: str, key: str, groups: int, email: str, auth_data: [Data](common.md)) -> [RMCResponse](common.md)
Calls method `27` on the server. The RMC response has the following attributes:
pid: int
pid_hmac: str
**async def lookup_or_create_account**(name: str, key: str, groups: int, email: str, auth_data: [Data](common.md)) -> int
Calls method `28` on the server. **async def disconnect_principal**(pid: int) -> bool
Calls method `29` on the server. **async def disconnect_all_principals**() -> bool
Calls method `30` on the server. ## AccountServer **def _\_init__**()
Creates a new [`AccountServer`](#accountserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def create_account**(client: [RMCClient](rmc.md#rmcclient), name: str, key: str, groups: int, email: str) -> [Result](common.md#result)
Handler for method `1`. This method should be overridden by a subclass. **async def delete_account**(client: [RMCClient](rmc.md#rmcclient), pid: int) -> None
Handler for method `2`. This method should be overridden by a subclass. **async def disable_account**(client: [RMCClient](rmc.md#rmcclient), pid: int, until: [DateTime](common.md#datetime), message: str) -> [Result](common.md#result)
Handler for method `3`. This method should be overridden by a subclass. **async def change_password**(client: [RMCClient](rmc.md#rmcclient), new_key: str) -> bool
Handler for method `4`. This method should be overridden by a subclass. **async def test_capability**(client: [RMCClient](rmc.md#rmcclient), capability: int) -> bool
Handler for method `5`. This method should be overridden by a subclass. **async def get_name**(client: [RMCClient](rmc.md#rmcclient), pid: int) -> str
Handler for method `6`. This method should be overridden by a subclass. **async def get_account_data**(client: [RMCClient](rmc.md#rmcclient)) -> [RMCResponse](common.md)
Handler for method `7`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: [Result](common.md#result)
data: [AccountData](#accountdata)
**async def get_private_data**(client: [RMCClient](rmc.md#rmcclient)) -> [RMCResponse](common.md)
Handler for method `8`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
data: [Data](common.md)
**async def get_public_data**(client: [RMCClient](rmc.md#rmcclient), pid: int) -> [RMCResponse](common.md)
Handler for method `9`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
data: [Data](common.md)
**async def get_multiple_public_data**(client: [RMCClient](rmc.md#rmcclient), pids: list[int]) -> [RMCResponse](common.md)
Handler for method `10`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
data: list[[Data](common.md)]
**async def update_account_name**(client: [RMCClient](rmc.md#rmcclient), name: str) -> [Result](common.md#result)
Handler for method `11`. This method should be overridden by a subclass. **async def update_account_email**(client: [RMCClient](rmc.md#rmcclient), email: str) -> [Result](common.md#result)
Handler for method `12`. This method should be overridden by a subclass. **async def update_custom_data**(client: [RMCClient](rmc.md#rmcclient), public_data: [Data](common.md), private_data: [Data](common.md)) -> [Result](common.md#result)
Handler for method `13`. This method should be overridden by a subclass. **async def find_by_name_regex**(client: [RMCClient](rmc.md#rmcclient), groups: int, regex: str, range: [ResultRange](common.md#resultrange)) -> list[[BasicAccountInfo](#basicaccountinfo)]
Handler for method `14`. This method should be overridden by a subclass. **async def update_account_expiry_date**(client: [RMCClient](rmc.md#rmcclient), pid: int, expiry: [DateTime](common.md#datetime), message: str) -> None
Handler for method `15`. This method should be overridden by a subclass. **async def update_account_effective_date**(client: [RMCClient](rmc.md#rmcclient), pid: int, effective_from: [DateTime](common.md#datetime), message: str) -> None
Handler for method `16`. This method should be overridden by a subclass. **async def update_status**(client: [RMCClient](rmc.md#rmcclient), status: str) -> None
Handler for method `17`. This method should be overridden by a subclass. **async def get_status**(client: [RMCClient](rmc.md#rmcclient), pid: int) -> str
Handler for method `18`. This method should be overridden by a subclass. **async def get_last_connection_stats**(client: [RMCClient](rmc.md#rmcclient), pid: int) -> [RMCResponse](common.md)
Handler for method `19`. This method should be overridden by a subclass. The RMC response must have the following attributes:
last_session_login: [DateTime](common.md#datetime)
last_session_logout: [DateTime](common.md#datetime)
current_session_login: [DateTime](common.md#datetime)
**async def reset_password**(client: [RMCClient](rmc.md#rmcclient)) -> bool
Handler for method `20`. This method should be overridden by a subclass. **async def create_account_with_custom_data**(client: [RMCClient](rmc.md#rmcclient), name: str, key: str, groups: int, email: str, public_data: [Data](common.md), private_data: [Data](common.md)) -> None
Handler for method `21`. This method should be overridden by a subclass. **async def retrieve_account**(client: [RMCClient](rmc.md#rmcclient)) -> [RMCResponse](common.md)
Handler for method `22`. This method should be overridden by a subclass. The RMC response must have the following attributes:
account_data: [AccountData](#accountdata)
public_data: [Data](common.md)
private_data: [Data](common.md)
**async def update_account**(client: [RMCClient](rmc.md#rmcclient), key: str, email: str, public_data: [Data](common.md), private_data: [Data](common.md)) -> None
Handler for method `23`. This method should be overridden by a subclass. **async def change_password_by_guest**(client: [RMCClient](rmc.md#rmcclient), name: str, email: str, key: str) -> None
Handler for method `24`. This method should be overridden by a subclass. **async def find_by_name_like**(client: [RMCClient](rmc.md#rmcclient), groups: int, like: str, range: [ResultRange](common.md#resultrange)) -> list[[BasicAccountInfo](#basicaccountinfo)]
Handler for method `25`. This method should be overridden by a subclass. **async def custom_create_account**(client: [RMCClient](rmc.md#rmcclient), name: str, key: str, groups: int, email: str, auth_data: [Data](common.md)) -> int
Handler for method `26`. This method should be overridden by a subclass. **async def nintendo_create_account**(client: [RMCClient](rmc.md#rmcclient), name: str, key: str, groups: int, email: str, auth_data: [Data](common.md)) -> [RMCResponse](common.md)
Handler for method `27`. This method should be overridden by a subclass. The RMC response must have the following attributes:
pid: int
pid_hmac: str
**async def lookup_or_create_account**(client: [RMCClient](rmc.md#rmcclient), name: str, key: str, groups: int, email: str, auth_data: [Data](common.md)) -> int
Handler for method `28`. This method should be overridden by a subclass. **async def disconnect_principal**(client: [RMCClient](rmc.md#rmcclient), pid: int) -> bool
Handler for method `29`. This method should be overridden by a subclass. **async def disconnect_all_principals**(client: [RMCClient](rmc.md#rmcclient)) -> bool
Handler for method `30`. This method should be overridden by a subclass. ## AccountData **def _\_init__**()
Creates a new `AccountData` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
name: str
groups: int
email: str
creation_date: [DateTime](common.md#datetime)
effective_date: [DateTime](common.md#datetime)
not_effective_message: str
expiry_date: [DateTime](common.md#datetime)
expired_message: str

## BasicAccountInfo **def _\_init__**()
Creates a new `BasicAccountInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
name: str

================================================ FILE: docs/reference/nex/authentication.md ================================================ # Module: nintendo.nex.authentication Provides a client and server for the `AuthenticationProtocol` and `AuthenticationProtocolNX`. This page was generated automatically from `authentication.proto`. **class** [AuthenticationClient](#authenticationclient)
The client for the `AuthenticationProtocol`. **class** [AuthenticationClientNX](#authenticationclientnx)
The client for the `AuthenticationProtocolNX`. **class** [AuthenticationServer](#authenticationserver)
The server for the `AuthenticationProtocol`. **class** [AuthenticationServerNX](#authenticationservernx)
The server for the `AuthenticationProtocolNX`. **class** [AuthenticationInfo](#authenticationinfo)([Data](common.md))
**class** [RVConnectionData](#rvconnectiondata)([Structure](common.md))
**class** [ValidateAndRequestTicketParam](#validateandrequestticketparam)([Structure](common.md))
**class** [ValidateAndRequestTicketResult](#validateandrequestticketresult)([Structure](common.md))
## AuthenticationClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`AuthenticationClient`](#authenticationclient). **async def login**(username: str) -> [RMCResponse](common.md)
Calls method `1` on the server. The RMC response has the following attributes:
result: [Result](common.md#result)
pid: int
ticket: bytes
connection_data: [RVConnectionData](#rvconnectiondata)
server_name: str
**async def login_ex**(username: str, extra_data: [Data](common.md)) -> [RMCResponse](common.md)
Calls method `2` on the server. The RMC response has the following attributes:
result: [Result](common.md#result)
pid: int
ticket: bytes
connection_data: [RVConnectionData](#rvconnectiondata)
server_name: str
**async def request_ticket**(source: int, target: int) -> [RMCResponse](common.md)
Calls method `3` on the server. The RMC response has the following attributes:
result: [Result](common.md#result)
ticket: bytes
**async def get_pid**(username: str) -> int
Calls method `4` on the server. **async def get_name**(pid: int) -> str
Calls method `5` on the server. **async def login_with_context**(login_data: [Data](common.md)) -> [RMCResponse](common.md)
Calls method `6` on the server. The RMC response has the following attributes:
result: [Result](common.md#result)
pid: int
ticket: bytes
connection_data: [RVConnectionData](#rvconnectiondata)
## AuthenticationClientNX **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`AuthenticationClientNX`](#authenticationclientnx). **async def validate_and_request_ticket**(username: str) -> [RMCResponse](common.md)
Calls method `1` on the server. The RMC response has the following attributes:
result: [Result](common.md#result)
pid: int
ticket: bytes
connection_data: [RVConnectionData](#rvconnectiondata)
server_name: str
**async def validate_and_request_ticket_with_custom_data**(username: str, extra_data: [Data](common.md)) -> [RMCResponse](common.md)
Calls method `2` on the server. The RMC response has the following attributes:
result: [Result](common.md#result)
pid: int
ticket: bytes
connection_data: [RVConnectionData](#rvconnectiondata)
server_name: str
source_key: str
**async def request_ticket**(source: int, target: int) -> [RMCResponse](common.md)
Calls method `3` on the server. The RMC response has the following attributes:
result: [Result](common.md#result)
ticket: bytes
key: str
**async def get_pid**(username: str) -> int
Calls method `4` on the server. **async def get_name**(pid: int) -> str
Calls method `5` on the server. **async def validate_and_request_ticket_with_param**(param: [ValidateAndRequestTicketParam](#validateandrequestticketparam)) -> [ValidateAndRequestTicketResult](#validateandrequestticketresult)
Calls method `6` on the server. ## AuthenticationServer **def _\_init__**()
Creates a new [`AuthenticationServer`](#authenticationserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def login**(client: [RMCClient](rmc.md#rmcclient), username: str) -> [RMCResponse](common.md)
Handler for method `1`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: [Result](common.md#result)
pid: int
ticket: bytes
connection_data: [RVConnectionData](#rvconnectiondata)
server_name: str
**async def login_ex**(client: [RMCClient](rmc.md#rmcclient), username: str, extra_data: [Data](common.md)) -> [RMCResponse](common.md)
Handler for method `2`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: [Result](common.md#result)
pid: int
ticket: bytes
connection_data: [RVConnectionData](#rvconnectiondata)
server_name: str
**async def request_ticket**(client: [RMCClient](rmc.md#rmcclient), source: int, target: int) -> [RMCResponse](common.md)
Handler for method `3`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: [Result](common.md#result)
ticket: bytes
**async def get_pid**(client: [RMCClient](rmc.md#rmcclient), username: str) -> int
Handler for method `4`. This method should be overridden by a subclass. **async def get_name**(client: [RMCClient](rmc.md#rmcclient), pid: int) -> str
Handler for method `5`. This method should be overridden by a subclass. **async def login_with_context**(client: [RMCClient](rmc.md#rmcclient), login_data: [Data](common.md)) -> [RMCResponse](common.md)
Handler for method `6`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: [Result](common.md#result)
pid: int
ticket: bytes
connection_data: [RVConnectionData](#rvconnectiondata)
## AuthenticationServerNX **def _\_init__**()
Creates a new [`AuthenticationServerNX`](#authenticationservernx). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def validate_and_request_ticket**(client: [RMCClient](rmc.md#rmcclient), username: str) -> [RMCResponse](common.md)
Handler for method `1`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: [Result](common.md#result)
pid: int
ticket: bytes
connection_data: [RVConnectionData](#rvconnectiondata)
server_name: str
**async def validate_and_request_ticket_with_custom_data**(client: [RMCClient](rmc.md#rmcclient), username: str, extra_data: [Data](common.md)) -> [RMCResponse](common.md)
Handler for method `2`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: [Result](common.md#result)
pid: int
ticket: bytes
connection_data: [RVConnectionData](#rvconnectiondata)
server_name: str
source_key: str
**async def request_ticket**(client: [RMCClient](rmc.md#rmcclient), source: int, target: int) -> [RMCResponse](common.md)
Handler for method `3`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: [Result](common.md#result)
ticket: bytes
key: str
**async def get_pid**(client: [RMCClient](rmc.md#rmcclient), username: str) -> int
Handler for method `4`. This method should be overridden by a subclass. **async def get_name**(client: [RMCClient](rmc.md#rmcclient), pid: int) -> str
Handler for method `5`. This method should be overridden by a subclass. **async def validate_and_request_ticket_with_param**(client: [RMCClient](rmc.md#rmcclient), param: [ValidateAndRequestTicketParam](#validateandrequestticketparam)) -> [ValidateAndRequestTicketResult](#validateandrequestticketresult)
Handler for method `6`. This method should be overridden by a subclass. ## AuthenticationInfo **def _\_init__**()
Creates a new `AuthenticationInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
token: str
ngs_version: int = 3
token_type: int = 1
server_version: int = 0

## RVConnectionData **def _\_init__**()
Creates a new `RVConnectionData` instance. Required fields must be filled in manually. The following fields are defined in this class:
main_station: [StationURL](common.md#stationurl) = "prudp:/"
special_protocols: list[int] = []
special_station: [StationURL](common.md#stationurl) = "prudp:/"
If `nex.version` >= 30500:
If `revision` >= 1:
server_time: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).never()



## ValidateAndRequestTicketParam **def _\_init__**()
Creates a new `ValidateAndRequestTicketParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
platform: int = 3
username: str
data: [Data](common.md)
skip_version_check: bool = False
nex_version: int
client_version: int

## ValidateAndRequestTicketResult **def _\_init__**()
Creates a new `ValidateAndRequestTicketResult` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
ticket: bytes
server_url: [StationURL](common.md#stationurl)
server_time: [DateTime](common.md#datetime)
server_name: str
source_key: str

================================================ FILE: docs/reference/nex/backend.md ================================================ # Module: nintendo.nex.backend Provides a client for game servers. **class** [BackEndClient](#backendclient)
The game server client. **async with connect**(settings: [Settings](settings.md#settings), host: str, port: int) -> [BackEndClient](#backendclient)
Establishes a connection with the authentication server at the given address. Blocks until the connection is ready. ## BackEndClient auth_client: [RMCClient](rmc.md#rmcclient)
The RMC client that is connected to the authentication server. **async with login**(username: str, password: str = None, auth_info: [Data](common.md) = None, servers: list[object] = []) -> [RMCClient](rmc.md#rmcclient)
Requests a ticket from the authentication server and establishes a connection with the secure server. The returned RMC client can be used to call methods on the secure server. `servers` must be a list of protocol server objects that should be defined in an external protocol file. These servers are registered on the secure client. **async with login_guest**() -> [RMCClient](rmc.md#rmcclient)
Logs in as guest. On most servers the guest account is disabled. ================================================ FILE: docs/reference/nex/common.md ================================================ # Module: nintendo.nex.common Provides classes that are used by various `nex` modules. **class** [RMCError](#rmcerror)(Exception)
Raised when the server returns an error code. **class** [Result](#result)
Holds the result of a remote method call. **class** Structure
Base class for `nex` structures. This class should not be subclassed manually. Instead, structures should be defined in a protocol file. **class** Data(Structure)
Base class for structures that can be held by a data holder. This class should not be subclassed manually. Instead, data structures should be defined in a protocol file. **class** NullData(Data)
The `NullData` structure. This class does not define any fields. **class** [StationURL](#stationurl)
A station url (`nn::nex::StationURL`). **class** [DateTime](#datetime)
A date time object (`nn::nex::DateTime`). **class** [ResultRange](#resultrange)(Structure)
A result range (`nn::nex::ResultRange`). This structure limits database queries to a specific range. ## RMCError **def _\_init__**(code: str = "Core::Unknown)
Creates a new RMCError from the given error description. **def _\_init__**(code: int = 0x10001)
Creates a new RMCError from the given error code. **def code**() -> int
Returns the error code. **def name**() -> str
Returns a description of the error. If the error code is unknown, this method returns `"unknown error"`. **def result**() -> [Result](#result)
Returns a result object that represents the error. ## Result @classmethod
**def success**(code: str = "Core::Unknown") -> [Result](#result)
Creates a new [`Result`](#result) object that indicates success. @classmethod
**def success**(code: int = 0x10001) -> [Result](#result)
Creates a new [`Result`](#result) object that indicates success. @classmethod
**def error**(code: str = "Core::Unknown") -> [Result](#result)
Creates a new [`Result`](#result) object that indicates an error. @classmethod
**def error**(code: int = 0x10001) -> [Result](#result)
Creates a new [`Result`](#result) object that indicates an error. **def is_success**() -> bool
Returns `True` if the result indicates success. **def is_error**() -> bool
Returns `True` if the result indicates an error. **def code**() -> int
Returns the error code of the result. Errors are indicated by bit `1 << 31`. **def name**() -> str
Returns a description of the result. If the result indicates success, this method always returns `"success"`, regardless of the error code. If the error bit is set but the error code is unknown, this method returns `"unknown error"`. **def raise_if_error**() -> None
Raises an `RMCError` if the error bit is set. ## StationURL A station url consists of an url scheme and a bunch of parameters. The following parameters are currently valid:
`address`, `Rsa`, `port`, `stream`, `sid`, `PID`, `CID`, `type`, `RVCID`, `natm`, `natf`, `upnp`, `pmp`, `probeinit`, `PRID` and `Rsp`. **def _\_init__**(scheme: str = "prudp", \**kwargs)
Creates a new station url with the given url scheme. Additional parameters may be provided in `kwargs`. **def _\_repr__**() -> str
Returns the string representation of the station url. **def _\_getitem__**(name: str) -> object
Returns a specific parameter, either as `str` or `int`. Returns a default value if the parameter name is valid but not defined in the station url. Raises `KeyError` if the parameter name is invalid. **def _\_setitem__**(name: str, value: object) -> None
Changes a specific parameter. The given `value` is automatically converted to string. **def scheme**() -> str
Returns the url scheme. **def address**() -> tuple[str, int]
Returns the address of the station url as a tuple: `(address, port)`. **def is_public**() -> bool
Returns `True` if the `type` field indicates that the station address is public. **def is_behind_nat**() -> bool
Returns `True` if the `type` field indicates that the station is behind a nat device. **def is_global**() -> bool
Returns `True` if the `type` field indicates that the station address is global (i.e. public and not behind a nat device). **def copy**() -> [StationURL](#stationurl)
Returns a copy of the station url. @classmethod
**def parse**(string: str) -> [StationURL](#stationurl)
Parses the given station url string. If `string` is empty, the station url is created with the `"prudp"` scheme and without parameters. ## DateTime A `DateTime` object always represents UTC time. ** def _\_init__**(value: int)
Creates a new [`DateTime`](#datetime) object from the given value. **def value**() -> int
Returns value of the [`DateTime`](#datetime) object, as encoded by `nex`. **def second**() -> int
Returns the seconds (0 - 59)
**def minute**() -> int
Returns the minutes (0 - 59)
**def hour**() -> int
Returns the hours (0 - 23)
**def day**() -> int
Returns the day of the month (1 - 31).
**def month**() -> int
Returns the month (1 - 12)
**def year**() -> int
Returns the year. **def standard_datetime**() -> datetime.datetime
Converts the [`DateTime`](#datetime) object to a standard `datetime.datetime` object. **def timestamp**() -> int
Returns a posix timestamp. @classmethod
**def make**(year: int, month: int = 1, day: int = 1, hour: int = 0, minute: int = 0, second: int = 0) -> [DateTime](#datetime)
Creates a new [`DateTime`](#datetime) object for the given date. @classmethod
**def fromtimestamp**(timestamp: int) -> [DateTime](#datetime)
Creates a new [`DateTime`](#datetime) object from the given posix timestamp. @classmethod
**def now**() -> [DateTime](#datetime)
Creates a new [`DateTime`](#datetime) object for the current time. @classmethod
**def never**() -> [DateTime](#datetime)
Creates a special [`DateTime`](#datetime) object that represents 'never'. @classmethod
**def future**() -> [DateTime](#datetime)
Creates a special [`DateTime`](#datetime) object that represents 'future'. ## ResultRange `offset: int`
`size: int` **def _\_init__**(offset: int = 0, size: int = 10)
Creates a new result range. ================================================ FILE: docs/reference/nex/datastore.md ================================================ # Module: nintendo.nex.datastore Provides a client and server for the `DataStoreProtocol`. This page was generated automatically from `datastore.proto`. **class** [DataStoreClient](#datastoreclient)
The client for the `DataStoreProtocol`. **class** [DataStoreServer](#datastoreserver)
The server for the `DataStoreProtocol`. **class** [DataStoreChangeMetaCompareParam](#datastorechangemetacompareparam)([Structure](common.md))
**class** [DataStoreChangeMetaParam](#datastorechangemetaparam)([Structure](common.md))
**class** [DataStoreChangeMetaParamV1](#datastorechangemetaparamv1)([Structure](common.md))
**class** [DataStoreCompletePostParam](#datastorecompletepostparam)([Structure](common.md))
**class** [DataStoreCompletePostParamV1](#datastorecompletepostparamv1)([Structure](common.md))
**class** [DataStoreCompleteUpdateParam](#datastorecompleteupdateparam)([Structure](common.md))
**class** [DataStoreDeleteParam](#datastoredeleteparam)([Structure](common.md))
**class** [DataStoreGetMetaParam](#datastoregetmetaparam)([Structure](common.md))
**class** [DataStoreGetNewArrivedNotificationsParam](#datastoregetnewarrivednotificationsparam)([Structure](common.md))
**class** [DataStoreGetNotificationUrlParam](#datastoregetnotificationurlparam)([Structure](common.md))
**class** [DataStoreGetSpecificMetaParam](#datastoregetspecificmetaparam)([Structure](common.md))
**class** [DataStoreGetSpecificMetaParamV1](#datastoregetspecificmetaparamv1)([Structure](common.md))
**class** [DataStoreKeyValue](#datastorekeyvalue)([Structure](common.md))
**class** [DataStoreMetaInfo](#datastoremetainfo)([Structure](common.md))
**class** [DataStoreNotification](#datastorenotification)([Structure](common.md))
**class** [DataStoreNotificationV1](#datastorenotificationv1)([Structure](common.md))
**class** [DataStorePasswordInfo](#datastorepasswordinfo)([Structure](common.md))
**class** [DataStorePermission](#datastorepermission)([Structure](common.md))
**class** [DataStorePersistenceInfo](#datastorepersistenceinfo)([Structure](common.md))
**class** [DataStorePersistenceInitParam](#datastorepersistenceinitparam)([Structure](common.md))
**class** [DataStorePersistenceTarget](#datastorepersistencetarget)([Structure](common.md))
**class** [DataStorePrepareGetParam](#datastorepreparegetparam)([Structure](common.md))
**class** [DataStorePrepareGetParamV1](#datastorepreparegetparamv1)([Structure](common.md))
**class** [DataStorePreparePostParam](#datastorepreparepostparam)([Structure](common.md))
**class** [DataStorePreparePostParamV1](#datastorepreparepostparamv1)([Structure](common.md))
**class** [DataStorePrepareUpdateParam](#datastoreprepareupdateparam)([Structure](common.md))
**class** [DataStoreRateObjectParam](#datastorerateobjectparam)([Structure](common.md))
**class** [DataStoreRatingInfo](#datastoreratinginfo)([Structure](common.md))
**class** [DataStoreRatingInfoWithSlot](#datastoreratinginfowithslot)([Structure](common.md))
**class** [DataStoreRatingInitParam](#datastoreratinginitparam)([Structure](common.md))
**class** [DataStoreRatingInitParamWithSlot](#datastoreratinginitparamwithslot)([Structure](common.md))
**class** [DataStoreRatingLog](#datastoreratinglog)([Structure](common.md))
**class** [DataStoreRatingTarget](#datastoreratingtarget)([Structure](common.md))
**class** [DataStoreReqGetAdditionalMeta](#datastorereqgetadditionalmeta)([Structure](common.md))
**class** [DataStoreReqGetInfo](#datastorereqgetinfo)([Structure](common.md))
**class** [DataStoreReqGetInfoV1](#datastorereqgetinfov1)([Structure](common.md))
**class** [DataStoreReqGetNotificationUrlInfo](#datastorereqgetnotificationurlinfo)([Structure](common.md))
**class** [DataStoreReqPostInfo](#datastorereqpostinfo)([Structure](common.md))
**class** [DataStoreReqPostInfoV1](#datastorereqpostinfov1)([Structure](common.md))
**class** [DataStoreReqUpdateInfo](#datastorerequpdateinfo)([Structure](common.md))
**class** [DataStoreSearchParam](#datastoresearchparam)([Structure](common.md))
**class** [DataStoreSearchResult](#datastoresearchresult)([Structure](common.md))
**class** [DataStoreSpecificMetaInfo](#datastorespecificmetainfo)([Structure](common.md))
**class** [DataStoreSpecificMetaInfoV1](#datastorespecificmetainfov1)([Structure](common.md))
**class** [DataStoreTouchObjectParam](#datastoretouchobjectparam)([Structure](common.md))
## DataStoreClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`DataStoreClient`](#datastoreclient). **async def prepare_get_object_v1**(param: [DataStorePrepareGetParamV1](#datastorepreparegetparamv1)) -> [DataStoreReqGetInfoV1](#datastorereqgetinfov1)
Calls method `1` on the server. **async def prepare_post_object_v1**(param: [DataStorePreparePostParamV1](#datastorepreparepostparamv1)) -> [DataStoreReqPostInfoV1](#datastorereqpostinfov1)
Calls method `2` on the server. **async def complete_post_object_v1**(param: [DataStoreCompletePostParamV1](#datastorecompletepostparamv1)) -> None
Calls method `3` on the server. **async def delete_object**(param: [DataStoreDeleteParam](#datastoredeleteparam)) -> None
Calls method `4` on the server. **async def delete_objects**(param: list[[DataStoreDeleteParam](#datastoredeleteparam)], transactional: bool) -> list[[Result](common.md#result)]
Calls method `5` on the server. **async def change_meta_v1**(param: [DataStoreChangeMetaParamV1](#datastorechangemetaparamv1)) -> None
Calls method `6` on the server. **async def change_metas_v1**(data_ids: list[int], param: list[[DataStoreChangeMetaParamV1](#datastorechangemetaparamv1)], transactional: bool) -> list[[Result](common.md#result)]
Calls method `7` on the server. **async def get_meta**(param: [DataStoreGetMetaParam](#datastoregetmetaparam)) -> [DataStoreMetaInfo](#datastoremetainfo)
Calls method `8` on the server. **async def get_metas**(data_ids: list[int], param: [DataStoreGetMetaParam](#datastoregetmetaparam)) -> [RMCResponse](common.md)
Calls method `9` on the server. The RMC response has the following attributes:
info: list[[DataStoreMetaInfo](#datastoremetainfo)]
results: list[[Result](common.md#result)]
**async def prepare_update_object**(param: [DataStorePrepareUpdateParam](#datastoreprepareupdateparam)) -> [DataStoreReqUpdateInfo](#datastorerequpdateinfo)
Calls method `10` on the server. **async def complete_update_object**(param: [DataStoreCompleteUpdateParam](#datastorecompleteupdateparam)) -> None
Calls method `11` on the server. **async def search_object**(param: [DataStoreSearchParam](#datastoresearchparam)) -> [DataStoreSearchResult](#datastoresearchresult)
Calls method `12` on the server. **async def get_notification_url**(param: [DataStoreGetNotificationUrlParam](#datastoregetnotificationurlparam)) -> [DataStoreReqGetNotificationUrlInfo](#datastorereqgetnotificationurlinfo)
Calls method `13` on the server. **async def get_new_arrived_notifications_v1**(param: [DataStoreGetNewArrivedNotificationsParam](#datastoregetnewarrivednotificationsparam)) -> [RMCResponse](common.md)
Calls method `14` on the server. The RMC response has the following attributes:
result: list[[DataStoreNotificationV1](#datastorenotificationv1)]
has_next: bool
**async def rate_object**(target: [DataStoreRatingTarget](#datastoreratingtarget), param: [DataStoreRateObjectParam](#datastorerateobjectparam), fetch_ratings: bool) -> [DataStoreRatingInfo](#datastoreratinginfo)
Calls method `15` on the server. **async def get_rating**(target: [DataStoreRatingTarget](#datastoreratingtarget), access_password: int) -> [DataStoreRatingInfo](#datastoreratinginfo)
Calls method `16` on the server. **async def get_ratings**(data_ids: list[int], access_password: int) -> [RMCResponse](common.md)
Calls method `17` on the server. The RMC response has the following attributes:
ratings: list[list[[DataStoreRatingInfoWithSlot](#datastoreratinginfowithslot)]]
results: list[[Result](common.md#result)]
**async def reset_rating**(target: [DataStoreRatingTarget](#datastoreratingtarget), update_password: int) -> None
Calls method `18` on the server. **async def reset_ratings**(data_ids: list[int], transactional: bool) -> list[[Result](common.md#result)]
Calls method `19` on the server. **async def get_specific_meta_v1**(param: [DataStoreGetSpecificMetaParamV1](#datastoregetspecificmetaparamv1)) -> list[[DataStoreSpecificMetaInfoV1](#datastorespecificmetainfov1)]
Calls method `20` on the server. **async def post_meta_binary**(param: [DataStorePreparePostParam](#datastorepreparepostparam)) -> int
Calls method `21` on the server. **async def touch_object**(param: [DataStoreTouchObjectParam](#datastoretouchobjectparam)) -> None
Calls method `22` on the server. **async def get_rating_with_log**(target: [DataStoreRatingTarget](#datastoreratingtarget), access_password: int) -> [RMCResponse](common.md)
Calls method `23` on the server. The RMC response has the following attributes:
rating: [DataStoreRatingInfo](#datastoreratinginfo)
log: [DataStoreRatingLog](#datastoreratinglog)
**async def prepare_post_object**(param: [DataStorePreparePostParam](#datastorepreparepostparam)) -> [DataStoreReqPostInfo](#datastorereqpostinfo)
Calls method `24` on the server. **async def prepare_get_object**(param: [DataStorePrepareGetParam](#datastorepreparegetparam)) -> [DataStoreReqGetInfo](#datastorereqgetinfo)
Calls method `25` on the server. **async def complete_post_object**(param: [DataStoreCompletePostParam](#datastorecompletepostparam)) -> None
Calls method `26` on the server. **async def get_new_arrived_notifications**(param: [DataStoreGetNewArrivedNotificationsParam](#datastoregetnewarrivednotificationsparam)) -> [RMCResponse](common.md)
Calls method `27` on the server. The RMC response has the following attributes:
result: list[[DataStoreNotification](#datastorenotification)]
has_next: bool
**async def get_specific_meta**(param: [DataStoreGetSpecificMetaParam](#datastoregetspecificmetaparam)) -> list[[DataStoreSpecificMetaInfo](#datastorespecificmetainfo)]
Calls method `28` on the server. **async def get_persistence_info**(owner_id: int, slot_id: int) -> [DataStorePersistenceInfo](#datastorepersistenceinfo)
Calls method `29` on the server. **async def get_persistence_infos**(owner_id: int, slot_ids: list[int]) -> [RMCResponse](common.md)
Calls method `30` on the server. The RMC response has the following attributes:
infos: list[[DataStorePersistenceInfo](#datastorepersistenceinfo)]
results: list[[Result](common.md#result)]
**async def perpetuate_object**(persistence_slot_id: int, data_id: int, delete_last_object: bool) -> None
Calls method `31` on the server. **async def unperpetuate_object**(persistence_slot_id: int, delete_last_object: bool) -> None
Calls method `32` on the server. **async def prepare_get_object_or_meta_binary**(param: [DataStorePrepareGetParam](#datastorepreparegetparam)) -> [RMCResponse](common.md)
Calls method `33` on the server. The RMC response has the following attributes:
get_info: [DataStoreReqGetInfo](#datastorereqgetinfo)
additional_meta: [DataStoreReqGetAdditionalMeta](#datastorereqgetadditionalmeta)
**async def get_password_info**(data_id: int) -> [DataStorePasswordInfo](#datastorepasswordinfo)
Calls method `34` on the server. **async def get_password_infos**(data_ids: list[int]) -> [RMCResponse](common.md)
Calls method `35` on the server. The RMC response has the following attributes:
infos: list[[DataStorePasswordInfo](#datastorepasswordinfo)]
results: list[[Result](common.md#result)]
**async def get_metas_multiple_param**(params: list[[DataStoreGetMetaParam](#datastoregetmetaparam)]) -> [RMCResponse](common.md)
Calls method `36` on the server. The RMC response has the following attributes:
infos: list[[DataStoreMetaInfo](#datastoremetainfo)]
results: list[[Result](common.md#result)]
**async def complete_post_objects**(data_ids: list[int]) -> None
Calls method `37` on the server. **async def change_meta**(param: [DataStoreChangeMetaParam](#datastorechangemetaparam)) -> None
Calls method `38` on the server. **async def change_metas**(data_ids: list[int], param: list[[DataStoreChangeMetaParam](#datastorechangemetaparam)], transactional: bool) -> list[[Result](common.md#result)]
Calls method `39` on the server. **async def rate_objects**(targets: list[[DataStoreRatingTarget](#datastoreratingtarget)], param: list[[DataStoreRateObjectParam](#datastorerateobjectparam)], transactional: bool, fetch_ratings: bool) -> [RMCResponse](common.md)
Calls method `40` on the server. The RMC response has the following attributes:
infos: list[[DataStoreRatingInfo](#datastoreratinginfo)]
results: list[[Result](common.md#result)]
**async def post_meta_binary_with_data_id**(data_id: int, param: [DataStorePreparePostParam](#datastorepreparepostparam)) -> None
Calls method `41` on the server. **async def post_meta_binaries_with_data_id**(data_ids: list[int], param: list[[DataStorePreparePostParam](#datastorepreparepostparam)], transactional: bool) -> list[[Result](common.md#result)]
Calls method `42` on the server. **async def rate_object_with_posting**(target: [DataStoreRatingTarget](#datastoreratingtarget), rate_param: [DataStoreRateObjectParam](#datastorerateobjectparam), post_param: [DataStorePreparePostParam](#datastorepreparepostparam), fetch_ratings: bool) -> [DataStoreRatingInfo](#datastoreratinginfo)
Calls method `43` on the server. **async def rate_objects_with_posting**(targets: list[[DataStoreRatingTarget](#datastoreratingtarget)], rate_param: list[[DataStoreRateObjectParam](#datastorerateobjectparam)], post_param: list[[DataStorePreparePostParam](#datastorepreparepostparam)], transactional: bool, fetch_ratings: bool) -> [RMCResponse](common.md)
Calls method `44` on the server. The RMC response has the following attributes:
ratings: list[[DataStoreRatingInfo](#datastoreratinginfo)]
results: list[[Result](common.md#result)]
**async def get_object_infos**(data_ids: list[int]) -> [RMCResponse](common.md)
Calls method `45` on the server. The RMC response has the following attributes:
infos: list[[DataStoreReqGetInfo](#datastorereqgetinfo)]
results: list[[Result](common.md#result)]
**async def search_object_light**(param: [DataStoreSearchParam](#datastoresearchparam)) -> [DataStoreSearchResult](#datastoresearchresult)
Calls method `46` on the server. ## DataStoreServer **def _\_init__**()
Creates a new [`DataStoreServer`](#datastoreserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def prepare_get_object_v1**(client: [RMCClient](rmc.md#rmcclient), param: [DataStorePrepareGetParamV1](#datastorepreparegetparamv1)) -> [DataStoreReqGetInfoV1](#datastorereqgetinfov1)
Handler for method `1`. This method should be overridden by a subclass. **async def prepare_post_object_v1**(client: [RMCClient](rmc.md#rmcclient), param: [DataStorePreparePostParamV1](#datastorepreparepostparamv1)) -> [DataStoreReqPostInfoV1](#datastorereqpostinfov1)
Handler for method `2`. This method should be overridden by a subclass. **async def complete_post_object_v1**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreCompletePostParamV1](#datastorecompletepostparamv1)) -> None
Handler for method `3`. This method should be overridden by a subclass. **async def delete_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreDeleteParam](#datastoredeleteparam)) -> None
Handler for method `4`. This method should be overridden by a subclass. **async def delete_objects**(client: [RMCClient](rmc.md#rmcclient), param: list[[DataStoreDeleteParam](#datastoredeleteparam)], transactional: bool) -> list[[Result](common.md#result)]
Handler for method `5`. This method should be overridden by a subclass. **async def change_meta_v1**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreChangeMetaParamV1](#datastorechangemetaparamv1)) -> None
Handler for method `6`. This method should be overridden by a subclass. **async def change_metas_v1**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int], param: list[[DataStoreChangeMetaParamV1](#datastorechangemetaparamv1)], transactional: bool) -> list[[Result](common.md#result)]
Handler for method `7`. This method should be overridden by a subclass. **async def get_meta**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreGetMetaParam](#datastoregetmetaparam)) -> [DataStoreMetaInfo](#datastoremetainfo)
Handler for method `8`. This method should be overridden by a subclass. **async def get_metas**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int], param: [DataStoreGetMetaParam](#datastoregetmetaparam)) -> [RMCResponse](common.md)
Handler for method `9`. This method should be overridden by a subclass. The RMC response must have the following attributes:
info: list[[DataStoreMetaInfo](#datastoremetainfo)]
results: list[[Result](common.md#result)]
**async def prepare_update_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStorePrepareUpdateParam](#datastoreprepareupdateparam)) -> [DataStoreReqUpdateInfo](#datastorerequpdateinfo)
Handler for method `10`. This method should be overridden by a subclass. **async def complete_update_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreCompleteUpdateParam](#datastorecompleteupdateparam)) -> None
Handler for method `11`. This method should be overridden by a subclass. **async def search_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreSearchParam](#datastoresearchparam)) -> [DataStoreSearchResult](#datastoresearchresult)
Handler for method `12`. This method should be overridden by a subclass. **async def get_notification_url**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreGetNotificationUrlParam](#datastoregetnotificationurlparam)) -> [DataStoreReqGetNotificationUrlInfo](#datastorereqgetnotificationurlinfo)
Handler for method `13`. This method should be overridden by a subclass. **async def get_new_arrived_notifications_v1**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreGetNewArrivedNotificationsParam](#datastoregetnewarrivednotificationsparam)) -> [RMCResponse](common.md)
Handler for method `14`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: list[[DataStoreNotificationV1](#datastorenotificationv1)]
has_next: bool
**async def rate_object**(client: [RMCClient](rmc.md#rmcclient), target: [DataStoreRatingTarget](#datastoreratingtarget), param: [DataStoreRateObjectParam](#datastorerateobjectparam), fetch_ratings: bool) -> [DataStoreRatingInfo](#datastoreratinginfo)
Handler for method `15`. This method should be overridden by a subclass. **async def get_rating**(client: [RMCClient](rmc.md#rmcclient), target: [DataStoreRatingTarget](#datastoreratingtarget), access_password: int) -> [DataStoreRatingInfo](#datastoreratinginfo)
Handler for method `16`. This method should be overridden by a subclass. **async def get_ratings**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int], access_password: int) -> [RMCResponse](common.md)
Handler for method `17`. This method should be overridden by a subclass. The RMC response must have the following attributes:
ratings: list[list[[DataStoreRatingInfoWithSlot](#datastoreratinginfowithslot)]]
results: list[[Result](common.md#result)]
**async def reset_rating**(client: [RMCClient](rmc.md#rmcclient), target: [DataStoreRatingTarget](#datastoreratingtarget), update_password: int) -> None
Handler for method `18`. This method should be overridden by a subclass. **async def reset_ratings**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int], transactional: bool) -> list[[Result](common.md#result)]
Handler for method `19`. This method should be overridden by a subclass. **async def get_specific_meta_v1**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreGetSpecificMetaParamV1](#datastoregetspecificmetaparamv1)) -> list[[DataStoreSpecificMetaInfoV1](#datastorespecificmetainfov1)]
Handler for method `20`. This method should be overridden by a subclass. **async def post_meta_binary**(client: [RMCClient](rmc.md#rmcclient), param: [DataStorePreparePostParam](#datastorepreparepostparam)) -> int
Handler for method `21`. This method should be overridden by a subclass. **async def touch_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreTouchObjectParam](#datastoretouchobjectparam)) -> None
Handler for method `22`. This method should be overridden by a subclass. **async def get_rating_with_log**(client: [RMCClient](rmc.md#rmcclient), target: [DataStoreRatingTarget](#datastoreratingtarget), access_password: int) -> [RMCResponse](common.md)
Handler for method `23`. This method should be overridden by a subclass. The RMC response must have the following attributes:
rating: [DataStoreRatingInfo](#datastoreratinginfo)
log: [DataStoreRatingLog](#datastoreratinglog)
**async def prepare_post_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStorePreparePostParam](#datastorepreparepostparam)) -> [DataStoreReqPostInfo](#datastorereqpostinfo)
Handler for method `24`. This method should be overridden by a subclass. **async def prepare_get_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStorePrepareGetParam](#datastorepreparegetparam)) -> [DataStoreReqGetInfo](#datastorereqgetinfo)
Handler for method `25`. This method should be overridden by a subclass. **async def complete_post_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreCompletePostParam](#datastorecompletepostparam)) -> None
Handler for method `26`. This method should be overridden by a subclass. **async def get_new_arrived_notifications**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreGetNewArrivedNotificationsParam](#datastoregetnewarrivednotificationsparam)) -> [RMCResponse](common.md)
Handler for method `27`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: list[[DataStoreNotification](#datastorenotification)]
has_next: bool
**async def get_specific_meta**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreGetSpecificMetaParam](#datastoregetspecificmetaparam)) -> list[[DataStoreSpecificMetaInfo](#datastorespecificmetainfo)]
Handler for method `28`. This method should be overridden by a subclass. **async def get_persistence_info**(client: [RMCClient](rmc.md#rmcclient), owner_id: int, slot_id: int) -> [DataStorePersistenceInfo](#datastorepersistenceinfo)
Handler for method `29`. This method should be overridden by a subclass. **async def get_persistence_infos**(client: [RMCClient](rmc.md#rmcclient), owner_id: int, slot_ids: list[int]) -> [RMCResponse](common.md)
Handler for method `30`. This method should be overridden by a subclass. The RMC response must have the following attributes:
infos: list[[DataStorePersistenceInfo](#datastorepersistenceinfo)]
results: list[[Result](common.md#result)]
**async def perpetuate_object**(client: [RMCClient](rmc.md#rmcclient), persistence_slot_id: int, data_id: int, delete_last_object: bool) -> None
Handler for method `31`. This method should be overridden by a subclass. **async def unperpetuate_object**(client: [RMCClient](rmc.md#rmcclient), persistence_slot_id: int, delete_last_object: bool) -> None
Handler for method `32`. This method should be overridden by a subclass. **async def prepare_get_object_or_meta_binary**(client: [RMCClient](rmc.md#rmcclient), param: [DataStorePrepareGetParam](#datastorepreparegetparam)) -> [RMCResponse](common.md)
Handler for method `33`. This method should be overridden by a subclass. The RMC response must have the following attributes:
get_info: [DataStoreReqGetInfo](#datastorereqgetinfo)
additional_meta: [DataStoreReqGetAdditionalMeta](#datastorereqgetadditionalmeta)
**async def get_password_info**(client: [RMCClient](rmc.md#rmcclient), data_id: int) -> [DataStorePasswordInfo](#datastorepasswordinfo)
Handler for method `34`. This method should be overridden by a subclass. **async def get_password_infos**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int]) -> [RMCResponse](common.md)
Handler for method `35`. This method should be overridden by a subclass. The RMC response must have the following attributes:
infos: list[[DataStorePasswordInfo](#datastorepasswordinfo)]
results: list[[Result](common.md#result)]
**async def get_metas_multiple_param**(client: [RMCClient](rmc.md#rmcclient), params: list[[DataStoreGetMetaParam](#datastoregetmetaparam)]) -> [RMCResponse](common.md)
Handler for method `36`. This method should be overridden by a subclass. The RMC response must have the following attributes:
infos: list[[DataStoreMetaInfo](#datastoremetainfo)]
results: list[[Result](common.md#result)]
**async def complete_post_objects**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int]) -> None
Handler for method `37`. This method should be overridden by a subclass. **async def change_meta**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreChangeMetaParam](#datastorechangemetaparam)) -> None
Handler for method `38`. This method should be overridden by a subclass. **async def change_metas**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int], param: list[[DataStoreChangeMetaParam](#datastorechangemetaparam)], transactional: bool) -> list[[Result](common.md#result)]
Handler for method `39`. This method should be overridden by a subclass. **async def rate_objects**(client: [RMCClient](rmc.md#rmcclient), targets: list[[DataStoreRatingTarget](#datastoreratingtarget)], param: list[[DataStoreRateObjectParam](#datastorerateobjectparam)], transactional: bool, fetch_ratings: bool) -> [RMCResponse](common.md)
Handler for method `40`. This method should be overridden by a subclass. The RMC response must have the following attributes:
infos: list[[DataStoreRatingInfo](#datastoreratinginfo)]
results: list[[Result](common.md#result)]
**async def post_meta_binary_with_data_id**(client: [RMCClient](rmc.md#rmcclient), data_id: int, param: [DataStorePreparePostParam](#datastorepreparepostparam)) -> None
Handler for method `41`. This method should be overridden by a subclass. **async def post_meta_binaries_with_data_id**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int], param: list[[DataStorePreparePostParam](#datastorepreparepostparam)], transactional: bool) -> list[[Result](common.md#result)]
Handler for method `42`. This method should be overridden by a subclass. **async def rate_object_with_posting**(client: [RMCClient](rmc.md#rmcclient), target: [DataStoreRatingTarget](#datastoreratingtarget), rate_param: [DataStoreRateObjectParam](#datastorerateobjectparam), post_param: [DataStorePreparePostParam](#datastorepreparepostparam), fetch_ratings: bool) -> [DataStoreRatingInfo](#datastoreratinginfo)
Handler for method `43`. This method should be overridden by a subclass. **async def rate_objects_with_posting**(client: [RMCClient](rmc.md#rmcclient), targets: list[[DataStoreRatingTarget](#datastoreratingtarget)], rate_param: list[[DataStoreRateObjectParam](#datastorerateobjectparam)], post_param: list[[DataStorePreparePostParam](#datastorepreparepostparam)], transactional: bool, fetch_ratings: bool) -> [RMCResponse](common.md)
Handler for method `44`. This method should be overridden by a subclass. The RMC response must have the following attributes:
ratings: list[[DataStoreRatingInfo](#datastoreratinginfo)]
results: list[[Result](common.md#result)]
**async def get_object_infos**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int]) -> [RMCResponse](common.md)
Handler for method `45`. This method should be overridden by a subclass. The RMC response must have the following attributes:
infos: list[[DataStoreReqGetInfo](#datastorereqgetinfo)]
results: list[[Result](common.md#result)]
**async def search_object_light**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreSearchParam](#datastoresearchparam)) -> [DataStoreSearchResult](#datastoresearchresult)
Handler for method `46`. This method should be overridden by a subclass. ## DataStoreChangeMetaCompareParam **def _\_init__**()
Creates a new `DataStoreChangeMetaCompareParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
comparison_flag: int
name: str
permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
delete_permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
period: int
meta_binary: bytes
tags: list[str]
referred_count: int
data_type: int
status: int

## DataStoreChangeMetaParam **def _\_init__**()
Creates a new `DataStoreChangeMetaParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
modifies_flag: int
name: str
permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
delete_permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
period: int
meta_binary: bytes
tags: list[str]
update_password: int
referred_count: int
data_type: int
status: int
compare_param: [DataStoreChangeMetaCompareParam](#datastorechangemetacompareparam) = [DataStoreChangeMetaCompareParam](#datastorechangemetacompareparam)()
persistence_target: [DataStorePersistenceTarget](#datastorepersistencetarget) = [DataStorePersistenceTarget](#datastorepersistencetarget)()

## DataStoreChangeMetaParamV1 **def _\_init__**()
Creates a new `DataStoreChangeMetaParamV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
modifies_flag: int
name: str
permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
delete_permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
period: int
meta_binary: bytes
tags: list[str]
update_password: int

## DataStoreCompletePostParam **def _\_init__**()
Creates a new `DataStoreCompletePostParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
success: bool

## DataStoreCompletePostParamV1 **def _\_init__**()
Creates a new `DataStoreCompletePostParamV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
success: bool

## DataStoreCompleteUpdateParam **def _\_init__**()
Creates a new `DataStoreCompleteUpdateParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
version: int
success: bool

## DataStoreDeleteParam **def _\_init__**()
Creates a new `DataStoreDeleteParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
update_password: int

## DataStoreGetMetaParam **def _\_init__**()
Creates a new `DataStoreGetMetaParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int = 0
persistence_target: [DataStorePersistenceTarget](#datastorepersistencetarget) = [DataStorePersistenceTarget](#datastorepersistencetarget)()
result_option: int = 0
access_password: int = 0

## DataStoreGetNewArrivedNotificationsParam **def _\_init__**()
Creates a new `DataStoreGetNewArrivedNotificationsParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
last_notification_id: int
limit: int

## DataStoreGetNotificationUrlParam **def _\_init__**()
Creates a new `DataStoreGetNotificationUrlParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
previous_url: str

## DataStoreGetSpecificMetaParam **def _\_init__**()
Creates a new `DataStoreGetSpecificMetaParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_ids: list[int]

## DataStoreGetSpecificMetaParamV1 **def _\_init__**()
Creates a new `DataStoreGetSpecificMetaParamV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_ids: list[int]

## DataStoreKeyValue **def _\_init__**()
Creates a new `DataStoreKeyValue` instance. Required fields must be filled in manually. The following fields are defined in this class:
key: str
value: str

## DataStoreMetaInfo **def _\_init__**()
Creates a new `DataStoreMetaInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
owner_id: int
size: int
name: str
data_type: int
meta_binary: bytes
permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
delete_permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
create_time: [DateTime](common.md#datetime)
update_time: [DateTime](common.md#datetime)
period: int
status: int
referred_count: int
refer_data_id: int
flag: int
referred_time: [DateTime](common.md#datetime)
expire_time: [DateTime](common.md#datetime)
tags: list[str]
ratings: list[[DataStoreRatingInfoWithSlot](#datastoreratinginfowithslot)]

## DataStoreNotification **def _\_init__**()
Creates a new `DataStoreNotification` instance. Required fields must be filled in manually. The following fields are defined in this class:
notification_id: int
data_id: int

## DataStoreNotificationV1 **def _\_init__**()
Creates a new `DataStoreNotificationV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
notification_id: int
data_id: int

## DataStorePasswordInfo **def _\_init__**()
Creates a new `DataStorePasswordInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
access_password: int
update_password: int

## DataStorePermission **def _\_init__**()
Creates a new `DataStorePermission` instance. Required fields must be filled in manually. The following fields are defined in this class:
permission: int = 3
recipients: list[int] = []

## DataStorePersistenceInfo **def _\_init__**()
Creates a new `DataStorePersistenceInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
owner_id: int
slot_id: int
data_id: int

## DataStorePersistenceInitParam **def _\_init__**()
Creates a new `DataStorePersistenceInitParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
persistence_id: int = 65535
delete_last_object: bool = True

## DataStorePersistenceTarget **def _\_init__**()
Creates a new `DataStorePersistenceTarget` instance. Required fields must be filled in manually. The following fields are defined in this class:
owner_id: int = 0
persistence_id: int = 65535

## DataStorePrepareGetParam **def _\_init__**()
Creates a new `DataStorePrepareGetParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int = 0
lock_id: int = 0
persistence_target: [DataStorePersistenceTarget](#datastorepersistencetarget) = [DataStorePersistenceTarget](#datastorepersistencetarget)()
access_password: int = 0
If `nex.version` >= 30500:
extra_data: list[str] = []


## DataStorePrepareGetParamV1 **def _\_init__**()
Creates a new `DataStorePrepareGetParamV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
lock_id: int = 0

## DataStorePreparePostParam **def _\_init__**()
Creates a new `DataStorePreparePostParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
size: int
name: str
data_type: int
meta_binary: bytes
permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
delete_permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
flag: int
period: int
refer_data_id: int = 0
tags: list[str] = []
rating_init_param: list[[DataStoreRatingInitParamWithSlot](#datastoreratinginitparamwithslot)] = []
persistence_init_param: [DataStorePersistenceInitParam](#datastorepersistenceinitparam) = [DataStorePersistenceInitParam](#datastorepersistenceinitparam)()
If `nex.version` >= 30500:
extra_data: list[str]


## DataStorePreparePostParamV1 **def _\_init__**()
Creates a new `DataStorePreparePostParamV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
size: int
name: str
data_type: int = 0
meta_binary: bytes = b""
permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
delete_permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
flag: int
period: int
refer_data_id: int = 0
tags: list[str]
rating_init_param: list[[DataStoreRatingInitParamWithSlot](#datastoreratinginitparamwithslot)]

## DataStorePrepareUpdateParam **def _\_init__**()
Creates a new `DataStorePrepareUpdateParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
size: int
update_password: int
extra_data: list[str]

## DataStoreRateObjectParam **def _\_init__**()
Creates a new `DataStoreRateObjectParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
rating_value: int
access_password: int

## DataStoreRatingInfo **def _\_init__**()
Creates a new `DataStoreRatingInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
total_value: int
count: int
initial_value: int

## DataStoreRatingInfoWithSlot **def _\_init__**()
Creates a new `DataStoreRatingInfoWithSlot` instance. Required fields must be filled in manually. The following fields are defined in this class:
slot: int
info: [DataStoreRatingInfo](#datastoreratinginfo) = [DataStoreRatingInfo](#datastoreratinginfo)()

## DataStoreRatingInitParam **def _\_init__**()
Creates a new `DataStoreRatingInitParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
flag: int
internal_flag: int
lock_type: int
initial_value: int
range_min: int
range_max: int
period_hour: int
period_duration: int

## DataStoreRatingInitParamWithSlot **def _\_init__**()
Creates a new `DataStoreRatingInitParamWithSlot` instance. Required fields must be filled in manually. The following fields are defined in this class:
slot: int
param: [DataStoreRatingInitParam](#datastoreratinginitparam) = [DataStoreRatingInitParam](#datastoreratinginitparam)()

## DataStoreRatingLog **def _\_init__**()
Creates a new `DataStoreRatingLog` instance. Required fields must be filled in manually. The following fields are defined in this class:
is_rated: bool
pid: int
rating_value: int
lock_expiration_time: [DateTime](common.md#datetime)

## DataStoreRatingTarget **def _\_init__**()
Creates a new `DataStoreRatingTarget` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
slot: int

## DataStoreReqGetAdditionalMeta **def _\_init__**()
Creates a new `DataStoreReqGetAdditionalMeta` instance. Required fields must be filled in manually. The following fields are defined in this class:
owner_id: int
data_type: int
version: int
meta_binary: bytes

## DataStoreReqGetInfo **def _\_init__**()
Creates a new `DataStoreReqGetInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
url: str
headers: list[[DataStoreKeyValue](#datastorekeyvalue)]
size: int
root_ca_cert: bytes
If `nex.version` >= 30500:
data_id: int


## DataStoreReqGetInfoV1 **def _\_init__**()
Creates a new `DataStoreReqGetInfoV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
url: str
headers: list[[DataStoreKeyValue](#datastorekeyvalue)]
size: int
root_ca_cert: bytes

## DataStoreReqGetNotificationUrlInfo **def _\_init__**()
Creates a new `DataStoreReqGetNotificationUrlInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
url: str
key: str
query: str
root_ca_cert: bytes

## DataStoreReqPostInfo **def _\_init__**()
Creates a new `DataStoreReqPostInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
url: str
headers: list[[DataStoreKeyValue](#datastorekeyvalue)]
form: list[[DataStoreKeyValue](#datastorekeyvalue)]
root_ca_cert: bytes

## DataStoreReqPostInfoV1 **def _\_init__**()
Creates a new `DataStoreReqPostInfoV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
url: str
headers: list[[DataStoreKeyValue](#datastorekeyvalue)]
form: list[[DataStoreKeyValue](#datastorekeyvalue)]
root_ca_cert: bytes

## DataStoreReqUpdateInfo **def _\_init__**()
Creates a new `DataStoreReqUpdateInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
version: int
url: str
headers: list[[DataStoreKeyValue](#datastorekeyvalue)]
form: list[[DataStoreKeyValue](#datastorekeyvalue)]
root_ca_cert: bytes

## DataStoreSearchParam **def _\_init__**()
Creates a new `DataStoreSearchParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
search_target: int = 1
owner_ids: list[int] = []
owner_type: int = 0
destination_ids: list[int] = []
data_type: int = 65535
created_after: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).future()
created_before: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).future()
updated_after: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).future()
updated_before: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).future()
refer_data_id: int = 0
tags: list[str] = []
result_order_column: int = 0
result_order: int = 0
result_range: [ResultRange](common.md#resultrange) = [ResultRange](common.md#resultrange)()
result_option: int = 0
minimal_rating_frequency: int = 0
use_cache: bool = False
total_count_enabled: bool = True
data_types: list[int] = []

## DataStoreSearchResult **def _\_init__**()
Creates a new `DataStoreSearchResult` instance. Required fields must be filled in manually. The following fields are defined in this class:
total_count: int
result: list[[DataStoreMetaInfo](#datastoremetainfo)]
total_count_type: int

## DataStoreSpecificMetaInfo **def _\_init__**()
Creates a new `DataStoreSpecificMetaInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
owner_id: int
size: int
data_type: int
version: int

## DataStoreSpecificMetaInfoV1 **def _\_init__**()
Creates a new `DataStoreSpecificMetaInfoV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
owner_id: int
size: int
data_type: int
version: int

## DataStoreTouchObjectParam **def _\_init__**()
Creates a new `DataStoreTouchObjectParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
lock_id: int
access_password: int

================================================ FILE: docs/reference/nex/datastore_miitopia_3ds.md ================================================ # Module: nintendo.nex.datastore_miitopia_3ds Provides a client and server for the `DataStoreProtocolMiitopia3DS`. This page was generated automatically from `datastore_miitopia_3ds.proto`. **class** [DataStoreClientMiitopia3DS](#datastoreclientmiitopia3ds)
The client for the `DataStoreProtocolMiitopia3DS`. **class** [DataStoreServerMiitopia3DS](#datastoreservermiitopia3ds)
The server for the `DataStoreProtocolMiitopia3DS`. **class** [Category](#category)
**class** [Gender](#gender)
**class** [DataStoreChangeMetaCompareParam](#datastorechangemetacompareparam)([Structure](common.md))
**class** [DataStoreChangeMetaParam](#datastorechangemetaparam)([Structure](common.md))
**class** [DataStoreChangeMetaParamV1](#datastorechangemetaparamv1)([Structure](common.md))
**class** [DataStoreCompletePostParam](#datastorecompletepostparam)([Structure](common.md))
**class** [DataStoreCompletePostParamV1](#datastorecompletepostparamv1)([Structure](common.md))
**class** [DataStoreCompleteUpdateParam](#datastorecompleteupdateparam)([Structure](common.md))
**class** [DataStoreDeleteParam](#datastoredeleteparam)([Structure](common.md))
**class** [DataStoreGetMetaParam](#datastoregetmetaparam)([Structure](common.md))
**class** [DataStoreGetNewArrivedNotificationsParam](#datastoregetnewarrivednotificationsparam)([Structure](common.md))
**class** [DataStoreGetNotificationUrlParam](#datastoregetnotificationurlparam)([Structure](common.md))
**class** [DataStoreGetSpecificMetaParam](#datastoregetspecificmetaparam)([Structure](common.md))
**class** [DataStoreGetSpecificMetaParamV1](#datastoregetspecificmetaparamv1)([Structure](common.md))
**class** [DataStoreKeyValue](#datastorekeyvalue)([Structure](common.md))
**class** [DataStoreMetaInfo](#datastoremetainfo)([Structure](common.md))
**class** [DataStoreNotification](#datastorenotification)([Structure](common.md))
**class** [DataStoreNotificationV1](#datastorenotificationv1)([Structure](common.md))
**class** [DataStorePasswordInfo](#datastorepasswordinfo)([Structure](common.md))
**class** [DataStorePermission](#datastorepermission)([Structure](common.md))
**class** [DataStorePersistenceInfo](#datastorepersistenceinfo)([Structure](common.md))
**class** [DataStorePersistenceInitParam](#datastorepersistenceinitparam)([Structure](common.md))
**class** [DataStorePersistenceTarget](#datastorepersistencetarget)([Structure](common.md))
**class** [DataStorePrepareGetParam](#datastorepreparegetparam)([Structure](common.md))
**class** [DataStorePrepareGetParamV1](#datastorepreparegetparamv1)([Structure](common.md))
**class** [DataStorePreparePostParam](#datastorepreparepostparam)([Structure](common.md))
**class** [DataStorePreparePostParamV1](#datastorepreparepostparamv1)([Structure](common.md))
**class** [DataStorePrepareUpdateParam](#datastoreprepareupdateparam)([Structure](common.md))
**class** [DataStoreRateObjectParam](#datastorerateobjectparam)([Structure](common.md))
**class** [DataStoreRatingInfo](#datastoreratinginfo)([Structure](common.md))
**class** [DataStoreRatingInfoWithSlot](#datastoreratinginfowithslot)([Structure](common.md))
**class** [DataStoreRatingInitParam](#datastoreratinginitparam)([Structure](common.md))
**class** [DataStoreRatingInitParamWithSlot](#datastoreratinginitparamwithslot)([Structure](common.md))
**class** [DataStoreRatingLog](#datastoreratinglog)([Structure](common.md))
**class** [DataStoreRatingTarget](#datastoreratingtarget)([Structure](common.md))
**class** [DataStoreReqGetAdditionalMeta](#datastorereqgetadditionalmeta)([Structure](common.md))
**class** [DataStoreReqGetInfo](#datastorereqgetinfo)([Structure](common.md))
**class** [DataStoreReqGetInfoV1](#datastorereqgetinfov1)([Structure](common.md))
**class** [DataStoreReqGetNotificationUrlInfo](#datastorereqgetnotificationurlinfo)([Structure](common.md))
**class** [DataStoreReqPostInfo](#datastorereqpostinfo)([Structure](common.md))
**class** [DataStoreReqPostInfoV1](#datastorereqpostinfov1)([Structure](common.md))
**class** [DataStoreReqUpdateInfo](#datastorerequpdateinfo)([Structure](common.md))
**class** [DataStoreSearchParam](#datastoresearchparam)([Structure](common.md))
**class** [DataStoreSearchResult](#datastoresearchresult)([Structure](common.md))
**class** [DataStoreSpecificMetaInfo](#datastorespecificmetainfo)([Structure](common.md))
**class** [DataStoreSpecificMetaInfoV1](#datastorespecificmetainfov1)([Structure](common.md))
**class** [DataStoreTouchObjectParam](#datastoretouchobjectparam)([Structure](common.md))
**class** [MiiTubeMiiInfo](#miitubemiiinfo)([Structure](common.md))
**class** [MiiTubeSearchParam](#miitubesearchparam)([Structure](common.md))
**class** [MiiTubeSearchResult](#miitubesearchresult)([Structure](common.md))
## DataStoreClientMiitopia3DS **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`DataStoreClientMiitopia3DS`](#datastoreclientmiitopia3ds). **async def prepare_get_object_v1**(param: [DataStorePrepareGetParamV1](#datastorepreparegetparamv1)) -> [DataStoreReqGetInfoV1](#datastorereqgetinfov1)
Calls method `1` on the server. **async def prepare_post_object_v1**(param: [DataStorePreparePostParamV1](#datastorepreparepostparamv1)) -> [DataStoreReqPostInfoV1](#datastorereqpostinfov1)
Calls method `2` on the server. **async def complete_post_object_v1**(param: [DataStoreCompletePostParamV1](#datastorecompletepostparamv1)) -> None
Calls method `3` on the server. **async def delete_object**(param: [DataStoreDeleteParam](#datastoredeleteparam)) -> None
Calls method `4` on the server. **async def delete_objects**(param: list[[DataStoreDeleteParam](#datastoredeleteparam)], transactional: bool) -> list[[Result](common.md#result)]
Calls method `5` on the server. **async def change_meta_v1**(param: [DataStoreChangeMetaParamV1](#datastorechangemetaparamv1)) -> None
Calls method `6` on the server. **async def change_metas_v1**(data_ids: list[int], param: list[[DataStoreChangeMetaParamV1](#datastorechangemetaparamv1)], transactional: bool) -> list[[Result](common.md#result)]
Calls method `7` on the server. **async def get_meta**(param: [DataStoreGetMetaParam](#datastoregetmetaparam)) -> [DataStoreMetaInfo](#datastoremetainfo)
Calls method `8` on the server. **async def get_metas**(data_ids: list[int], param: [DataStoreGetMetaParam](#datastoregetmetaparam)) -> [RMCResponse](common.md)
Calls method `9` on the server. The RMC response has the following attributes:
info: list[[DataStoreMetaInfo](#datastoremetainfo)]
results: list[[Result](common.md#result)]
**async def prepare_update_object**(param: [DataStorePrepareUpdateParam](#datastoreprepareupdateparam)) -> [DataStoreReqUpdateInfo](#datastorerequpdateinfo)
Calls method `10` on the server. **async def complete_update_object**(param: [DataStoreCompleteUpdateParam](#datastorecompleteupdateparam)) -> None
Calls method `11` on the server. **async def search_object**(param: [DataStoreSearchParam](#datastoresearchparam)) -> [DataStoreSearchResult](#datastoresearchresult)
Calls method `12` on the server. **async def get_notification_url**(param: [DataStoreGetNotificationUrlParam](#datastoregetnotificationurlparam)) -> [DataStoreReqGetNotificationUrlInfo](#datastorereqgetnotificationurlinfo)
Calls method `13` on the server. **async def get_new_arrived_notifications_v1**(param: [DataStoreGetNewArrivedNotificationsParam](#datastoregetnewarrivednotificationsparam)) -> [RMCResponse](common.md)
Calls method `14` on the server. The RMC response has the following attributes:
result: list[[DataStoreNotificationV1](#datastorenotificationv1)]
has_next: bool
**async def rate_object**(target: [DataStoreRatingTarget](#datastoreratingtarget), param: [DataStoreRateObjectParam](#datastorerateobjectparam), fetch_ratings: bool) -> [DataStoreRatingInfo](#datastoreratinginfo)
Calls method `15` on the server. **async def get_rating**(target: [DataStoreRatingTarget](#datastoreratingtarget), access_password: int) -> [DataStoreRatingInfo](#datastoreratinginfo)
Calls method `16` on the server. **async def get_ratings**(data_ids: list[int], access_password: int) -> [RMCResponse](common.md)
Calls method `17` on the server. The RMC response has the following attributes:
ratings: list[list[[DataStoreRatingInfoWithSlot](#datastoreratinginfowithslot)]]
results: list[[Result](common.md#result)]
**async def reset_rating**(target: [DataStoreRatingTarget](#datastoreratingtarget), update_password: int) -> None
Calls method `18` on the server. **async def reset_ratings**(data_ids: list[int], transactional: bool) -> list[[Result](common.md#result)]
Calls method `19` on the server. **async def get_specific_meta_v1**(param: [DataStoreGetSpecificMetaParamV1](#datastoregetspecificmetaparamv1)) -> list[[DataStoreSpecificMetaInfoV1](#datastorespecificmetainfov1)]
Calls method `20` on the server. **async def post_meta_binary**(param: [DataStorePreparePostParam](#datastorepreparepostparam)) -> int
Calls method `21` on the server. **async def touch_object**(param: [DataStoreTouchObjectParam](#datastoretouchobjectparam)) -> None
Calls method `22` on the server. **async def get_rating_with_log**(target: [DataStoreRatingTarget](#datastoreratingtarget), access_password: int) -> [RMCResponse](common.md)
Calls method `23` on the server. The RMC response has the following attributes:
rating: [DataStoreRatingInfo](#datastoreratinginfo)
log: [DataStoreRatingLog](#datastoreratinglog)
**async def prepare_post_object**(param: [DataStorePreparePostParam](#datastorepreparepostparam)) -> [DataStoreReqPostInfo](#datastorereqpostinfo)
Calls method `24` on the server. **async def prepare_get_object**(param: [DataStorePrepareGetParam](#datastorepreparegetparam)) -> [DataStoreReqGetInfo](#datastorereqgetinfo)
Calls method `25` on the server. **async def complete_post_object**(param: [DataStoreCompletePostParam](#datastorecompletepostparam)) -> None
Calls method `26` on the server. **async def get_new_arrived_notifications**(param: [DataStoreGetNewArrivedNotificationsParam](#datastoregetnewarrivednotificationsparam)) -> [RMCResponse](common.md)
Calls method `27` on the server. The RMC response has the following attributes:
result: list[[DataStoreNotification](#datastorenotification)]
has_next: bool
**async def get_specific_meta**(param: [DataStoreGetSpecificMetaParam](#datastoregetspecificmetaparam)) -> list[[DataStoreSpecificMetaInfo](#datastorespecificmetainfo)]
Calls method `28` on the server. **async def get_persistence_info**(owner_id: int, slot_id: int) -> [DataStorePersistenceInfo](#datastorepersistenceinfo)
Calls method `29` on the server. **async def get_persistence_infos**(owner_id: int, slot_ids: list[int]) -> [RMCResponse](common.md)
Calls method `30` on the server. The RMC response has the following attributes:
infos: list[[DataStorePersistenceInfo](#datastorepersistenceinfo)]
results: list[[Result](common.md#result)]
**async def perpetuate_object**(persistence_slot_id: int, data_id: int, delete_last_object: bool) -> None
Calls method `31` on the server. **async def unperpetuate_object**(persistence_slot_id: int, delete_last_object: bool) -> None
Calls method `32` on the server. **async def prepare_get_object_or_meta_binary**(param: [DataStorePrepareGetParam](#datastorepreparegetparam)) -> [RMCResponse](common.md)
Calls method `33` on the server. The RMC response has the following attributes:
get_info: [DataStoreReqGetInfo](#datastorereqgetinfo)
additional_meta: [DataStoreReqGetAdditionalMeta](#datastorereqgetadditionalmeta)
**async def get_password_info**(data_id: int) -> [DataStorePasswordInfo](#datastorepasswordinfo)
Calls method `34` on the server. **async def get_password_infos**(data_ids: list[int]) -> [RMCResponse](common.md)
Calls method `35` on the server. The RMC response has the following attributes:
infos: list[[DataStorePasswordInfo](#datastorepasswordinfo)]
results: list[[Result](common.md#result)]
**async def get_metas_multiple_param**(params: list[[DataStoreGetMetaParam](#datastoregetmetaparam)]) -> [RMCResponse](common.md)
Calls method `36` on the server. The RMC response has the following attributes:
infos: list[[DataStoreMetaInfo](#datastoremetainfo)]
results: list[[Result](common.md#result)]
**async def complete_post_objects**(data_ids: list[int]) -> None
Calls method `37` on the server. **async def change_meta**(param: [DataStoreChangeMetaParam](#datastorechangemetaparam)) -> None
Calls method `38` on the server. **async def change_metas**(data_ids: list[int], param: list[[DataStoreChangeMetaParam](#datastorechangemetaparam)], transactional: bool) -> list[[Result](common.md#result)]
Calls method `39` on the server. **async def rate_objects**(targets: list[[DataStoreRatingTarget](#datastoreratingtarget)], param: list[[DataStoreRateObjectParam](#datastorerateobjectparam)], transactional: bool, fetch_ratings: bool) -> [RMCResponse](common.md)
Calls method `40` on the server. The RMC response has the following attributes:
infos: list[[DataStoreRatingInfo](#datastoreratinginfo)]
results: list[[Result](common.md#result)]
**async def post_meta_binary_with_data_id**(data_id: int, param: [DataStorePreparePostParam](#datastorepreparepostparam)) -> None
Calls method `41` on the server. **async def post_meta_binaries_with_data_id**(data_ids: list[int], param: list[[DataStorePreparePostParam](#datastorepreparepostparam)], transactional: bool) -> list[[Result](common.md#result)]
Calls method `42` on the server. **async def rate_object_with_posting**(target: [DataStoreRatingTarget](#datastoreratingtarget), rate_param: [DataStoreRateObjectParam](#datastorerateobjectparam), post_param: [DataStorePreparePostParam](#datastorepreparepostparam), fetch_ratings: bool) -> [DataStoreRatingInfo](#datastoreratinginfo)
Calls method `43` on the server. **async def rate_objects_with_posting**(targets: list[[DataStoreRatingTarget](#datastoreratingtarget)], rate_param: list[[DataStoreRateObjectParam](#datastorerateobjectparam)], post_param: list[[DataStorePreparePostParam](#datastorepreparepostparam)], transactional: bool, fetch_ratings: bool) -> [RMCResponse](common.md)
Calls method `44` on the server. The RMC response has the following attributes:
ratings: list[[DataStoreRatingInfo](#datastoreratinginfo)]
results: list[[Result](common.md#result)]
**async def get_object_infos**(data_ids: list[int]) -> [RMCResponse](common.md)
Calls method `45` on the server. The RMC response has the following attributes:
infos: list[[DataStoreReqGetInfo](#datastorereqgetinfo)]
results: list[[Result](common.md#result)]
**async def search_object_light**(param: [DataStoreSearchParam](#datastoresearchparam)) -> [DataStoreSearchResult](#datastoresearchresult)
Calls method `46` on the server. **async def search_mii**(param: [MiiTubeSearchParam](#miitubesearchparam)) -> [MiiTubeSearchResult](#miitubesearchresult)
Calls method `47` on the server. ## DataStoreServerMiitopia3DS **def _\_init__**()
Creates a new [`DataStoreServerMiitopia3DS`](#datastoreservermiitopia3ds). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def prepare_get_object_v1**(client: [RMCClient](rmc.md#rmcclient), param: [DataStorePrepareGetParamV1](#datastorepreparegetparamv1)) -> [DataStoreReqGetInfoV1](#datastorereqgetinfov1)
Handler for method `1`. This method should be overridden by a subclass. **async def prepare_post_object_v1**(client: [RMCClient](rmc.md#rmcclient), param: [DataStorePreparePostParamV1](#datastorepreparepostparamv1)) -> [DataStoreReqPostInfoV1](#datastorereqpostinfov1)
Handler for method `2`. This method should be overridden by a subclass. **async def complete_post_object_v1**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreCompletePostParamV1](#datastorecompletepostparamv1)) -> None
Handler for method `3`. This method should be overridden by a subclass. **async def delete_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreDeleteParam](#datastoredeleteparam)) -> None
Handler for method `4`. This method should be overridden by a subclass. **async def delete_objects**(client: [RMCClient](rmc.md#rmcclient), param: list[[DataStoreDeleteParam](#datastoredeleteparam)], transactional: bool) -> list[[Result](common.md#result)]
Handler for method `5`. This method should be overridden by a subclass. **async def change_meta_v1**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreChangeMetaParamV1](#datastorechangemetaparamv1)) -> None
Handler for method `6`. This method should be overridden by a subclass. **async def change_metas_v1**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int], param: list[[DataStoreChangeMetaParamV1](#datastorechangemetaparamv1)], transactional: bool) -> list[[Result](common.md#result)]
Handler for method `7`. This method should be overridden by a subclass. **async def get_meta**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreGetMetaParam](#datastoregetmetaparam)) -> [DataStoreMetaInfo](#datastoremetainfo)
Handler for method `8`. This method should be overridden by a subclass. **async def get_metas**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int], param: [DataStoreGetMetaParam](#datastoregetmetaparam)) -> [RMCResponse](common.md)
Handler for method `9`. This method should be overridden by a subclass. The RMC response must have the following attributes:
info: list[[DataStoreMetaInfo](#datastoremetainfo)]
results: list[[Result](common.md#result)]
**async def prepare_update_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStorePrepareUpdateParam](#datastoreprepareupdateparam)) -> [DataStoreReqUpdateInfo](#datastorerequpdateinfo)
Handler for method `10`. This method should be overridden by a subclass. **async def complete_update_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreCompleteUpdateParam](#datastorecompleteupdateparam)) -> None
Handler for method `11`. This method should be overridden by a subclass. **async def search_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreSearchParam](#datastoresearchparam)) -> [DataStoreSearchResult](#datastoresearchresult)
Handler for method `12`. This method should be overridden by a subclass. **async def get_notification_url**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreGetNotificationUrlParam](#datastoregetnotificationurlparam)) -> [DataStoreReqGetNotificationUrlInfo](#datastorereqgetnotificationurlinfo)
Handler for method `13`. This method should be overridden by a subclass. **async def get_new_arrived_notifications_v1**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreGetNewArrivedNotificationsParam](#datastoregetnewarrivednotificationsparam)) -> [RMCResponse](common.md)
Handler for method `14`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: list[[DataStoreNotificationV1](#datastorenotificationv1)]
has_next: bool
**async def rate_object**(client: [RMCClient](rmc.md#rmcclient), target: [DataStoreRatingTarget](#datastoreratingtarget), param: [DataStoreRateObjectParam](#datastorerateobjectparam), fetch_ratings: bool) -> [DataStoreRatingInfo](#datastoreratinginfo)
Handler for method `15`. This method should be overridden by a subclass. **async def get_rating**(client: [RMCClient](rmc.md#rmcclient), target: [DataStoreRatingTarget](#datastoreratingtarget), access_password: int) -> [DataStoreRatingInfo](#datastoreratinginfo)
Handler for method `16`. This method should be overridden by a subclass. **async def get_ratings**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int], access_password: int) -> [RMCResponse](common.md)
Handler for method `17`. This method should be overridden by a subclass. The RMC response must have the following attributes:
ratings: list[list[[DataStoreRatingInfoWithSlot](#datastoreratinginfowithslot)]]
results: list[[Result](common.md#result)]
**async def reset_rating**(client: [RMCClient](rmc.md#rmcclient), target: [DataStoreRatingTarget](#datastoreratingtarget), update_password: int) -> None
Handler for method `18`. This method should be overridden by a subclass. **async def reset_ratings**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int], transactional: bool) -> list[[Result](common.md#result)]
Handler for method `19`. This method should be overridden by a subclass. **async def get_specific_meta_v1**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreGetSpecificMetaParamV1](#datastoregetspecificmetaparamv1)) -> list[[DataStoreSpecificMetaInfoV1](#datastorespecificmetainfov1)]
Handler for method `20`. This method should be overridden by a subclass. **async def post_meta_binary**(client: [RMCClient](rmc.md#rmcclient), param: [DataStorePreparePostParam](#datastorepreparepostparam)) -> int
Handler for method `21`. This method should be overridden by a subclass. **async def touch_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreTouchObjectParam](#datastoretouchobjectparam)) -> None
Handler for method `22`. This method should be overridden by a subclass. **async def get_rating_with_log**(client: [RMCClient](rmc.md#rmcclient), target: [DataStoreRatingTarget](#datastoreratingtarget), access_password: int) -> [RMCResponse](common.md)
Handler for method `23`. This method should be overridden by a subclass. The RMC response must have the following attributes:
rating: [DataStoreRatingInfo](#datastoreratinginfo)
log: [DataStoreRatingLog](#datastoreratinglog)
**async def prepare_post_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStorePreparePostParam](#datastorepreparepostparam)) -> [DataStoreReqPostInfo](#datastorereqpostinfo)
Handler for method `24`. This method should be overridden by a subclass. **async def prepare_get_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStorePrepareGetParam](#datastorepreparegetparam)) -> [DataStoreReqGetInfo](#datastorereqgetinfo)
Handler for method `25`. This method should be overridden by a subclass. **async def complete_post_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreCompletePostParam](#datastorecompletepostparam)) -> None
Handler for method `26`. This method should be overridden by a subclass. **async def get_new_arrived_notifications**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreGetNewArrivedNotificationsParam](#datastoregetnewarrivednotificationsparam)) -> [RMCResponse](common.md)
Handler for method `27`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: list[[DataStoreNotification](#datastorenotification)]
has_next: bool
**async def get_specific_meta**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreGetSpecificMetaParam](#datastoregetspecificmetaparam)) -> list[[DataStoreSpecificMetaInfo](#datastorespecificmetainfo)]
Handler for method `28`. This method should be overridden by a subclass. **async def get_persistence_info**(client: [RMCClient](rmc.md#rmcclient), owner_id: int, slot_id: int) -> [DataStorePersistenceInfo](#datastorepersistenceinfo)
Handler for method `29`. This method should be overridden by a subclass. **async def get_persistence_infos**(client: [RMCClient](rmc.md#rmcclient), owner_id: int, slot_ids: list[int]) -> [RMCResponse](common.md)
Handler for method `30`. This method should be overridden by a subclass. The RMC response must have the following attributes:
infos: list[[DataStorePersistenceInfo](#datastorepersistenceinfo)]
results: list[[Result](common.md#result)]
**async def perpetuate_object**(client: [RMCClient](rmc.md#rmcclient), persistence_slot_id: int, data_id: int, delete_last_object: bool) -> None
Handler for method `31`. This method should be overridden by a subclass. **async def unperpetuate_object**(client: [RMCClient](rmc.md#rmcclient), persistence_slot_id: int, delete_last_object: bool) -> None
Handler for method `32`. This method should be overridden by a subclass. **async def prepare_get_object_or_meta_binary**(client: [RMCClient](rmc.md#rmcclient), param: [DataStorePrepareGetParam](#datastorepreparegetparam)) -> [RMCResponse](common.md)
Handler for method `33`. This method should be overridden by a subclass. The RMC response must have the following attributes:
get_info: [DataStoreReqGetInfo](#datastorereqgetinfo)
additional_meta: [DataStoreReqGetAdditionalMeta](#datastorereqgetadditionalmeta)
**async def get_password_info**(client: [RMCClient](rmc.md#rmcclient), data_id: int) -> [DataStorePasswordInfo](#datastorepasswordinfo)
Handler for method `34`. This method should be overridden by a subclass. **async def get_password_infos**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int]) -> [RMCResponse](common.md)
Handler for method `35`. This method should be overridden by a subclass. The RMC response must have the following attributes:
infos: list[[DataStorePasswordInfo](#datastorepasswordinfo)]
results: list[[Result](common.md#result)]
**async def get_metas_multiple_param**(client: [RMCClient](rmc.md#rmcclient), params: list[[DataStoreGetMetaParam](#datastoregetmetaparam)]) -> [RMCResponse](common.md)
Handler for method `36`. This method should be overridden by a subclass. The RMC response must have the following attributes:
infos: list[[DataStoreMetaInfo](#datastoremetainfo)]
results: list[[Result](common.md#result)]
**async def complete_post_objects**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int]) -> None
Handler for method `37`. This method should be overridden by a subclass. **async def change_meta**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreChangeMetaParam](#datastorechangemetaparam)) -> None
Handler for method `38`. This method should be overridden by a subclass. **async def change_metas**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int], param: list[[DataStoreChangeMetaParam](#datastorechangemetaparam)], transactional: bool) -> list[[Result](common.md#result)]
Handler for method `39`. This method should be overridden by a subclass. **async def rate_objects**(client: [RMCClient](rmc.md#rmcclient), targets: list[[DataStoreRatingTarget](#datastoreratingtarget)], param: list[[DataStoreRateObjectParam](#datastorerateobjectparam)], transactional: bool, fetch_ratings: bool) -> [RMCResponse](common.md)
Handler for method `40`. This method should be overridden by a subclass. The RMC response must have the following attributes:
infos: list[[DataStoreRatingInfo](#datastoreratinginfo)]
results: list[[Result](common.md#result)]
**async def post_meta_binary_with_data_id**(client: [RMCClient](rmc.md#rmcclient), data_id: int, param: [DataStorePreparePostParam](#datastorepreparepostparam)) -> None
Handler for method `41`. This method should be overridden by a subclass. **async def post_meta_binaries_with_data_id**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int], param: list[[DataStorePreparePostParam](#datastorepreparepostparam)], transactional: bool) -> list[[Result](common.md#result)]
Handler for method `42`. This method should be overridden by a subclass. **async def rate_object_with_posting**(client: [RMCClient](rmc.md#rmcclient), target: [DataStoreRatingTarget](#datastoreratingtarget), rate_param: [DataStoreRateObjectParam](#datastorerateobjectparam), post_param: [DataStorePreparePostParam](#datastorepreparepostparam), fetch_ratings: bool) -> [DataStoreRatingInfo](#datastoreratinginfo)
Handler for method `43`. This method should be overridden by a subclass. **async def rate_objects_with_posting**(client: [RMCClient](rmc.md#rmcclient), targets: list[[DataStoreRatingTarget](#datastoreratingtarget)], rate_param: list[[DataStoreRateObjectParam](#datastorerateobjectparam)], post_param: list[[DataStorePreparePostParam](#datastorepreparepostparam)], transactional: bool, fetch_ratings: bool) -> [RMCResponse](common.md)
Handler for method `44`. This method should be overridden by a subclass. The RMC response must have the following attributes:
ratings: list[[DataStoreRatingInfo](#datastoreratinginfo)]
results: list[[Result](common.md#result)]
**async def get_object_infos**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int]) -> [RMCResponse](common.md)
Handler for method `45`. This method should be overridden by a subclass. The RMC response must have the following attributes:
infos: list[[DataStoreReqGetInfo](#datastorereqgetinfo)]
results: list[[Result](common.md#result)]
**async def search_object_light**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreSearchParam](#datastoresearchparam)) -> [DataStoreSearchResult](#datastoresearchresult)
Handler for method `46`. This method should be overridden by a subclass. **async def search_mii**(client: [RMCClient](rmc.md#rmcclient), param: [MiiTubeSearchParam](#miitubesearchparam)) -> [MiiTubeSearchResult](#miitubesearchresult)
Handler for method `47`. This method should be overridden by a subclass. ## Category This class defines the following constants:
`SINGING = 0`
`SPORT = 1`
`ACTING = 2`
`COMEDY = 3`
`MUSIC = 4`
`MARTIAL_ARTS = 5`
`DANCING = 6`
`ADVENTURING = 7`
`FILM_DIRECTING = 8`
`COOKING = 9`
`CHATTING = 10`
`PUBLIC_SPEAKING = 11`
`CRAFTWORK = 12`
`DRAWING = 13`
`STUDYING = 14`
`WRITING = 15`
`FASHION = 16`
`DINING = 17`
`NOT_TELLING = 18`
`ANY = 255`
## Gender This class defines the following constants:
`MALE = 0`
`FEMALE = 1`
`ANY = 2`
## DataStoreChangeMetaCompareParam **def _\_init__**()
Creates a new `DataStoreChangeMetaCompareParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
comparison_flag: int
name: str
permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
delete_permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
period: int
meta_binary: bytes
tags: list[str]
referred_count: int
data_type: int
status: int

## DataStoreChangeMetaParam **def _\_init__**()
Creates a new `DataStoreChangeMetaParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
modifies_flag: int
name: str
permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
delete_permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
period: int
meta_binary: bytes
tags: list[str]
update_password: int
referred_count: int
data_type: int
status: int
compare_param: [DataStoreChangeMetaCompareParam](#datastorechangemetacompareparam) = [DataStoreChangeMetaCompareParam](#datastorechangemetacompareparam)()
persistence_target: [DataStorePersistenceTarget](#datastorepersistencetarget) = [DataStorePersistenceTarget](#datastorepersistencetarget)()

## DataStoreChangeMetaParamV1 **def _\_init__**()
Creates a new `DataStoreChangeMetaParamV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
modifies_flag: int
name: str
permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
delete_permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
period: int
meta_binary: bytes
tags: list[str]
update_password: int

## DataStoreCompletePostParam **def _\_init__**()
Creates a new `DataStoreCompletePostParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
success: bool

## DataStoreCompletePostParamV1 **def _\_init__**()
Creates a new `DataStoreCompletePostParamV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
success: bool

## DataStoreCompleteUpdateParam **def _\_init__**()
Creates a new `DataStoreCompleteUpdateParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
version: int
success: bool

## DataStoreDeleteParam **def _\_init__**()
Creates a new `DataStoreDeleteParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
update_password: int

## DataStoreGetMetaParam **def _\_init__**()
Creates a new `DataStoreGetMetaParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int = 0
persistence_target: [DataStorePersistenceTarget](#datastorepersistencetarget) = [DataStorePersistenceTarget](#datastorepersistencetarget)()
result_option: int = 0
access_password: int = 0

## DataStoreGetNewArrivedNotificationsParam **def _\_init__**()
Creates a new `DataStoreGetNewArrivedNotificationsParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
last_notification_id: int
limit: int

## DataStoreGetNotificationUrlParam **def _\_init__**()
Creates a new `DataStoreGetNotificationUrlParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
previous_url: str

## DataStoreGetSpecificMetaParam **def _\_init__**()
Creates a new `DataStoreGetSpecificMetaParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_ids: list[int]

## DataStoreGetSpecificMetaParamV1 **def _\_init__**()
Creates a new `DataStoreGetSpecificMetaParamV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_ids: list[int]

## DataStoreKeyValue **def _\_init__**()
Creates a new `DataStoreKeyValue` instance. Required fields must be filled in manually. The following fields are defined in this class:
key: str
value: str

## DataStoreMetaInfo **def _\_init__**()
Creates a new `DataStoreMetaInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
owner_id: int
size: int
name: str
data_type: int
meta_binary: bytes
permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
delete_permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
create_time: [DateTime](common.md#datetime)
update_time: [DateTime](common.md#datetime)
period: int
status: int
referred_count: int
refer_data_id: int
flag: int
referred_time: [DateTime](common.md#datetime)
expire_time: [DateTime](common.md#datetime)
tags: list[str]
ratings: list[[DataStoreRatingInfoWithSlot](#datastoreratinginfowithslot)]

## DataStoreNotification **def _\_init__**()
Creates a new `DataStoreNotification` instance. Required fields must be filled in manually. The following fields are defined in this class:
notification_id: int
data_id: int

## DataStoreNotificationV1 **def _\_init__**()
Creates a new `DataStoreNotificationV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
notification_id: int
data_id: int

## DataStorePasswordInfo **def _\_init__**()
Creates a new `DataStorePasswordInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
access_password: int
update_password: int

## DataStorePermission **def _\_init__**()
Creates a new `DataStorePermission` instance. Required fields must be filled in manually. The following fields are defined in this class:
permission: int = 3
recipients: list[int] = []

## DataStorePersistenceInfo **def _\_init__**()
Creates a new `DataStorePersistenceInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
owner_id: int
slot_id: int
data_id: int

## DataStorePersistenceInitParam **def _\_init__**()
Creates a new `DataStorePersistenceInitParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
persistence_id: int = 65535
delete_last_object: bool = True

## DataStorePersistenceTarget **def _\_init__**()
Creates a new `DataStorePersistenceTarget` instance. Required fields must be filled in manually. The following fields are defined in this class:
owner_id: int = 0
persistence_id: int = 65535

## DataStorePrepareGetParam **def _\_init__**()
Creates a new `DataStorePrepareGetParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int = 0
lock_id: int = 0
persistence_target: [DataStorePersistenceTarget](#datastorepersistencetarget) = [DataStorePersistenceTarget](#datastorepersistencetarget)()
access_password: int = 0
If `nex.version` >= 30500:
extra_data: list[str] = []


## DataStorePrepareGetParamV1 **def _\_init__**()
Creates a new `DataStorePrepareGetParamV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
lock_id: int = 0

## DataStorePreparePostParam **def _\_init__**()
Creates a new `DataStorePreparePostParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
size: int
name: str
data_type: int
meta_binary: bytes
permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
delete_permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
flag: int
period: int
refer_data_id: int = 0
tags: list[str] = []
rating_init_param: list[[DataStoreRatingInitParamWithSlot](#datastoreratinginitparamwithslot)] = []
persistence_init_param: [DataStorePersistenceInitParam](#datastorepersistenceinitparam) = [DataStorePersistenceInitParam](#datastorepersistenceinitparam)()
If `nex.version` >= 30500:
extra_data: list[str]


## DataStorePreparePostParamV1 **def _\_init__**()
Creates a new `DataStorePreparePostParamV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
size: int
name: str
data_type: int = 0
meta_binary: bytes = b""
permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
delete_permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
flag: int
period: int
refer_data_id: int = 0
tags: list[str]
rating_init_param: list[[DataStoreRatingInitParamWithSlot](#datastoreratinginitparamwithslot)]

## DataStorePrepareUpdateParam **def _\_init__**()
Creates a new `DataStorePrepareUpdateParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
size: int
update_password: int
extra_data: list[str]

## DataStoreRateObjectParam **def _\_init__**()
Creates a new `DataStoreRateObjectParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
rating_value: int
access_password: int

## DataStoreRatingInfo **def _\_init__**()
Creates a new `DataStoreRatingInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
total_value: int
count: int
initial_value: int

## DataStoreRatingInfoWithSlot **def _\_init__**()
Creates a new `DataStoreRatingInfoWithSlot` instance. Required fields must be filled in manually. The following fields are defined in this class:
slot: int
info: [DataStoreRatingInfo](#datastoreratinginfo) = [DataStoreRatingInfo](#datastoreratinginfo)()

## DataStoreRatingInitParam **def _\_init__**()
Creates a new `DataStoreRatingInitParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
flag: int
internal_flag: int
lock_type: int
initial_value: int
range_min: int
range_max: int
period_hour: int
period_duration: int

## DataStoreRatingInitParamWithSlot **def _\_init__**()
Creates a new `DataStoreRatingInitParamWithSlot` instance. Required fields must be filled in manually. The following fields are defined in this class:
slot: int
param: [DataStoreRatingInitParam](#datastoreratinginitparam) = [DataStoreRatingInitParam](#datastoreratinginitparam)()

## DataStoreRatingLog **def _\_init__**()
Creates a new `DataStoreRatingLog` instance. Required fields must be filled in manually. The following fields are defined in this class:
is_rated: bool
pid: int
rating_value: int
lock_expiration_time: [DateTime](common.md#datetime)

## DataStoreRatingTarget **def _\_init__**()
Creates a new `DataStoreRatingTarget` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
slot: int

## DataStoreReqGetAdditionalMeta **def _\_init__**()
Creates a new `DataStoreReqGetAdditionalMeta` instance. Required fields must be filled in manually. The following fields are defined in this class:
owner_id: int
data_type: int
version: int
meta_binary: bytes

## DataStoreReqGetInfo **def _\_init__**()
Creates a new `DataStoreReqGetInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
url: str
headers: list[[DataStoreKeyValue](#datastorekeyvalue)]
size: int
root_ca_cert: bytes
If `nex.version` >= 30500:
data_id: int


## DataStoreReqGetInfoV1 **def _\_init__**()
Creates a new `DataStoreReqGetInfoV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
url: str
headers: list[[DataStoreKeyValue](#datastorekeyvalue)]
size: int
root_ca_cert: bytes

## DataStoreReqGetNotificationUrlInfo **def _\_init__**()
Creates a new `DataStoreReqGetNotificationUrlInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
url: str
key: str
query: str
root_ca_cert: bytes

## DataStoreReqPostInfo **def _\_init__**()
Creates a new `DataStoreReqPostInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
url: str
headers: list[[DataStoreKeyValue](#datastorekeyvalue)]
form: list[[DataStoreKeyValue](#datastorekeyvalue)]
root_ca_cert: bytes

## DataStoreReqPostInfoV1 **def _\_init__**()
Creates a new `DataStoreReqPostInfoV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
url: str
headers: list[[DataStoreKeyValue](#datastorekeyvalue)]
form: list[[DataStoreKeyValue](#datastorekeyvalue)]
root_ca_cert: bytes

## DataStoreReqUpdateInfo **def _\_init__**()
Creates a new `DataStoreReqUpdateInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
version: int
url: str
headers: list[[DataStoreKeyValue](#datastorekeyvalue)]
form: list[[DataStoreKeyValue](#datastorekeyvalue)]
root_ca_cert: bytes

## DataStoreSearchParam **def _\_init__**()
Creates a new `DataStoreSearchParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
search_target: int = 1
owner_ids: list[int] = []
owner_type: int = 0
destination_ids: list[int] = []
data_type: int = 65535
created_after: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).future()
created_before: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).future()
updated_after: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).future()
updated_before: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).future()
refer_data_id: int = 0
tags: list[str] = []
result_order_column: int = 0
result_order: int = 0
result_range: [ResultRange](common.md#resultrange) = [ResultRange](common.md#resultrange)()
result_option: int = 0
minimal_rating_frequency: int = 0
use_cache: bool = False
total_count_enabled: bool = True
data_types: list[int] = []

## DataStoreSearchResult **def _\_init__**()
Creates a new `DataStoreSearchResult` instance. Required fields must be filled in manually. The following fields are defined in this class:
total_count: int
result: list[[DataStoreMetaInfo](#datastoremetainfo)]
total_count_type: int

## DataStoreSpecificMetaInfo **def _\_init__**()
Creates a new `DataStoreSpecificMetaInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
owner_id: int
size: int
data_type: int
version: int

## DataStoreSpecificMetaInfoV1 **def _\_init__**()
Creates a new `DataStoreSpecificMetaInfoV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
owner_id: int
size: int
data_type: int
version: int

## DataStoreTouchObjectParam **def _\_init__**()
Creates a new `DataStoreTouchObjectParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
lock_id: int
access_password: int

## MiiTubeMiiInfo **def _\_init__**()
Creates a new `MiiTubeMiiInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
meta_info: [DataStoreMetaInfo](#datastoremetainfo) = [DataStoreMetaInfo](#datastoremetainfo)()
category: int
ranking_type: int

## MiiTubeSearchParam **def _\_init__**()
Creates a new `MiiTubeSearchParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
name: str
page: int = 0
category: int = 255
gender: int = 2
country: int
search_type: int = 0
result_option: int = 0

## MiiTubeSearchResult **def _\_init__**()
Creates a new `MiiTubeSearchResult` instance. Required fields must be filled in manually. The following fields are defined in this class:
result: list[[MiiTubeMiiInfo](#miitubemiiinfo)]
count: int
page: int
has_next: bool

================================================ FILE: docs/reference/nex/datastore_smm.md ================================================ # Module: nintendo.nex.datastore_smm Provides a client and server for the `DataStoreProtocolSMM`. This page was generated automatically from `datastore_smm.proto`. **class** [DataStoreClientSMM](#datastoreclientsmm)
The client for the `DataStoreProtocolSMM`. **class** [DataStoreServerSMM](#datastoreserversmm)
The server for the `DataStoreProtocolSMM`. **class** [DataStoreChangeMetaCompareParam](#datastorechangemetacompareparam)([Structure](common.md))
**class** [DataStoreChangeMetaParam](#datastorechangemetaparam)([Structure](common.md))
**class** [DataStoreChangeMetaParamV1](#datastorechangemetaparamv1)([Structure](common.md))
**class** [DataStoreCompletePostParam](#datastorecompletepostparam)([Structure](common.md))
**class** [DataStoreCompletePostParamV1](#datastorecompletepostparamv1)([Structure](common.md))
**class** [DataStoreCompleteUpdateParam](#datastorecompleteupdateparam)([Structure](common.md))
**class** [DataStoreDeleteParam](#datastoredeleteparam)([Structure](common.md))
**class** [DataStoreGetMetaParam](#datastoregetmetaparam)([Structure](common.md))
**class** [DataStoreGetNewArrivedNotificationsParam](#datastoregetnewarrivednotificationsparam)([Structure](common.md))
**class** [DataStoreGetNotificationUrlParam](#datastoregetnotificationurlparam)([Structure](common.md))
**class** [DataStoreGetSpecificMetaParam](#datastoregetspecificmetaparam)([Structure](common.md))
**class** [DataStoreGetSpecificMetaParamV1](#datastoregetspecificmetaparamv1)([Structure](common.md))
**class** [DataStoreKeyValue](#datastorekeyvalue)([Structure](common.md))
**class** [DataStoreMetaInfo](#datastoremetainfo)([Structure](common.md))
**class** [DataStoreNotification](#datastorenotification)([Structure](common.md))
**class** [DataStoreNotificationV1](#datastorenotificationv1)([Structure](common.md))
**class** [DataStorePasswordInfo](#datastorepasswordinfo)([Structure](common.md))
**class** [DataStorePermission](#datastorepermission)([Structure](common.md))
**class** [DataStorePersistenceInfo](#datastorepersistenceinfo)([Structure](common.md))
**class** [DataStorePersistenceInitParam](#datastorepersistenceinitparam)([Structure](common.md))
**class** [DataStorePersistenceTarget](#datastorepersistencetarget)([Structure](common.md))
**class** [DataStorePrepareGetParam](#datastorepreparegetparam)([Structure](common.md))
**class** [DataStorePrepareGetParamV1](#datastorepreparegetparamv1)([Structure](common.md))
**class** [DataStorePreparePostParam](#datastorepreparepostparam)([Structure](common.md))
**class** [DataStorePreparePostParamV1](#datastorepreparepostparamv1)([Structure](common.md))
**class** [DataStorePrepareUpdateParam](#datastoreprepareupdateparam)([Structure](common.md))
**class** [DataStoreRateObjectParam](#datastorerateobjectparam)([Structure](common.md))
**class** [DataStoreRatingInfo](#datastoreratinginfo)([Structure](common.md))
**class** [DataStoreRatingInfoWithSlot](#datastoreratinginfowithslot)([Structure](common.md))
**class** [DataStoreRatingInitParam](#datastoreratinginitparam)([Structure](common.md))
**class** [DataStoreRatingInitParamWithSlot](#datastoreratinginitparamwithslot)([Structure](common.md))
**class** [DataStoreRatingLog](#datastoreratinglog)([Structure](common.md))
**class** [DataStoreRatingTarget](#datastoreratingtarget)([Structure](common.md))
**class** [DataStoreReqGetAdditionalMeta](#datastorereqgetadditionalmeta)([Structure](common.md))
**class** [DataStoreReqGetInfo](#datastorereqgetinfo)([Structure](common.md))
**class** [DataStoreReqGetInfoV1](#datastorereqgetinfov1)([Structure](common.md))
**class** [DataStoreReqGetNotificationUrlInfo](#datastorereqgetnotificationurlinfo)([Structure](common.md))
**class** [DataStoreReqPostInfo](#datastorereqpostinfo)([Structure](common.md))
**class** [DataStoreReqPostInfoV1](#datastorereqpostinfov1)([Structure](common.md))
**class** [DataStoreReqUpdateInfo](#datastorerequpdateinfo)([Structure](common.md))
**class** [DataStoreSearchParam](#datastoresearchparam)([Structure](common.md))
**class** [DataStoreSearchResult](#datastoresearchresult)([Structure](common.md))
**class** [DataStoreSpecificMetaInfo](#datastorespecificmetainfo)([Structure](common.md))
**class** [DataStoreSpecificMetaInfoV1](#datastorespecificmetainfov1)([Structure](common.md))
**class** [DataStoreTouchObjectParam](#datastoretouchobjectparam)([Structure](common.md))
## DataStoreClientSMM **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`DataStoreClientSMM`](#datastoreclientsmm). **async def prepare_get_object_v1**(param: [DataStorePrepareGetParamV1](#datastorepreparegetparamv1)) -> [DataStoreReqGetInfoV1](#datastorereqgetinfov1)
Calls method `1` on the server. **async def prepare_post_object_v1**(param: [DataStorePreparePostParamV1](#datastorepreparepostparamv1)) -> [DataStoreReqPostInfoV1](#datastorereqpostinfov1)
Calls method `2` on the server. **async def complete_post_object_v1**(param: [DataStoreCompletePostParamV1](#datastorecompletepostparamv1)) -> None
Calls method `3` on the server. **async def delete_object**(param: [DataStoreDeleteParam](#datastoredeleteparam)) -> None
Calls method `4` on the server. **async def delete_objects**(param: list[[DataStoreDeleteParam](#datastoredeleteparam)], transactional: bool) -> list[[Result](common.md#result)]
Calls method `5` on the server. **async def change_meta_v1**(param: [DataStoreChangeMetaParamV1](#datastorechangemetaparamv1)) -> None
Calls method `6` on the server. **async def change_metas_v1**(data_ids: list[int], param: list[[DataStoreChangeMetaParamV1](#datastorechangemetaparamv1)], transactional: bool) -> list[[Result](common.md#result)]
Calls method `7` on the server. **async def get_meta**(param: [DataStoreGetMetaParam](#datastoregetmetaparam)) -> [DataStoreMetaInfo](#datastoremetainfo)
Calls method `8` on the server. **async def get_metas**(data_ids: list[int], param: [DataStoreGetMetaParam](#datastoregetmetaparam)) -> [RMCResponse](common.md)
Calls method `9` on the server. The RMC response has the following attributes:
info: list[[DataStoreMetaInfo](#datastoremetainfo)]
results: list[[Result](common.md#result)]
**async def prepare_update_object**(param: [DataStorePrepareUpdateParam](#datastoreprepareupdateparam)) -> [DataStoreReqUpdateInfo](#datastorerequpdateinfo)
Calls method `10` on the server. **async def complete_update_object**(param: [DataStoreCompleteUpdateParam](#datastorecompleteupdateparam)) -> None
Calls method `11` on the server. **async def search_object**(param: [DataStoreSearchParam](#datastoresearchparam)) -> [DataStoreSearchResult](#datastoresearchresult)
Calls method `12` on the server. **async def get_notification_url**(param: [DataStoreGetNotificationUrlParam](#datastoregetnotificationurlparam)) -> [DataStoreReqGetNotificationUrlInfo](#datastorereqgetnotificationurlinfo)
Calls method `13` on the server. **async def get_new_arrived_notifications_v1**(param: [DataStoreGetNewArrivedNotificationsParam](#datastoregetnewarrivednotificationsparam)) -> [RMCResponse](common.md)
Calls method `14` on the server. The RMC response has the following attributes:
result: list[[DataStoreNotificationV1](#datastorenotificationv1)]
has_next: bool
**async def rate_object**(target: [DataStoreRatingTarget](#datastoreratingtarget), param: [DataStoreRateObjectParam](#datastorerateobjectparam), fetch_ratings: bool) -> [DataStoreRatingInfo](#datastoreratinginfo)
Calls method `15` on the server. **async def get_rating**(target: [DataStoreRatingTarget](#datastoreratingtarget), access_password: int) -> [DataStoreRatingInfo](#datastoreratinginfo)
Calls method `16` on the server. **async def get_ratings**(data_ids: list[int], access_password: int) -> [RMCResponse](common.md)
Calls method `17` on the server. The RMC response has the following attributes:
ratings: list[list[[DataStoreRatingInfoWithSlot](#datastoreratinginfowithslot)]]
results: list[[Result](common.md#result)]
**async def reset_rating**(target: [DataStoreRatingTarget](#datastoreratingtarget), update_password: int) -> None
Calls method `18` on the server. **async def reset_ratings**(data_ids: list[int], transactional: bool) -> list[[Result](common.md#result)]
Calls method `19` on the server. **async def get_specific_meta_v1**(param: [DataStoreGetSpecificMetaParamV1](#datastoregetspecificmetaparamv1)) -> list[[DataStoreSpecificMetaInfoV1](#datastorespecificmetainfov1)]
Calls method `20` on the server. **async def post_meta_binary**(param: [DataStorePreparePostParam](#datastorepreparepostparam)) -> int
Calls method `21` on the server. **async def touch_object**(param: [DataStoreTouchObjectParam](#datastoretouchobjectparam)) -> None
Calls method `22` on the server. **async def get_rating_with_log**(target: [DataStoreRatingTarget](#datastoreratingtarget), access_password: int) -> [RMCResponse](common.md)
Calls method `23` on the server. The RMC response has the following attributes:
rating: [DataStoreRatingInfo](#datastoreratinginfo)
log: [DataStoreRatingLog](#datastoreratinglog)
**async def prepare_post_object**(param: [DataStorePreparePostParam](#datastorepreparepostparam)) -> [DataStoreReqPostInfo](#datastorereqpostinfo)
Calls method `24` on the server. **async def prepare_get_object**(param: [DataStorePrepareGetParam](#datastorepreparegetparam)) -> [DataStoreReqGetInfo](#datastorereqgetinfo)
Calls method `25` on the server. **async def complete_post_object**(param: [DataStoreCompletePostParam](#datastorecompletepostparam)) -> None
Calls method `26` on the server. **async def get_new_arrived_notifications**(param: [DataStoreGetNewArrivedNotificationsParam](#datastoregetnewarrivednotificationsparam)) -> [RMCResponse](common.md)
Calls method `27` on the server. The RMC response has the following attributes:
result: list[[DataStoreNotification](#datastorenotification)]
has_next: bool
**async def get_specific_meta**(param: [DataStoreGetSpecificMetaParam](#datastoregetspecificmetaparam)) -> list[[DataStoreSpecificMetaInfo](#datastorespecificmetainfo)]
Calls method `28` on the server. **async def get_persistence_info**(owner_id: int, slot_id: int) -> [DataStorePersistenceInfo](#datastorepersistenceinfo)
Calls method `29` on the server. **async def get_persistence_infos**(owner_id: int, slot_ids: list[int]) -> [RMCResponse](common.md)
Calls method `30` on the server. The RMC response has the following attributes:
infos: list[[DataStorePersistenceInfo](#datastorepersistenceinfo)]
results: list[[Result](common.md#result)]
**async def perpetuate_object**(persistence_slot_id: int, data_id: int, delete_last_object: bool) -> None
Calls method `31` on the server. **async def unperpetuate_object**(persistence_slot_id: int, delete_last_object: bool) -> None
Calls method `32` on the server. **async def prepare_get_object_or_meta_binary**(param: [DataStorePrepareGetParam](#datastorepreparegetparam)) -> [RMCResponse](common.md)
Calls method `33` on the server. The RMC response has the following attributes:
get_info: [DataStoreReqGetInfo](#datastorereqgetinfo)
additional_meta: [DataStoreReqGetAdditionalMeta](#datastorereqgetadditionalmeta)
**async def get_password_info**(data_id: int) -> [DataStorePasswordInfo](#datastorepasswordinfo)
Calls method `34` on the server. **async def get_password_infos**(data_ids: list[int]) -> [RMCResponse](common.md)
Calls method `35` on the server. The RMC response has the following attributes:
infos: list[[DataStorePasswordInfo](#datastorepasswordinfo)]
results: list[[Result](common.md#result)]
**async def get_metas_multiple_param**(params: list[[DataStoreGetMetaParam](#datastoregetmetaparam)]) -> [RMCResponse](common.md)
Calls method `36` on the server. The RMC response has the following attributes:
infos: list[[DataStoreMetaInfo](#datastoremetainfo)]
results: list[[Result](common.md#result)]
**async def complete_post_objects**(data_ids: list[int]) -> None
Calls method `37` on the server. **async def change_meta**(param: [DataStoreChangeMetaParam](#datastorechangemetaparam)) -> None
Calls method `38` on the server. **async def change_metas**(data_ids: list[int], param: list[[DataStoreChangeMetaParam](#datastorechangemetaparam)], transactional: bool) -> list[[Result](common.md#result)]
Calls method `39` on the server. **async def rate_objects**(targets: list[[DataStoreRatingTarget](#datastoreratingtarget)], param: list[[DataStoreRateObjectParam](#datastorerateobjectparam)], transactional: bool, fetch_ratings: bool) -> [RMCResponse](common.md)
Calls method `40` on the server. The RMC response has the following attributes:
infos: list[[DataStoreRatingInfo](#datastoreratinginfo)]
results: list[[Result](common.md#result)]
**async def post_meta_binary_with_data_id**(data_id: int, param: [DataStorePreparePostParam](#datastorepreparepostparam)) -> None
Calls method `41` on the server. **async def post_meta_binaries_with_data_id**(data_ids: list[int], param: list[[DataStorePreparePostParam](#datastorepreparepostparam)], transactional: bool) -> list[[Result](common.md#result)]
Calls method `42` on the server. **async def rate_object_with_posting**(target: [DataStoreRatingTarget](#datastoreratingtarget), rate_param: [DataStoreRateObjectParam](#datastorerateobjectparam), post_param: [DataStorePreparePostParam](#datastorepreparepostparam), fetch_ratings: bool) -> [DataStoreRatingInfo](#datastoreratinginfo)
Calls method `43` on the server. **async def rate_objects_with_posting**(targets: list[[DataStoreRatingTarget](#datastoreratingtarget)], rate_param: list[[DataStoreRateObjectParam](#datastorerateobjectparam)], post_param: list[[DataStorePreparePostParam](#datastorepreparepostparam)], transactional: bool, fetch_ratings: bool) -> [RMCResponse](common.md)
Calls method `44` on the server. The RMC response has the following attributes:
ratings: list[[DataStoreRatingInfo](#datastoreratinginfo)]
results: list[[Result](common.md#result)]
**async def get_object_infos**(data_ids: list[int]) -> [RMCResponse](common.md)
Calls method `45` on the server. The RMC response has the following attributes:
infos: list[[DataStoreReqGetInfo](#datastorereqgetinfo)]
results: list[[Result](common.md#result)]
**async def search_object_light**(param: [DataStoreSearchParam](#datastoresearchparam)) -> [DataStoreSearchResult](#datastoresearchresult)
Calls method `46` on the server. **async def get_application_config**(id: int) -> list[int]
Calls method `61` on the server. **async def get_application_config_string**(id: int) -> list[str]
Calls method `74` on the server. ## DataStoreServerSMM **def _\_init__**()
Creates a new [`DataStoreServerSMM`](#datastoreserversmm). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def prepare_get_object_v1**(client: [RMCClient](rmc.md#rmcclient), param: [DataStorePrepareGetParamV1](#datastorepreparegetparamv1)) -> [DataStoreReqGetInfoV1](#datastorereqgetinfov1)
Handler for method `1`. This method should be overridden by a subclass. **async def prepare_post_object_v1**(client: [RMCClient](rmc.md#rmcclient), param: [DataStorePreparePostParamV1](#datastorepreparepostparamv1)) -> [DataStoreReqPostInfoV1](#datastorereqpostinfov1)
Handler for method `2`. This method should be overridden by a subclass. **async def complete_post_object_v1**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreCompletePostParamV1](#datastorecompletepostparamv1)) -> None
Handler for method `3`. This method should be overridden by a subclass. **async def delete_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreDeleteParam](#datastoredeleteparam)) -> None
Handler for method `4`. This method should be overridden by a subclass. **async def delete_objects**(client: [RMCClient](rmc.md#rmcclient), param: list[[DataStoreDeleteParam](#datastoredeleteparam)], transactional: bool) -> list[[Result](common.md#result)]
Handler for method `5`. This method should be overridden by a subclass. **async def change_meta_v1**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreChangeMetaParamV1](#datastorechangemetaparamv1)) -> None
Handler for method `6`. This method should be overridden by a subclass. **async def change_metas_v1**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int], param: list[[DataStoreChangeMetaParamV1](#datastorechangemetaparamv1)], transactional: bool) -> list[[Result](common.md#result)]
Handler for method `7`. This method should be overridden by a subclass. **async def get_meta**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreGetMetaParam](#datastoregetmetaparam)) -> [DataStoreMetaInfo](#datastoremetainfo)
Handler for method `8`. This method should be overridden by a subclass. **async def get_metas**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int], param: [DataStoreGetMetaParam](#datastoregetmetaparam)) -> [RMCResponse](common.md)
Handler for method `9`. This method should be overridden by a subclass. The RMC response must have the following attributes:
info: list[[DataStoreMetaInfo](#datastoremetainfo)]
results: list[[Result](common.md#result)]
**async def prepare_update_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStorePrepareUpdateParam](#datastoreprepareupdateparam)) -> [DataStoreReqUpdateInfo](#datastorerequpdateinfo)
Handler for method `10`. This method should be overridden by a subclass. **async def complete_update_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreCompleteUpdateParam](#datastorecompleteupdateparam)) -> None
Handler for method `11`. This method should be overridden by a subclass. **async def search_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreSearchParam](#datastoresearchparam)) -> [DataStoreSearchResult](#datastoresearchresult)
Handler for method `12`. This method should be overridden by a subclass. **async def get_notification_url**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreGetNotificationUrlParam](#datastoregetnotificationurlparam)) -> [DataStoreReqGetNotificationUrlInfo](#datastorereqgetnotificationurlinfo)
Handler for method `13`. This method should be overridden by a subclass. **async def get_new_arrived_notifications_v1**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreGetNewArrivedNotificationsParam](#datastoregetnewarrivednotificationsparam)) -> [RMCResponse](common.md)
Handler for method `14`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: list[[DataStoreNotificationV1](#datastorenotificationv1)]
has_next: bool
**async def rate_object**(client: [RMCClient](rmc.md#rmcclient), target: [DataStoreRatingTarget](#datastoreratingtarget), param: [DataStoreRateObjectParam](#datastorerateobjectparam), fetch_ratings: bool) -> [DataStoreRatingInfo](#datastoreratinginfo)
Handler for method `15`. This method should be overridden by a subclass. **async def get_rating**(client: [RMCClient](rmc.md#rmcclient), target: [DataStoreRatingTarget](#datastoreratingtarget), access_password: int) -> [DataStoreRatingInfo](#datastoreratinginfo)
Handler for method `16`. This method should be overridden by a subclass. **async def get_ratings**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int], access_password: int) -> [RMCResponse](common.md)
Handler for method `17`. This method should be overridden by a subclass. The RMC response must have the following attributes:
ratings: list[list[[DataStoreRatingInfoWithSlot](#datastoreratinginfowithslot)]]
results: list[[Result](common.md#result)]
**async def reset_rating**(client: [RMCClient](rmc.md#rmcclient), target: [DataStoreRatingTarget](#datastoreratingtarget), update_password: int) -> None
Handler for method `18`. This method should be overridden by a subclass. **async def reset_ratings**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int], transactional: bool) -> list[[Result](common.md#result)]
Handler for method `19`. This method should be overridden by a subclass. **async def get_specific_meta_v1**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreGetSpecificMetaParamV1](#datastoregetspecificmetaparamv1)) -> list[[DataStoreSpecificMetaInfoV1](#datastorespecificmetainfov1)]
Handler for method `20`. This method should be overridden by a subclass. **async def post_meta_binary**(client: [RMCClient](rmc.md#rmcclient), param: [DataStorePreparePostParam](#datastorepreparepostparam)) -> int
Handler for method `21`. This method should be overridden by a subclass. **async def touch_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreTouchObjectParam](#datastoretouchobjectparam)) -> None
Handler for method `22`. This method should be overridden by a subclass. **async def get_rating_with_log**(client: [RMCClient](rmc.md#rmcclient), target: [DataStoreRatingTarget](#datastoreratingtarget), access_password: int) -> [RMCResponse](common.md)
Handler for method `23`. This method should be overridden by a subclass. The RMC response must have the following attributes:
rating: [DataStoreRatingInfo](#datastoreratinginfo)
log: [DataStoreRatingLog](#datastoreratinglog)
**async def prepare_post_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStorePreparePostParam](#datastorepreparepostparam)) -> [DataStoreReqPostInfo](#datastorereqpostinfo)
Handler for method `24`. This method should be overridden by a subclass. **async def prepare_get_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStorePrepareGetParam](#datastorepreparegetparam)) -> [DataStoreReqGetInfo](#datastorereqgetinfo)
Handler for method `25`. This method should be overridden by a subclass. **async def complete_post_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreCompletePostParam](#datastorecompletepostparam)) -> None
Handler for method `26`. This method should be overridden by a subclass. **async def get_new_arrived_notifications**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreGetNewArrivedNotificationsParam](#datastoregetnewarrivednotificationsparam)) -> [RMCResponse](common.md)
Handler for method `27`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: list[[DataStoreNotification](#datastorenotification)]
has_next: bool
**async def get_specific_meta**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreGetSpecificMetaParam](#datastoregetspecificmetaparam)) -> list[[DataStoreSpecificMetaInfo](#datastorespecificmetainfo)]
Handler for method `28`. This method should be overridden by a subclass. **async def get_persistence_info**(client: [RMCClient](rmc.md#rmcclient), owner_id: int, slot_id: int) -> [DataStorePersistenceInfo](#datastorepersistenceinfo)
Handler for method `29`. This method should be overridden by a subclass. **async def get_persistence_infos**(client: [RMCClient](rmc.md#rmcclient), owner_id: int, slot_ids: list[int]) -> [RMCResponse](common.md)
Handler for method `30`. This method should be overridden by a subclass. The RMC response must have the following attributes:
infos: list[[DataStorePersistenceInfo](#datastorepersistenceinfo)]
results: list[[Result](common.md#result)]
**async def perpetuate_object**(client: [RMCClient](rmc.md#rmcclient), persistence_slot_id: int, data_id: int, delete_last_object: bool) -> None
Handler for method `31`. This method should be overridden by a subclass. **async def unperpetuate_object**(client: [RMCClient](rmc.md#rmcclient), persistence_slot_id: int, delete_last_object: bool) -> None
Handler for method `32`. This method should be overridden by a subclass. **async def prepare_get_object_or_meta_binary**(client: [RMCClient](rmc.md#rmcclient), param: [DataStorePrepareGetParam](#datastorepreparegetparam)) -> [RMCResponse](common.md)
Handler for method `33`. This method should be overridden by a subclass. The RMC response must have the following attributes:
get_info: [DataStoreReqGetInfo](#datastorereqgetinfo)
additional_meta: [DataStoreReqGetAdditionalMeta](#datastorereqgetadditionalmeta)
**async def get_password_info**(client: [RMCClient](rmc.md#rmcclient), data_id: int) -> [DataStorePasswordInfo](#datastorepasswordinfo)
Handler for method `34`. This method should be overridden by a subclass. **async def get_password_infos**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int]) -> [RMCResponse](common.md)
Handler for method `35`. This method should be overridden by a subclass. The RMC response must have the following attributes:
infos: list[[DataStorePasswordInfo](#datastorepasswordinfo)]
results: list[[Result](common.md#result)]
**async def get_metas_multiple_param**(client: [RMCClient](rmc.md#rmcclient), params: list[[DataStoreGetMetaParam](#datastoregetmetaparam)]) -> [RMCResponse](common.md)
Handler for method `36`. This method should be overridden by a subclass. The RMC response must have the following attributes:
infos: list[[DataStoreMetaInfo](#datastoremetainfo)]
results: list[[Result](common.md#result)]
**async def complete_post_objects**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int]) -> None
Handler for method `37`. This method should be overridden by a subclass. **async def change_meta**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreChangeMetaParam](#datastorechangemetaparam)) -> None
Handler for method `38`. This method should be overridden by a subclass. **async def change_metas**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int], param: list[[DataStoreChangeMetaParam](#datastorechangemetaparam)], transactional: bool) -> list[[Result](common.md#result)]
Handler for method `39`. This method should be overridden by a subclass. **async def rate_objects**(client: [RMCClient](rmc.md#rmcclient), targets: list[[DataStoreRatingTarget](#datastoreratingtarget)], param: list[[DataStoreRateObjectParam](#datastorerateobjectparam)], transactional: bool, fetch_ratings: bool) -> [RMCResponse](common.md)
Handler for method `40`. This method should be overridden by a subclass. The RMC response must have the following attributes:
infos: list[[DataStoreRatingInfo](#datastoreratinginfo)]
results: list[[Result](common.md#result)]
**async def post_meta_binary_with_data_id**(client: [RMCClient](rmc.md#rmcclient), data_id: int, param: [DataStorePreparePostParam](#datastorepreparepostparam)) -> None
Handler for method `41`. This method should be overridden by a subclass. **async def post_meta_binaries_with_data_id**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int], param: list[[DataStorePreparePostParam](#datastorepreparepostparam)], transactional: bool) -> list[[Result](common.md#result)]
Handler for method `42`. This method should be overridden by a subclass. **async def rate_object_with_posting**(client: [RMCClient](rmc.md#rmcclient), target: [DataStoreRatingTarget](#datastoreratingtarget), rate_param: [DataStoreRateObjectParam](#datastorerateobjectparam), post_param: [DataStorePreparePostParam](#datastorepreparepostparam), fetch_ratings: bool) -> [DataStoreRatingInfo](#datastoreratinginfo)
Handler for method `43`. This method should be overridden by a subclass. **async def rate_objects_with_posting**(client: [RMCClient](rmc.md#rmcclient), targets: list[[DataStoreRatingTarget](#datastoreratingtarget)], rate_param: list[[DataStoreRateObjectParam](#datastorerateobjectparam)], post_param: list[[DataStorePreparePostParam](#datastorepreparepostparam)], transactional: bool, fetch_ratings: bool) -> [RMCResponse](common.md)
Handler for method `44`. This method should be overridden by a subclass. The RMC response must have the following attributes:
ratings: list[[DataStoreRatingInfo](#datastoreratinginfo)]
results: list[[Result](common.md#result)]
**async def get_object_infos**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int]) -> [RMCResponse](common.md)
Handler for method `45`. This method should be overridden by a subclass. The RMC response must have the following attributes:
infos: list[[DataStoreReqGetInfo](#datastorereqgetinfo)]
results: list[[Result](common.md#result)]
**async def search_object_light**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreSearchParam](#datastoresearchparam)) -> [DataStoreSearchResult](#datastoresearchresult)
Handler for method `46`. This method should be overridden by a subclass. **async def get_application_config**(client: [RMCClient](rmc.md#rmcclient), id: int) -> list[int]
Handler for method `61`. This method should be overridden by a subclass. **async def get_application_config_string**(client: [RMCClient](rmc.md#rmcclient), id: int) -> list[str]
Handler for method `74`. This method should be overridden by a subclass. ## DataStoreChangeMetaCompareParam **def _\_init__**()
Creates a new `DataStoreChangeMetaCompareParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
comparison_flag: int
name: str
permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
delete_permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
period: int
meta_binary: bytes
tags: list[str]
referred_count: int
data_type: int
status: int

## DataStoreChangeMetaParam **def _\_init__**()
Creates a new `DataStoreChangeMetaParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
modifies_flag: int
name: str
permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
delete_permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
period: int
meta_binary: bytes
tags: list[str]
update_password: int
referred_count: int
data_type: int
status: int
compare_param: [DataStoreChangeMetaCompareParam](#datastorechangemetacompareparam) = [DataStoreChangeMetaCompareParam](#datastorechangemetacompareparam)()
persistence_target: [DataStorePersistenceTarget](#datastorepersistencetarget) = [DataStorePersistenceTarget](#datastorepersistencetarget)()

## DataStoreChangeMetaParamV1 **def _\_init__**()
Creates a new `DataStoreChangeMetaParamV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
modifies_flag: int
name: str
permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
delete_permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
period: int
meta_binary: bytes
tags: list[str]
update_password: int

## DataStoreCompletePostParam **def _\_init__**()
Creates a new `DataStoreCompletePostParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
success: bool

## DataStoreCompletePostParamV1 **def _\_init__**()
Creates a new `DataStoreCompletePostParamV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
success: bool

## DataStoreCompleteUpdateParam **def _\_init__**()
Creates a new `DataStoreCompleteUpdateParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
version: int
success: bool

## DataStoreDeleteParam **def _\_init__**()
Creates a new `DataStoreDeleteParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
update_password: int

## DataStoreGetMetaParam **def _\_init__**()
Creates a new `DataStoreGetMetaParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int = 0
persistence_target: [DataStorePersistenceTarget](#datastorepersistencetarget) = [DataStorePersistenceTarget](#datastorepersistencetarget)()
result_option: int = 0
access_password: int = 0

## DataStoreGetNewArrivedNotificationsParam **def _\_init__**()
Creates a new `DataStoreGetNewArrivedNotificationsParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
last_notification_id: int
limit: int

## DataStoreGetNotificationUrlParam **def _\_init__**()
Creates a new `DataStoreGetNotificationUrlParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
previous_url: str

## DataStoreGetSpecificMetaParam **def _\_init__**()
Creates a new `DataStoreGetSpecificMetaParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_ids: list[int]

## DataStoreGetSpecificMetaParamV1 **def _\_init__**()
Creates a new `DataStoreGetSpecificMetaParamV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_ids: list[int]

## DataStoreKeyValue **def _\_init__**()
Creates a new `DataStoreKeyValue` instance. Required fields must be filled in manually. The following fields are defined in this class:
key: str
value: str

## DataStoreMetaInfo **def _\_init__**()
Creates a new `DataStoreMetaInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
owner_id: int
size: int
name: str
data_type: int
meta_binary: bytes
permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
delete_permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
create_time: [DateTime](common.md#datetime)
update_time: [DateTime](common.md#datetime)
period: int
status: int
referred_count: int
refer_data_id: int
flag: int
referred_time: [DateTime](common.md#datetime)
expire_time: [DateTime](common.md#datetime)
tags: list[str]
ratings: list[[DataStoreRatingInfoWithSlot](#datastoreratinginfowithslot)]

## DataStoreNotification **def _\_init__**()
Creates a new `DataStoreNotification` instance. Required fields must be filled in manually. The following fields are defined in this class:
notification_id: int
data_id: int

## DataStoreNotificationV1 **def _\_init__**()
Creates a new `DataStoreNotificationV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
notification_id: int
data_id: int

## DataStorePasswordInfo **def _\_init__**()
Creates a new `DataStorePasswordInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
access_password: int
update_password: int

## DataStorePermission **def _\_init__**()
Creates a new `DataStorePermission` instance. Required fields must be filled in manually. The following fields are defined in this class:
permission: int = 3
recipients: list[int] = []

## DataStorePersistenceInfo **def _\_init__**()
Creates a new `DataStorePersistenceInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
owner_id: int
slot_id: int
data_id: int

## DataStorePersistenceInitParam **def _\_init__**()
Creates a new `DataStorePersistenceInitParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
persistence_id: int = 65535
delete_last_object: bool = True

## DataStorePersistenceTarget **def _\_init__**()
Creates a new `DataStorePersistenceTarget` instance. Required fields must be filled in manually. The following fields are defined in this class:
owner_id: int = 0
persistence_id: int = 65535

## DataStorePrepareGetParam **def _\_init__**()
Creates a new `DataStorePrepareGetParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int = 0
lock_id: int = 0
persistence_target: [DataStorePersistenceTarget](#datastorepersistencetarget) = [DataStorePersistenceTarget](#datastorepersistencetarget)()
access_password: int = 0
If `nex.version` >= 30500:
extra_data: list[str] = []


## DataStorePrepareGetParamV1 **def _\_init__**()
Creates a new `DataStorePrepareGetParamV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
lock_id: int = 0

## DataStorePreparePostParam **def _\_init__**()
Creates a new `DataStorePreparePostParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
size: int
name: str
data_type: int
meta_binary: bytes
permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
delete_permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
flag: int
period: int
refer_data_id: int = 0
tags: list[str] = []
rating_init_param: list[[DataStoreRatingInitParamWithSlot](#datastoreratinginitparamwithslot)] = []
persistence_init_param: [DataStorePersistenceInitParam](#datastorepersistenceinitparam) = [DataStorePersistenceInitParam](#datastorepersistenceinitparam)()
If `nex.version` >= 30500:
extra_data: list[str]


## DataStorePreparePostParamV1 **def _\_init__**()
Creates a new `DataStorePreparePostParamV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
size: int
name: str
data_type: int = 0
meta_binary: bytes = b""
permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
delete_permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
flag: int
period: int
refer_data_id: int = 0
tags: list[str]
rating_init_param: list[[DataStoreRatingInitParamWithSlot](#datastoreratinginitparamwithslot)]

## DataStorePrepareUpdateParam **def _\_init__**()
Creates a new `DataStorePrepareUpdateParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
size: int
update_password: int
extra_data: list[str]

## DataStoreRateObjectParam **def _\_init__**()
Creates a new `DataStoreRateObjectParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
rating_value: int
access_password: int

## DataStoreRatingInfo **def _\_init__**()
Creates a new `DataStoreRatingInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
total_value: int
count: int
initial_value: int

## DataStoreRatingInfoWithSlot **def _\_init__**()
Creates a new `DataStoreRatingInfoWithSlot` instance. Required fields must be filled in manually. The following fields are defined in this class:
slot: int
info: [DataStoreRatingInfo](#datastoreratinginfo) = [DataStoreRatingInfo](#datastoreratinginfo)()

## DataStoreRatingInitParam **def _\_init__**()
Creates a new `DataStoreRatingInitParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
flag: int
internal_flag: int
lock_type: int
initial_value: int
range_min: int
range_max: int
period_hour: int
period_duration: int

## DataStoreRatingInitParamWithSlot **def _\_init__**()
Creates a new `DataStoreRatingInitParamWithSlot` instance. Required fields must be filled in manually. The following fields are defined in this class:
slot: int
param: [DataStoreRatingInitParam](#datastoreratinginitparam) = [DataStoreRatingInitParam](#datastoreratinginitparam)()

## DataStoreRatingLog **def _\_init__**()
Creates a new `DataStoreRatingLog` instance. Required fields must be filled in manually. The following fields are defined in this class:
is_rated: bool
pid: int
rating_value: int
lock_expiration_time: [DateTime](common.md#datetime)

## DataStoreRatingTarget **def _\_init__**()
Creates a new `DataStoreRatingTarget` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
slot: int

## DataStoreReqGetAdditionalMeta **def _\_init__**()
Creates a new `DataStoreReqGetAdditionalMeta` instance. Required fields must be filled in manually. The following fields are defined in this class:
owner_id: int
data_type: int
version: int
meta_binary: bytes

## DataStoreReqGetInfo **def _\_init__**()
Creates a new `DataStoreReqGetInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
url: str
headers: list[[DataStoreKeyValue](#datastorekeyvalue)]
size: int
root_ca_cert: bytes
If `nex.version` >= 30500:
data_id: int


## DataStoreReqGetInfoV1 **def _\_init__**()
Creates a new `DataStoreReqGetInfoV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
url: str
headers: list[[DataStoreKeyValue](#datastorekeyvalue)]
size: int
root_ca_cert: bytes

## DataStoreReqGetNotificationUrlInfo **def _\_init__**()
Creates a new `DataStoreReqGetNotificationUrlInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
url: str
key: str
query: str
root_ca_cert: bytes

## DataStoreReqPostInfo **def _\_init__**()
Creates a new `DataStoreReqPostInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
url: str
headers: list[[DataStoreKeyValue](#datastorekeyvalue)]
form: list[[DataStoreKeyValue](#datastorekeyvalue)]
root_ca_cert: bytes

## DataStoreReqPostInfoV1 **def _\_init__**()
Creates a new `DataStoreReqPostInfoV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
url: str
headers: list[[DataStoreKeyValue](#datastorekeyvalue)]
form: list[[DataStoreKeyValue](#datastorekeyvalue)]
root_ca_cert: bytes

## DataStoreReqUpdateInfo **def _\_init__**()
Creates a new `DataStoreReqUpdateInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
version: int
url: str
headers: list[[DataStoreKeyValue](#datastorekeyvalue)]
form: list[[DataStoreKeyValue](#datastorekeyvalue)]
root_ca_cert: bytes

## DataStoreSearchParam **def _\_init__**()
Creates a new `DataStoreSearchParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
search_target: int = 1
owner_ids: list[int] = []
owner_type: int = 0
destination_ids: list[int] = []
data_type: int = 65535
created_after: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).future()
created_before: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).future()
updated_after: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).future()
updated_before: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).future()
refer_data_id: int = 0
tags: list[str] = []
result_order_column: int = 0
result_order: int = 0
result_range: [ResultRange](common.md#resultrange) = [ResultRange](common.md#resultrange)()
result_option: int = 0
minimal_rating_frequency: int = 0
use_cache: bool = False
total_count_enabled: bool = True
data_types: list[int] = []

## DataStoreSearchResult **def _\_init__**()
Creates a new `DataStoreSearchResult` instance. Required fields must be filled in manually. The following fields are defined in this class:
total_count: int
result: list[[DataStoreMetaInfo](#datastoremetainfo)]
total_count_type: int

## DataStoreSpecificMetaInfo **def _\_init__**()
Creates a new `DataStoreSpecificMetaInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
owner_id: int
size: int
data_type: int
version: int

## DataStoreSpecificMetaInfoV1 **def _\_init__**()
Creates a new `DataStoreSpecificMetaInfoV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
owner_id: int
size: int
data_type: int
version: int

## DataStoreTouchObjectParam **def _\_init__**()
Creates a new `DataStoreTouchObjectParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
lock_id: int
access_password: int

================================================ FILE: docs/reference/nex/datastore_smm2.md ================================================ # Module: nintendo.nex.datastore_smm2 Provides a client and server for the `DataStoreProtocolSMM2`. This page was generated automatically from `datastore_smm2.proto`. **class** [DataStoreClientSMM2](#datastoreclientsmm2)
The client for the `DataStoreProtocolSMM2`. **class** [DataStoreServerSMM2](#datastoreserversmm2)
The server for the `DataStoreProtocolSMM2`. **class** [ClearCondition](#clearcondition)
**class** [CourseDifficulty](#coursedifficulty)
**class** [CourseOption](#courseoption)
**class** [CourseTag](#coursetag)
**class** [CourseTheme](#coursetheme)
**class** [EventCourseOption](#eventcourseoption)
**class** [GameStyle](#gamestyle)
**class** [MultiplayerStatsKeys](#multiplayerstatskeys)
**class** [PlayStatsKeys](#playstatskeys)
**class** [UserOption](#useroption)
**class** [BadgeInfo](#badgeinfo)([Structure](common.md))
**class** [CommentInfo](#commentinfo)([Structure](common.md))
**class** [CommentPictureReqGetInfoWithoutHeaders](#commentpicturereqgetinfowithoutheaders)([Structure](common.md))
**class** [CourseInfo](#courseinfo)([Structure](common.md))
**class** [CourseTimeStats](#coursetimestats)([Structure](common.md))
**class** [DataStoreChangeMetaCompareParam](#datastorechangemetacompareparam)([Structure](common.md))
**class** [DataStoreChangeMetaParam](#datastorechangemetaparam)([Structure](common.md))
**class** [DataStoreChangeMetaParamV1](#datastorechangemetaparamv1)([Structure](common.md))
**class** [DataStoreCompletePostParam](#datastorecompletepostparam)([Structure](common.md))
**class** [DataStoreCompletePostParamV1](#datastorecompletepostparamv1)([Structure](common.md))
**class** [DataStoreCompleteUpdateParam](#datastorecompleteupdateparam)([Structure](common.md))
**class** [DataStoreDeleteParam](#datastoredeleteparam)([Structure](common.md))
**class** [DataStoreGetMetaParam](#datastoregetmetaparam)([Structure](common.md))
**class** [DataStoreGetNewArrivedNotificationsParam](#datastoregetnewarrivednotificationsparam)([Structure](common.md))
**class** [DataStoreGetNotificationUrlParam](#datastoregetnotificationurlparam)([Structure](common.md))
**class** [DataStoreGetSpecificMetaParam](#datastoregetspecificmetaparam)([Structure](common.md))
**class** [DataStoreGetSpecificMetaParamV1](#datastoregetspecificmetaparamv1)([Structure](common.md))
**class** [DataStoreKeyValue](#datastorekeyvalue)([Structure](common.md))
**class** [DataStoreMetaInfo](#datastoremetainfo)([Structure](common.md))
**class** [DataStoreNotification](#datastorenotification)([Structure](common.md))
**class** [DataStoreNotificationV1](#datastorenotificationv1)([Structure](common.md))
**class** [DataStorePasswordInfo](#datastorepasswordinfo)([Structure](common.md))
**class** [DataStorePermission](#datastorepermission)([Structure](common.md))
**class** [DataStorePersistenceInfo](#datastorepersistenceinfo)([Structure](common.md))
**class** [DataStorePersistenceInitParam](#datastorepersistenceinitparam)([Structure](common.md))
**class** [DataStorePersistenceTarget](#datastorepersistencetarget)([Structure](common.md))
**class** [DataStorePrepareGetParam](#datastorepreparegetparam)([Structure](common.md))
**class** [DataStorePrepareGetParamV1](#datastorepreparegetparamv1)([Structure](common.md))
**class** [DataStorePreparePostParam](#datastorepreparepostparam)([Structure](common.md))
**class** [DataStorePreparePostParamV1](#datastorepreparepostparamv1)([Structure](common.md))
**class** [DataStorePrepareUpdateParam](#datastoreprepareupdateparam)([Structure](common.md))
**class** [DataStoreRateObjectParam](#datastorerateobjectparam)([Structure](common.md))
**class** [DataStoreRatingInfo](#datastoreratinginfo)([Structure](common.md))
**class** [DataStoreRatingInfoWithSlot](#datastoreratinginfowithslot)([Structure](common.md))
**class** [DataStoreRatingInitParam](#datastoreratinginitparam)([Structure](common.md))
**class** [DataStoreRatingInitParamWithSlot](#datastoreratinginitparamwithslot)([Structure](common.md))
**class** [DataStoreRatingLog](#datastoreratinglog)([Structure](common.md))
**class** [DataStoreRatingTarget](#datastoreratingtarget)([Structure](common.md))
**class** [DataStoreReqGetAdditionalMeta](#datastorereqgetadditionalmeta)([Structure](common.md))
**class** [DataStoreReqGetInfo](#datastorereqgetinfo)([Structure](common.md))
**class** [DataStoreReqGetInfoV1](#datastorereqgetinfov1)([Structure](common.md))
**class** [DataStoreReqGetNotificationUrlInfo](#datastorereqgetnotificationurlinfo)([Structure](common.md))
**class** [DataStoreReqPostInfo](#datastorereqpostinfo)([Structure](common.md))
**class** [DataStoreReqPostInfoV1](#datastorereqpostinfov1)([Structure](common.md))
**class** [DataStoreReqUpdateInfo](#datastorerequpdateinfo)([Structure](common.md))
**class** [DataStoreSearchParam](#datastoresearchparam)([Structure](common.md))
**class** [DataStoreSearchResult](#datastoresearchresult)([Structure](common.md))
**class** [DataStoreSpecificMetaInfo](#datastorespecificmetainfo)([Structure](common.md))
**class** [DataStoreSpecificMetaInfoV1](#datastorespecificmetainfov1)([Structure](common.md))
**class** [DataStoreTouchObjectParam](#datastoretouchobjectparam)([Structure](common.md))
**class** [DeathPositionInfo](#deathpositioninfo)([Structure](common.md))
**class** [EventCourseGhostInfo](#eventcourseghostinfo)([Structure](common.md))
**class** [EventCourseHistogram](#eventcoursehistogram)([Structure](common.md))
**class** [EventCourseInfo](#eventcourseinfo)([Structure](common.md))
**class** [EventCourseStatusInfo](#eventcoursestatusinfo)([Structure](common.md))
**class** [EventCourseThumbnail](#eventcoursethumbnail)([Structure](common.md))
**class** [GetCoursesEventParam](#getcourseseventparam)([Structure](common.md))
**class** [GetCoursesParam](#getcoursesparam)([Structure](common.md))
**class** [GetEventCourseGhostParam](#geteventcourseghostparam)([Structure](common.md))
**class** [GetEventCourseHistogramParam](#geteventcoursehistogramparam)([Structure](common.md))
**class** [GetUserOrCourseParam](#getuserorcourseparam)([Structure](common.md))
**class** [GetUsersParam](#getusersparam)([Structure](common.md))
**class** [GetWorldMapParam](#getworldmapparam)([Structure](common.md))
**class** [RegisterUserParam](#registeruserparam)([Structure](common.md))
**class** [RelationObjectReqGetInfo](#relationobjectreqgetinfo)([Structure](common.md))
**class** [ReqGetInfoHeadersInfo](#reqgetinfoheadersinfo)([Structure](common.md))
**class** [SearchCommentsInOrderParam](#searchcommentsinorderparam)([Structure](common.md))
**class** [SearchCoursesBestTimeParam](#searchcoursesbesttimeparam)([Structure](common.md))
**class** [SearchCoursesEndlessModeParam](#searchcoursesendlessmodeparam)([Structure](common.md))
**class** [SearchCoursesEventParam](#searchcourseseventparam)([Structure](common.md))
**class** [SearchCoursesFirstClearParam](#searchcoursesfirstclearparam)([Structure](common.md))
**class** [SearchCoursesLatestParam](#searchcourseslatestparam)([Structure](common.md))
**class** [SearchCoursesPlayedByParam](#searchcoursesplayedbyparam)([Structure](common.md))
**class** [SearchCoursesPointRankingParam](#searchcoursespointrankingparam)([Structure](common.md))
**class** [SearchCoursesPositiveRatedByParam](#searchcoursespositiveratedbyparam)([Structure](common.md))
**class** [SearchCoursesPostedByParam](#searchcoursespostedbyparam)([Structure](common.md))
**class** [SearchUsersClearedCourseParam](#searchusersclearedcourseparam)([Structure](common.md))
**class** [SearchUsersPlayedCourseParam](#searchusersplayedcourseparam)([Structure](common.md))
**class** [SearchUsersPositiveRatedCourseParam](#searchuserspositiveratedcourseparam)([Structure](common.md))
**class** [SearchUsersUserPointParam](#searchusersuserpointparam)([Structure](common.md))
**class** [SearchWorldMapPickUpParam](#searchworldmappickupparam)([Structure](common.md))
**class** [SearchWorldMapPlayedByParam](#searchworldmapplayedbyparam)([Structure](common.md))
**class** [SyncUserProfileParam](#syncuserprofileparam)([Structure](common.md))
**class** [SyncUserProfileResult](#syncuserprofileresult)([Structure](common.md))
**class** [UnknownStruct1](#unknownstruct1)([Structure](common.md))
**class** [UnknownStruct3](#unknownstruct3)([Structure](common.md))
**class** [UnknownStruct6](#unknownstruct6)([Structure](common.md))
**class** [UserInfo](#userinfo)([Structure](common.md))
**class** [WorldMapInfo](#worldmapinfo)([Structure](common.md))
## DataStoreClientSMM2 **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`DataStoreClientSMM2`](#datastoreclientsmm2). **async def prepare_get_object_v1**(param: [DataStorePrepareGetParamV1](#datastorepreparegetparamv1)) -> [DataStoreReqGetInfoV1](#datastorereqgetinfov1)
Calls method `1` on the server. **async def prepare_post_object_v1**(param: [DataStorePreparePostParamV1](#datastorepreparepostparamv1)) -> [DataStoreReqPostInfoV1](#datastorereqpostinfov1)
Calls method `2` on the server. **async def complete_post_object_v1**(param: [DataStoreCompletePostParamV1](#datastorecompletepostparamv1)) -> None
Calls method `3` on the server. **async def delete_object**(param: [DataStoreDeleteParam](#datastoredeleteparam)) -> None
Calls method `4` on the server. **async def delete_objects**(param: list[[DataStoreDeleteParam](#datastoredeleteparam)], transactional: bool) -> list[[Result](common.md#result)]
Calls method `5` on the server. **async def change_meta_v1**(param: [DataStoreChangeMetaParamV1](#datastorechangemetaparamv1)) -> None
Calls method `6` on the server. **async def change_metas_v1**(data_ids: list[int], param: list[[DataStoreChangeMetaParamV1](#datastorechangemetaparamv1)], transactional: bool) -> list[[Result](common.md#result)]
Calls method `7` on the server. **async def get_meta**(param: [DataStoreGetMetaParam](#datastoregetmetaparam)) -> [DataStoreMetaInfo](#datastoremetainfo)
Calls method `8` on the server. **async def get_metas**(data_ids: list[int], param: [DataStoreGetMetaParam](#datastoregetmetaparam)) -> [RMCResponse](common.md)
Calls method `9` on the server. The RMC response has the following attributes:
info: list[[DataStoreMetaInfo](#datastoremetainfo)]
results: list[[Result](common.md#result)]
**async def prepare_update_object**(param: [DataStorePrepareUpdateParam](#datastoreprepareupdateparam)) -> [DataStoreReqUpdateInfo](#datastorerequpdateinfo)
Calls method `10` on the server. **async def complete_update_object**(param: [DataStoreCompleteUpdateParam](#datastorecompleteupdateparam)) -> None
Calls method `11` on the server. **async def search_object**(param: [DataStoreSearchParam](#datastoresearchparam)) -> [DataStoreSearchResult](#datastoresearchresult)
Calls method `12` on the server. **async def get_notification_url**(param: [DataStoreGetNotificationUrlParam](#datastoregetnotificationurlparam)) -> [DataStoreReqGetNotificationUrlInfo](#datastorereqgetnotificationurlinfo)
Calls method `13` on the server. **async def get_new_arrived_notifications_v1**(param: [DataStoreGetNewArrivedNotificationsParam](#datastoregetnewarrivednotificationsparam)) -> [RMCResponse](common.md)
Calls method `14` on the server. The RMC response has the following attributes:
result: list[[DataStoreNotificationV1](#datastorenotificationv1)]
has_next: bool
**async def rate_object**(target: [DataStoreRatingTarget](#datastoreratingtarget), param: [DataStoreRateObjectParam](#datastorerateobjectparam), fetch_ratings: bool) -> [DataStoreRatingInfo](#datastoreratinginfo)
Calls method `15` on the server. **async def get_rating**(target: [DataStoreRatingTarget](#datastoreratingtarget), access_password: int) -> [DataStoreRatingInfo](#datastoreratinginfo)
Calls method `16` on the server. **async def get_ratings**(data_ids: list[int], access_password: int) -> [RMCResponse](common.md)
Calls method `17` on the server. The RMC response has the following attributes:
ratings: list[list[[DataStoreRatingInfoWithSlot](#datastoreratinginfowithslot)]]
results: list[[Result](common.md#result)]
**async def reset_rating**(target: [DataStoreRatingTarget](#datastoreratingtarget), update_password: int) -> None
Calls method `18` on the server. **async def reset_ratings**(data_ids: list[int], transactional: bool) -> list[[Result](common.md#result)]
Calls method `19` on the server. **async def get_specific_meta_v1**(param: [DataStoreGetSpecificMetaParamV1](#datastoregetspecificmetaparamv1)) -> list[[DataStoreSpecificMetaInfoV1](#datastorespecificmetainfov1)]
Calls method `20` on the server. **async def post_meta_binary**(param: [DataStorePreparePostParam](#datastorepreparepostparam)) -> int
Calls method `21` on the server. **async def touch_object**(param: [DataStoreTouchObjectParam](#datastoretouchobjectparam)) -> None
Calls method `22` on the server. **async def get_rating_with_log**(target: [DataStoreRatingTarget](#datastoreratingtarget), access_password: int) -> [RMCResponse](common.md)
Calls method `23` on the server. The RMC response has the following attributes:
rating: [DataStoreRatingInfo](#datastoreratinginfo)
log: [DataStoreRatingLog](#datastoreratinglog)
**async def prepare_post_object**(param: [DataStorePreparePostParam](#datastorepreparepostparam)) -> [DataStoreReqPostInfo](#datastorereqpostinfo)
Calls method `24` on the server. **async def prepare_get_object**(param: [DataStorePrepareGetParam](#datastorepreparegetparam)) -> [DataStoreReqGetInfo](#datastorereqgetinfo)
Calls method `25` on the server. **async def complete_post_object**(param: [DataStoreCompletePostParam](#datastorecompletepostparam)) -> None
Calls method `26` on the server. **async def get_new_arrived_notifications**(param: [DataStoreGetNewArrivedNotificationsParam](#datastoregetnewarrivednotificationsparam)) -> [RMCResponse](common.md)
Calls method `27` on the server. The RMC response has the following attributes:
result: list[[DataStoreNotification](#datastorenotification)]
has_next: bool
**async def get_specific_meta**(param: [DataStoreGetSpecificMetaParam](#datastoregetspecificmetaparam)) -> list[[DataStoreSpecificMetaInfo](#datastorespecificmetainfo)]
Calls method `28` on the server. **async def get_persistence_info**(owner_id: int, slot_id: int) -> [DataStorePersistenceInfo](#datastorepersistenceinfo)
Calls method `29` on the server. **async def get_persistence_infos**(owner_id: int, slot_ids: list[int]) -> [RMCResponse](common.md)
Calls method `30` on the server. The RMC response has the following attributes:
infos: list[[DataStorePersistenceInfo](#datastorepersistenceinfo)]
results: list[[Result](common.md#result)]
**async def perpetuate_object**(persistence_slot_id: int, data_id: int, delete_last_object: bool) -> None
Calls method `31` on the server. **async def unperpetuate_object**(persistence_slot_id: int, delete_last_object: bool) -> None
Calls method `32` on the server. **async def prepare_get_object_or_meta_binary**(param: [DataStorePrepareGetParam](#datastorepreparegetparam)) -> [RMCResponse](common.md)
Calls method `33` on the server. The RMC response has the following attributes:
get_info: [DataStoreReqGetInfo](#datastorereqgetinfo)
additional_meta: [DataStoreReqGetAdditionalMeta](#datastorereqgetadditionalmeta)
**async def get_password_info**(data_id: int) -> [DataStorePasswordInfo](#datastorepasswordinfo)
Calls method `34` on the server. **async def get_password_infos**(data_ids: list[int]) -> [RMCResponse](common.md)
Calls method `35` on the server. The RMC response has the following attributes:
infos: list[[DataStorePasswordInfo](#datastorepasswordinfo)]
results: list[[Result](common.md#result)]
**async def get_metas_multiple_param**(params: list[[DataStoreGetMetaParam](#datastoregetmetaparam)]) -> [RMCResponse](common.md)
Calls method `36` on the server. The RMC response has the following attributes:
infos: list[[DataStoreMetaInfo](#datastoremetainfo)]
results: list[[Result](common.md#result)]
**async def complete_post_objects**(data_ids: list[int]) -> None
Calls method `37` on the server. **async def change_meta**(param: [DataStoreChangeMetaParam](#datastorechangemetaparam)) -> None
Calls method `38` on the server. **async def change_metas**(data_ids: list[int], param: list[[DataStoreChangeMetaParam](#datastorechangemetaparam)], transactional: bool) -> list[[Result](common.md#result)]
Calls method `39` on the server. **async def rate_objects**(targets: list[[DataStoreRatingTarget](#datastoreratingtarget)], param: list[[DataStoreRateObjectParam](#datastorerateobjectparam)], transactional: bool, fetch_ratings: bool) -> [RMCResponse](common.md)
Calls method `40` on the server. The RMC response has the following attributes:
infos: list[[DataStoreRatingInfo](#datastoreratinginfo)]
results: list[[Result](common.md#result)]
**async def post_meta_binary_with_data_id**(data_id: int, param: [DataStorePreparePostParam](#datastorepreparepostparam)) -> None
Calls method `41` on the server. **async def post_meta_binaries_with_data_id**(data_ids: list[int], param: list[[DataStorePreparePostParam](#datastorepreparepostparam)], transactional: bool) -> list[[Result](common.md#result)]
Calls method `42` on the server. **async def rate_object_with_posting**(target: [DataStoreRatingTarget](#datastoreratingtarget), rate_param: [DataStoreRateObjectParam](#datastorerateobjectparam), post_param: [DataStorePreparePostParam](#datastorepreparepostparam), fetch_ratings: bool) -> [DataStoreRatingInfo](#datastoreratinginfo)
Calls method `43` on the server. **async def rate_objects_with_posting**(targets: list[[DataStoreRatingTarget](#datastoreratingtarget)], rate_param: list[[DataStoreRateObjectParam](#datastorerateobjectparam)], post_param: list[[DataStorePreparePostParam](#datastorepreparepostparam)], transactional: bool, fetch_ratings: bool) -> [RMCResponse](common.md)
Calls method `44` on the server. The RMC response has the following attributes:
ratings: list[[DataStoreRatingInfo](#datastoreratinginfo)]
results: list[[Result](common.md#result)]
**async def get_object_infos**(data_ids: list[int]) -> [RMCResponse](common.md)
Calls method `45` on the server. The RMC response has the following attributes:
infos: list[[DataStoreReqGetInfo](#datastorereqgetinfo)]
results: list[[Result](common.md#result)]
**async def search_object_light**(param: [DataStoreSearchParam](#datastoresearchparam)) -> [DataStoreSearchResult](#datastoresearchresult)
Calls method `46` on the server. **async def register_user**(param: [RegisterUserParam](#registeruserparam)) -> None
Calls method `47` on the server. **async def get_users**(param: [GetUsersParam](#getusersparam)) -> [RMCResponse](common.md)
Calls method `48` on the server. The RMC response has the following attributes:
users: list[[UserInfo](#userinfo)]
results: list[[Result](common.md#result)]
**async def sync_user_profile**(param: [SyncUserProfileParam](#syncuserprofileparam)) -> [SyncUserProfileResult](#syncuserprofileresult)
Calls method `49` on the server. **async def search_users_user_point**(param: [SearchUsersUserPointParam](#searchusersuserpointparam)) -> [RMCResponse](common.md)
Calls method `50` on the server. The RMC response has the following attributes:
users: list[[UserInfo](#userinfo)]
ranks: list[int]
result: bool
**async def search_users_played_course**(param: [SearchUsersPlayedCourseParam](#searchusersplayedcourseparam)) -> list[[UserInfo](#userinfo)]
Calls method `53` on the server. **async def search_users_cleared_course**(param: [SearchUsersClearedCourseParam](#searchusersclearedcourseparam)) -> list[[UserInfo](#userinfo)]
Calls method `54` on the server. **async def search_users_positive_rated_course**(param: [SearchUsersPositiveRatedCourseParam](#searchuserspositiveratedcourseparam)) -> list[[UserInfo](#userinfo)]
Calls method `55` on the server. **async def update_last_login_time**() -> None
Calls method `59` on the server. **async def get_username_ng_type**() -> int
Calls method `65` on the server. **async def get_courses**(param: [GetCoursesParam](#getcoursesparam)) -> [RMCResponse](common.md)
Calls method `70` on the server. The RMC response has the following attributes:
courses: list[[CourseInfo](#courseinfo)]
results: list[[Result](common.md#result)]
**async def search_courses_point_ranking**(param: [SearchCoursesPointRankingParam](#searchcoursespointrankingparam)) -> [RMCResponse](common.md)
Calls method `71` on the server. The RMC response has the following attributes:
courses: list[[CourseInfo](#courseinfo)]
ranks: list[int]
result: bool
**async def search_courses_latest**(param: [SearchCoursesLatestParam](#searchcourseslatestparam)) -> [RMCResponse](common.md)
Calls method `73` on the server. The RMC response has the following attributes:
courses: list[[CourseInfo](#courseinfo)]
result: bool
**async def search_courses_posted_by**(param: [SearchCoursesPostedByParam](#searchcoursespostedbyparam)) -> [RMCResponse](common.md)
Calls method `74` on the server. The RMC response has the following attributes:
courses: list[[CourseInfo](#courseinfo)]
result: bool
**async def search_courses_positive_rated_by**(param: [SearchCoursesPositiveRatedByParam](#searchcoursespositiveratedbyparam)) -> list[[CourseInfo](#courseinfo)]
Calls method `75` on the server. **async def search_courses_played_by**(param: [SearchCoursesPlayedByParam](#searchcoursesplayedbyparam)) -> list[[CourseInfo](#courseinfo)]
Calls method `76` on the server. **async def search_courses_endless_mode**(param: [SearchCoursesEndlessModeParam](#searchcoursesendlessmodeparam)) -> list[[CourseInfo](#courseinfo)]
Calls method `79` on the server. **async def search_courses_first_clear**(param: [SearchCoursesFirstClearParam](#searchcoursesfirstclearparam)) -> [RMCResponse](common.md)
Calls method `80` on the server. The RMC response has the following attributes:
courses: list[[CourseInfo](#courseinfo)]
result: bool
**async def search_courses_best_time**(param: [SearchCoursesBestTimeParam](#searchcoursesbesttimeparam)) -> [RMCResponse](common.md)
Calls method `81` on the server. The RMC response has the following attributes:
courses: list[[CourseInfo](#courseinfo)]
result: bool
**async def get_courses_event**(param: [GetCoursesParam](#getcoursesparam), dummy: [GetCoursesEventParam](#getcourseseventparam)) -> [RMCResponse](common.md)
Calls method `85` on the server. The RMC response has the following attributes:
courses: list[[EventCourseInfo](#eventcourseinfo)]
results: list[[Result](common.md#result)]
**async def search_courses_event**(param: [SearchCoursesEventParam](#searchcourseseventparam)) -> list[[EventCourseInfo](#eventcourseinfo)]
Calls method `86` on the server. **async def search_comments_in_order**(param: [SearchCommentsInOrderParam](#searchcommentsinorderparam)) -> [RMCResponse](common.md)
Calls method `94` on the server. The RMC response has the following attributes:
comments: list[[CommentInfo](#commentinfo)]
result: bool
**async def search_comments**(data_id: int) -> list[[CommentInfo](#commentinfo)]
Calls method `95` on the server. **async def get_death_positions**(data_id: int) -> list[[DeathPositionInfo](#deathpositioninfo)]
Calls method `103` on the server. **async def get_user_or_course**(param: [GetUserOrCourseParam](#getuserorcourseparam)) -> [RMCResponse](common.md)
Calls method `131` on the server. The RMC response has the following attributes:
user: [UserInfo](#userinfo)
course: [CourseInfo](#courseinfo)
**async def get_req_get_info_headers_info**(type: int) -> [ReqGetInfoHeadersInfo](#reqgetinfoheadersinfo)
Calls method `134` on the server. **async def get_event_course_stamp**() -> int
Calls method `153` on the server. **async def get_event_course_status**() -> [EventCourseStatusInfo](#eventcoursestatusinfo)
Calls method `154` on the server. **async def get_event_course_histogram**(param: [GetEventCourseHistogramParam](#geteventcoursehistogramparam)) -> [EventCourseHistogram](#eventcoursehistogram)
Calls method `156` on the server. **async def get_event_course_ghost**(param: [GetEventCourseGhostParam](#geteventcourseghostparam)) -> list[[EventCourseGhostInfo](#eventcourseghostinfo)]
Calls method `157` on the server. **async def get_world_map**(param: [GetWorldMapParam](#getworldmapparam)) -> [RMCResponse](common.md)
Calls method `160` on the server. The RMC response has the following attributes:
maps: list[[WorldMapInfo](#worldmapinfo)]
results: list[[Result](common.md#result)]
**async def search_world_map_pick_up**(param: [SearchWorldMapPickUpParam](#searchworldmappickupparam)) -> list[[WorldMapInfo](#worldmapinfo)]
Calls method `162` on the server. ## DataStoreServerSMM2 **def _\_init__**()
Creates a new [`DataStoreServerSMM2`](#datastoreserversmm2). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def prepare_get_object_v1**(client: [RMCClient](rmc.md#rmcclient), param: [DataStorePrepareGetParamV1](#datastorepreparegetparamv1)) -> [DataStoreReqGetInfoV1](#datastorereqgetinfov1)
Handler for method `1`. This method should be overridden by a subclass. **async def prepare_post_object_v1**(client: [RMCClient](rmc.md#rmcclient), param: [DataStorePreparePostParamV1](#datastorepreparepostparamv1)) -> [DataStoreReqPostInfoV1](#datastorereqpostinfov1)
Handler for method `2`. This method should be overridden by a subclass. **async def complete_post_object_v1**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreCompletePostParamV1](#datastorecompletepostparamv1)) -> None
Handler for method `3`. This method should be overridden by a subclass. **async def delete_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreDeleteParam](#datastoredeleteparam)) -> None
Handler for method `4`. This method should be overridden by a subclass. **async def delete_objects**(client: [RMCClient](rmc.md#rmcclient), param: list[[DataStoreDeleteParam](#datastoredeleteparam)], transactional: bool) -> list[[Result](common.md#result)]
Handler for method `5`. This method should be overridden by a subclass. **async def change_meta_v1**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreChangeMetaParamV1](#datastorechangemetaparamv1)) -> None
Handler for method `6`. This method should be overridden by a subclass. **async def change_metas_v1**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int], param: list[[DataStoreChangeMetaParamV1](#datastorechangemetaparamv1)], transactional: bool) -> list[[Result](common.md#result)]
Handler for method `7`. This method should be overridden by a subclass. **async def get_meta**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreGetMetaParam](#datastoregetmetaparam)) -> [DataStoreMetaInfo](#datastoremetainfo)
Handler for method `8`. This method should be overridden by a subclass. **async def get_metas**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int], param: [DataStoreGetMetaParam](#datastoregetmetaparam)) -> [RMCResponse](common.md)
Handler for method `9`. This method should be overridden by a subclass. The RMC response must have the following attributes:
info: list[[DataStoreMetaInfo](#datastoremetainfo)]
results: list[[Result](common.md#result)]
**async def prepare_update_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStorePrepareUpdateParam](#datastoreprepareupdateparam)) -> [DataStoreReqUpdateInfo](#datastorerequpdateinfo)
Handler for method `10`. This method should be overridden by a subclass. **async def complete_update_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreCompleteUpdateParam](#datastorecompleteupdateparam)) -> None
Handler for method `11`. This method should be overridden by a subclass. **async def search_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreSearchParam](#datastoresearchparam)) -> [DataStoreSearchResult](#datastoresearchresult)
Handler for method `12`. This method should be overridden by a subclass. **async def get_notification_url**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreGetNotificationUrlParam](#datastoregetnotificationurlparam)) -> [DataStoreReqGetNotificationUrlInfo](#datastorereqgetnotificationurlinfo)
Handler for method `13`. This method should be overridden by a subclass. **async def get_new_arrived_notifications_v1**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreGetNewArrivedNotificationsParam](#datastoregetnewarrivednotificationsparam)) -> [RMCResponse](common.md)
Handler for method `14`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: list[[DataStoreNotificationV1](#datastorenotificationv1)]
has_next: bool
**async def rate_object**(client: [RMCClient](rmc.md#rmcclient), target: [DataStoreRatingTarget](#datastoreratingtarget), param: [DataStoreRateObjectParam](#datastorerateobjectparam), fetch_ratings: bool) -> [DataStoreRatingInfo](#datastoreratinginfo)
Handler for method `15`. This method should be overridden by a subclass. **async def get_rating**(client: [RMCClient](rmc.md#rmcclient), target: [DataStoreRatingTarget](#datastoreratingtarget), access_password: int) -> [DataStoreRatingInfo](#datastoreratinginfo)
Handler for method `16`. This method should be overridden by a subclass. **async def get_ratings**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int], access_password: int) -> [RMCResponse](common.md)
Handler for method `17`. This method should be overridden by a subclass. The RMC response must have the following attributes:
ratings: list[list[[DataStoreRatingInfoWithSlot](#datastoreratinginfowithslot)]]
results: list[[Result](common.md#result)]
**async def reset_rating**(client: [RMCClient](rmc.md#rmcclient), target: [DataStoreRatingTarget](#datastoreratingtarget), update_password: int) -> None
Handler for method `18`. This method should be overridden by a subclass. **async def reset_ratings**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int], transactional: bool) -> list[[Result](common.md#result)]
Handler for method `19`. This method should be overridden by a subclass. **async def get_specific_meta_v1**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreGetSpecificMetaParamV1](#datastoregetspecificmetaparamv1)) -> list[[DataStoreSpecificMetaInfoV1](#datastorespecificmetainfov1)]
Handler for method `20`. This method should be overridden by a subclass. **async def post_meta_binary**(client: [RMCClient](rmc.md#rmcclient), param: [DataStorePreparePostParam](#datastorepreparepostparam)) -> int
Handler for method `21`. This method should be overridden by a subclass. **async def touch_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreTouchObjectParam](#datastoretouchobjectparam)) -> None
Handler for method `22`. This method should be overridden by a subclass. **async def get_rating_with_log**(client: [RMCClient](rmc.md#rmcclient), target: [DataStoreRatingTarget](#datastoreratingtarget), access_password: int) -> [RMCResponse](common.md)
Handler for method `23`. This method should be overridden by a subclass. The RMC response must have the following attributes:
rating: [DataStoreRatingInfo](#datastoreratinginfo)
log: [DataStoreRatingLog](#datastoreratinglog)
**async def prepare_post_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStorePreparePostParam](#datastorepreparepostparam)) -> [DataStoreReqPostInfo](#datastorereqpostinfo)
Handler for method `24`. This method should be overridden by a subclass. **async def prepare_get_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStorePrepareGetParam](#datastorepreparegetparam)) -> [DataStoreReqGetInfo](#datastorereqgetinfo)
Handler for method `25`. This method should be overridden by a subclass. **async def complete_post_object**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreCompletePostParam](#datastorecompletepostparam)) -> None
Handler for method `26`. This method should be overridden by a subclass. **async def get_new_arrived_notifications**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreGetNewArrivedNotificationsParam](#datastoregetnewarrivednotificationsparam)) -> [RMCResponse](common.md)
Handler for method `27`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: list[[DataStoreNotification](#datastorenotification)]
has_next: bool
**async def get_specific_meta**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreGetSpecificMetaParam](#datastoregetspecificmetaparam)) -> list[[DataStoreSpecificMetaInfo](#datastorespecificmetainfo)]
Handler for method `28`. This method should be overridden by a subclass. **async def get_persistence_info**(client: [RMCClient](rmc.md#rmcclient), owner_id: int, slot_id: int) -> [DataStorePersistenceInfo](#datastorepersistenceinfo)
Handler for method `29`. This method should be overridden by a subclass. **async def get_persistence_infos**(client: [RMCClient](rmc.md#rmcclient), owner_id: int, slot_ids: list[int]) -> [RMCResponse](common.md)
Handler for method `30`. This method should be overridden by a subclass. The RMC response must have the following attributes:
infos: list[[DataStorePersistenceInfo](#datastorepersistenceinfo)]
results: list[[Result](common.md#result)]
**async def perpetuate_object**(client: [RMCClient](rmc.md#rmcclient), persistence_slot_id: int, data_id: int, delete_last_object: bool) -> None
Handler for method `31`. This method should be overridden by a subclass. **async def unperpetuate_object**(client: [RMCClient](rmc.md#rmcclient), persistence_slot_id: int, delete_last_object: bool) -> None
Handler for method `32`. This method should be overridden by a subclass. **async def prepare_get_object_or_meta_binary**(client: [RMCClient](rmc.md#rmcclient), param: [DataStorePrepareGetParam](#datastorepreparegetparam)) -> [RMCResponse](common.md)
Handler for method `33`. This method should be overridden by a subclass. The RMC response must have the following attributes:
get_info: [DataStoreReqGetInfo](#datastorereqgetinfo)
additional_meta: [DataStoreReqGetAdditionalMeta](#datastorereqgetadditionalmeta)
**async def get_password_info**(client: [RMCClient](rmc.md#rmcclient), data_id: int) -> [DataStorePasswordInfo](#datastorepasswordinfo)
Handler for method `34`. This method should be overridden by a subclass. **async def get_password_infos**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int]) -> [RMCResponse](common.md)
Handler for method `35`. This method should be overridden by a subclass. The RMC response must have the following attributes:
infos: list[[DataStorePasswordInfo](#datastorepasswordinfo)]
results: list[[Result](common.md#result)]
**async def get_metas_multiple_param**(client: [RMCClient](rmc.md#rmcclient), params: list[[DataStoreGetMetaParam](#datastoregetmetaparam)]) -> [RMCResponse](common.md)
Handler for method `36`. This method should be overridden by a subclass. The RMC response must have the following attributes:
infos: list[[DataStoreMetaInfo](#datastoremetainfo)]
results: list[[Result](common.md#result)]
**async def complete_post_objects**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int]) -> None
Handler for method `37`. This method should be overridden by a subclass. **async def change_meta**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreChangeMetaParam](#datastorechangemetaparam)) -> None
Handler for method `38`. This method should be overridden by a subclass. **async def change_metas**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int], param: list[[DataStoreChangeMetaParam](#datastorechangemetaparam)], transactional: bool) -> list[[Result](common.md#result)]
Handler for method `39`. This method should be overridden by a subclass. **async def rate_objects**(client: [RMCClient](rmc.md#rmcclient), targets: list[[DataStoreRatingTarget](#datastoreratingtarget)], param: list[[DataStoreRateObjectParam](#datastorerateobjectparam)], transactional: bool, fetch_ratings: bool) -> [RMCResponse](common.md)
Handler for method `40`. This method should be overridden by a subclass. The RMC response must have the following attributes:
infos: list[[DataStoreRatingInfo](#datastoreratinginfo)]
results: list[[Result](common.md#result)]
**async def post_meta_binary_with_data_id**(client: [RMCClient](rmc.md#rmcclient), data_id: int, param: [DataStorePreparePostParam](#datastorepreparepostparam)) -> None
Handler for method `41`. This method should be overridden by a subclass. **async def post_meta_binaries_with_data_id**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int], param: list[[DataStorePreparePostParam](#datastorepreparepostparam)], transactional: bool) -> list[[Result](common.md#result)]
Handler for method `42`. This method should be overridden by a subclass. **async def rate_object_with_posting**(client: [RMCClient](rmc.md#rmcclient), target: [DataStoreRatingTarget](#datastoreratingtarget), rate_param: [DataStoreRateObjectParam](#datastorerateobjectparam), post_param: [DataStorePreparePostParam](#datastorepreparepostparam), fetch_ratings: bool) -> [DataStoreRatingInfo](#datastoreratinginfo)
Handler for method `43`. This method should be overridden by a subclass. **async def rate_objects_with_posting**(client: [RMCClient](rmc.md#rmcclient), targets: list[[DataStoreRatingTarget](#datastoreratingtarget)], rate_param: list[[DataStoreRateObjectParam](#datastorerateobjectparam)], post_param: list[[DataStorePreparePostParam](#datastorepreparepostparam)], transactional: bool, fetch_ratings: bool) -> [RMCResponse](common.md)
Handler for method `44`. This method should be overridden by a subclass. The RMC response must have the following attributes:
ratings: list[[DataStoreRatingInfo](#datastoreratinginfo)]
results: list[[Result](common.md#result)]
**async def get_object_infos**(client: [RMCClient](rmc.md#rmcclient), data_ids: list[int]) -> [RMCResponse](common.md)
Handler for method `45`. This method should be overridden by a subclass. The RMC response must have the following attributes:
infos: list[[DataStoreReqGetInfo](#datastorereqgetinfo)]
results: list[[Result](common.md#result)]
**async def search_object_light**(client: [RMCClient](rmc.md#rmcclient), param: [DataStoreSearchParam](#datastoresearchparam)) -> [DataStoreSearchResult](#datastoresearchresult)
Handler for method `46`. This method should be overridden by a subclass. **async def register_user**(client: [RMCClient](rmc.md#rmcclient), param: [RegisterUserParam](#registeruserparam)) -> None
Handler for method `47`. This method should be overridden by a subclass. **async def get_users**(client: [RMCClient](rmc.md#rmcclient), param: [GetUsersParam](#getusersparam)) -> [RMCResponse](common.md)
Handler for method `48`. This method should be overridden by a subclass. The RMC response must have the following attributes:
users: list[[UserInfo](#userinfo)]
results: list[[Result](common.md#result)]
**async def sync_user_profile**(client: [RMCClient](rmc.md#rmcclient), param: [SyncUserProfileParam](#syncuserprofileparam)) -> [SyncUserProfileResult](#syncuserprofileresult)
Handler for method `49`. This method should be overridden by a subclass. **async def search_users_user_point**(client: [RMCClient](rmc.md#rmcclient), param: [SearchUsersUserPointParam](#searchusersuserpointparam)) -> [RMCResponse](common.md)
Handler for method `50`. This method should be overridden by a subclass. The RMC response must have the following attributes:
users: list[[UserInfo](#userinfo)]
ranks: list[int]
result: bool
**async def search_users_played_course**(client: [RMCClient](rmc.md#rmcclient), param: [SearchUsersPlayedCourseParam](#searchusersplayedcourseparam)) -> list[[UserInfo](#userinfo)]
Handler for method `53`. This method should be overridden by a subclass. **async def search_users_cleared_course**(client: [RMCClient](rmc.md#rmcclient), param: [SearchUsersClearedCourseParam](#searchusersclearedcourseparam)) -> list[[UserInfo](#userinfo)]
Handler for method `54`. This method should be overridden by a subclass. **async def search_users_positive_rated_course**(client: [RMCClient](rmc.md#rmcclient), param: [SearchUsersPositiveRatedCourseParam](#searchuserspositiveratedcourseparam)) -> list[[UserInfo](#userinfo)]
Handler for method `55`. This method should be overridden by a subclass. **async def update_last_login_time**(client: [RMCClient](rmc.md#rmcclient)) -> None
Handler for method `59`. This method should be overridden by a subclass. **async def get_username_ng_type**(client: [RMCClient](rmc.md#rmcclient)) -> int
Handler for method `65`. This method should be overridden by a subclass. **async def get_courses**(client: [RMCClient](rmc.md#rmcclient), param: [GetCoursesParam](#getcoursesparam)) -> [RMCResponse](common.md)
Handler for method `70`. This method should be overridden by a subclass. The RMC response must have the following attributes:
courses: list[[CourseInfo](#courseinfo)]
results: list[[Result](common.md#result)]
**async def search_courses_point_ranking**(client: [RMCClient](rmc.md#rmcclient), param: [SearchCoursesPointRankingParam](#searchcoursespointrankingparam)) -> [RMCResponse](common.md)
Handler for method `71`. This method should be overridden by a subclass. The RMC response must have the following attributes:
courses: list[[CourseInfo](#courseinfo)]
ranks: list[int]
result: bool
**async def search_courses_latest**(client: [RMCClient](rmc.md#rmcclient), param: [SearchCoursesLatestParam](#searchcourseslatestparam)) -> [RMCResponse](common.md)
Handler for method `73`. This method should be overridden by a subclass. The RMC response must have the following attributes:
courses: list[[CourseInfo](#courseinfo)]
result: bool
**async def search_courses_posted_by**(client: [RMCClient](rmc.md#rmcclient), param: [SearchCoursesPostedByParam](#searchcoursespostedbyparam)) -> [RMCResponse](common.md)
Handler for method `74`. This method should be overridden by a subclass. The RMC response must have the following attributes:
courses: list[[CourseInfo](#courseinfo)]
result: bool
**async def search_courses_positive_rated_by**(client: [RMCClient](rmc.md#rmcclient), param: [SearchCoursesPositiveRatedByParam](#searchcoursespositiveratedbyparam)) -> list[[CourseInfo](#courseinfo)]
Handler for method `75`. This method should be overridden by a subclass. **async def search_courses_played_by**(client: [RMCClient](rmc.md#rmcclient), param: [SearchCoursesPlayedByParam](#searchcoursesplayedbyparam)) -> list[[CourseInfo](#courseinfo)]
Handler for method `76`. This method should be overridden by a subclass. **async def search_courses_endless_mode**(client: [RMCClient](rmc.md#rmcclient), param: [SearchCoursesEndlessModeParam](#searchcoursesendlessmodeparam)) -> list[[CourseInfo](#courseinfo)]
Handler for method `79`. This method should be overridden by a subclass. **async def search_courses_first_clear**(client: [RMCClient](rmc.md#rmcclient), param: [SearchCoursesFirstClearParam](#searchcoursesfirstclearparam)) -> [RMCResponse](common.md)
Handler for method `80`. This method should be overridden by a subclass. The RMC response must have the following attributes:
courses: list[[CourseInfo](#courseinfo)]
result: bool
**async def search_courses_best_time**(client: [RMCClient](rmc.md#rmcclient), param: [SearchCoursesBestTimeParam](#searchcoursesbesttimeparam)) -> [RMCResponse](common.md)
Handler for method `81`. This method should be overridden by a subclass. The RMC response must have the following attributes:
courses: list[[CourseInfo](#courseinfo)]
result: bool
**async def get_courses_event**(client: [RMCClient](rmc.md#rmcclient), param: [GetCoursesParam](#getcoursesparam), dummy: [GetCoursesEventParam](#getcourseseventparam)) -> [RMCResponse](common.md)
Handler for method `85`. This method should be overridden by a subclass. The RMC response must have the following attributes:
courses: list[[EventCourseInfo](#eventcourseinfo)]
results: list[[Result](common.md#result)]
**async def search_courses_event**(client: [RMCClient](rmc.md#rmcclient), param: [SearchCoursesEventParam](#searchcourseseventparam)) -> list[[EventCourseInfo](#eventcourseinfo)]
Handler for method `86`. This method should be overridden by a subclass. **async def search_comments_in_order**(client: [RMCClient](rmc.md#rmcclient), param: [SearchCommentsInOrderParam](#searchcommentsinorderparam)) -> [RMCResponse](common.md)
Handler for method `94`. This method should be overridden by a subclass. The RMC response must have the following attributes:
comments: list[[CommentInfo](#commentinfo)]
result: bool
**async def search_comments**(client: [RMCClient](rmc.md#rmcclient), data_id: int) -> list[[CommentInfo](#commentinfo)]
Handler for method `95`. This method should be overridden by a subclass. **async def get_death_positions**(client: [RMCClient](rmc.md#rmcclient), data_id: int) -> list[[DeathPositionInfo](#deathpositioninfo)]
Handler for method `103`. This method should be overridden by a subclass. **async def get_user_or_course**(client: [RMCClient](rmc.md#rmcclient), param: [GetUserOrCourseParam](#getuserorcourseparam)) -> [RMCResponse](common.md)
Handler for method `131`. This method should be overridden by a subclass. The RMC response must have the following attributes:
user: [UserInfo](#userinfo)
course: [CourseInfo](#courseinfo)
**async def get_req_get_info_headers_info**(client: [RMCClient](rmc.md#rmcclient), type: int) -> [ReqGetInfoHeadersInfo](#reqgetinfoheadersinfo)
Handler for method `134`. This method should be overridden by a subclass. **async def get_event_course_stamp**(client: [RMCClient](rmc.md#rmcclient)) -> int
Handler for method `153`. This method should be overridden by a subclass. **async def get_event_course_status**(client: [RMCClient](rmc.md#rmcclient)) -> [EventCourseStatusInfo](#eventcoursestatusinfo)
Handler for method `154`. This method should be overridden by a subclass. **async def get_event_course_histogram**(client: [RMCClient](rmc.md#rmcclient), param: [GetEventCourseHistogramParam](#geteventcoursehistogramparam)) -> [EventCourseHistogram](#eventcoursehistogram)
Handler for method `156`. This method should be overridden by a subclass. **async def get_event_course_ghost**(client: [RMCClient](rmc.md#rmcclient), param: [GetEventCourseGhostParam](#geteventcourseghostparam)) -> list[[EventCourseGhostInfo](#eventcourseghostinfo)]
Handler for method `157`. This method should be overridden by a subclass. **async def get_world_map**(client: [RMCClient](rmc.md#rmcclient), param: [GetWorldMapParam](#getworldmapparam)) -> [RMCResponse](common.md)
Handler for method `160`. This method should be overridden by a subclass. The RMC response must have the following attributes:
maps: list[[WorldMapInfo](#worldmapinfo)]
results: list[[Result](common.md#result)]
**async def search_world_map_pick_up**(client: [RMCClient](rmc.md#rmcclient), param: [SearchWorldMapPickUpParam](#searchworldmappickupparam)) -> list[[WorldMapInfo](#worldmapinfo)]
Handler for method `162`. This method should be overridden by a subclass. ## ClearCondition This class defines the following constants:
`NORMAL = 0`
`COLLECT_COINS = 4116396131`
`KILL_SKIPSQUEAKS = 4042480826`
## CourseDifficulty This class defines the following constants:
`EASY = 0`
`STANDARD = 1`
`EXPERT = 2`
`SUPER_EXPERT = 3`
## CourseOption This class defines the following constants:
`PLAY_STATS = 1`
`RATINGS = 2`
`TIME_STATS = 4`
`COMMENT_STATS = 8`
`UNK9 = 16`
`UNK10 = 32`
`UNK8 = 64`
`ONE_SCREEN_THUMBNAIL = 128`
`ENTIRE_THUMBNAIL = 256`
`ALL = 511`
## CourseTag This class defines the following constants:
`NONE = 0`
`STANDARD = 1`
`PUZZLE_SOLVING = 2`
`SPEEDRUN = 3`
`AUTOSCROLL = 4`
`AUTO_MARIO = 5`
`SHORT_AND_SWEET = 6`
`MULTIPLAYER_VS = 7`
`THEMED = 8`
`MUSIC = 9`
## CourseTheme This class defines the following constants:
`GROUND = 0`
`UNDERGROUND = 1`
`CASTLE = 2`
`AIRSHIP = 3`
`UNDERWATER = 4`
`GHOST_HOUSE = 5`
`SNOW = 6`
`DESERT = 7`
`SKY = 8`
`FOREST = 9`
## EventCourseOption This class defines the following constants:
`UNK3 = 1`
`GET_INFO = 2`
`BEST_TIME = 8`
`ONE_SCREEN_THUMBNAIL = 16`
`ENTIRE_THUMBNAIL = 32`
`UNK1 = 64`
`MEDAL_TIME = 256`
`GHOST = 512`
`ALL = 1023`
## GameStyle This class defines the following constants:
`SMB1 = 0`
`SMB3 = 1`
`SMW = 2`
`NSMBU = 3`
`SM3DW = 4`
## MultiplayerStatsKeys This class defines the following constants:
`MULTIPLAYER_SCORE = 0`
`VERSUS_PLAYS = 2`
`VERSUS_WINS = 3`
`COOP_PLAYS = 10`
`COOP_WINS = 11`
## PlayStatsKeys This class defines the following constants:
`PLAYS = 0`
`CLEARS = 1`
`ATTEMPTS = 2`
`DEATHS = 3`
## UserOption This class defines the following constants:
`PLAY_STATS = 1`
`MAKER_STATS = 2`
`UNK2 = 4`
`ENDLESS_MODE = 8`
`MULTIPLAYER_STATS = 16`
`BADGE_INFO = 32`
`UNK8 = 64`
`UNK9 = 128`
`UNK1 = 512`
`UNK7 = 1024`
`UNK11 = 4096`
`UNK13 = 8192`
`UNK15 = 32768`
`ALL = 65535`
## BadgeInfo **def _\_init__**()
Creates a new `BadgeInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
unk1: int
unk2: int

## CommentInfo **def _\_init__**()
Creates a new `CommentInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
unk1: int
unk2: str
unk3: int
unk4: int
unk5: int
unk6: int
unk7: int
unk8: int
unk9: int
unk10: int
unk11: bool
unk12: bool
unk13: [DateTime](common.md#datetime)
unk14: bytes
unk15: str
picture: [CommentPictureReqGetInfoWithoutHeaders](#commentpicturereqgetinfowithoutheaders) = [CommentPictureReqGetInfoWithoutHeaders](#commentpicturereqgetinfowithoutheaders)()
unk16: int
unk17: int

## CommentPictureReqGetInfoWithoutHeaders **def _\_init__**()
Creates a new `CommentPictureReqGetInfoWithoutHeaders` instance. Required fields must be filled in manually. The following fields are defined in this class:
url: str
data_type: int
unk1: int
unk2: bytes
filename: str

## CourseInfo **def _\_init__**()
Creates a new `CourseInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
code: str
owner_id: int
name: str
description: str
game_style: int
course_theme: int
upload_time: [DateTime](common.md#datetime)
difficulty: int
tag1: int
tag2: int
unk1: int
clear_condition: int
clear_condition_magnitude: int
unk2: int
unk3: bytes
play_stats: dict[int, int]
ratings: dict[int, int]
unk4: dict[int, int]
time_stats: [CourseTimeStats](#coursetimestats) = [CourseTimeStats](#coursetimestats)()
comment_stats: dict[int, int]
unk9: int
unk10: int
unk11: int
unk12: int
one_screen_thumbnail: [RelationObjectReqGetInfo](#relationobjectreqgetinfo) = [RelationObjectReqGetInfo](#relationobjectreqgetinfo)()
entire_thumbnail: [RelationObjectReqGetInfo](#relationobjectreqgetinfo) = [RelationObjectReqGetInfo](#relationobjectreqgetinfo)()

## CourseTimeStats **def _\_init__**()
Creates a new `CourseTimeStats` instance. Required fields must be filled in manually. The following fields are defined in this class:
first_completion: int
world_record_holder: int
world_record: int
upload_time: int

## DataStoreChangeMetaCompareParam **def _\_init__**()
Creates a new `DataStoreChangeMetaCompareParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
comparison_flag: int
name: str
permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
delete_permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
period: int
meta_binary: bytes
tags: list[str]
referred_count: int
data_type: int
status: int

## DataStoreChangeMetaParam **def _\_init__**()
Creates a new `DataStoreChangeMetaParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
modifies_flag: int
name: str
permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
delete_permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
period: int
meta_binary: bytes
tags: list[str]
update_password: int
referred_count: int
data_type: int
status: int
compare_param: [DataStoreChangeMetaCompareParam](#datastorechangemetacompareparam) = [DataStoreChangeMetaCompareParam](#datastorechangemetacompareparam)()
persistence_target: [DataStorePersistenceTarget](#datastorepersistencetarget) = [DataStorePersistenceTarget](#datastorepersistencetarget)()

## DataStoreChangeMetaParamV1 **def _\_init__**()
Creates a new `DataStoreChangeMetaParamV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
modifies_flag: int
name: str
permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
delete_permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
period: int
meta_binary: bytes
tags: list[str]
update_password: int

## DataStoreCompletePostParam **def _\_init__**()
Creates a new `DataStoreCompletePostParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
success: bool

## DataStoreCompletePostParamV1 **def _\_init__**()
Creates a new `DataStoreCompletePostParamV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
success: bool

## DataStoreCompleteUpdateParam **def _\_init__**()
Creates a new `DataStoreCompleteUpdateParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
version: int
success: bool

## DataStoreDeleteParam **def _\_init__**()
Creates a new `DataStoreDeleteParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
update_password: int

## DataStoreGetMetaParam **def _\_init__**()
Creates a new `DataStoreGetMetaParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int = 0
persistence_target: [DataStorePersistenceTarget](#datastorepersistencetarget) = [DataStorePersistenceTarget](#datastorepersistencetarget)()
result_option: int = 0
access_password: int = 0

## DataStoreGetNewArrivedNotificationsParam **def _\_init__**()
Creates a new `DataStoreGetNewArrivedNotificationsParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
last_notification_id: int
limit: int

## DataStoreGetNotificationUrlParam **def _\_init__**()
Creates a new `DataStoreGetNotificationUrlParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
previous_url: str

## DataStoreGetSpecificMetaParam **def _\_init__**()
Creates a new `DataStoreGetSpecificMetaParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_ids: list[int]

## DataStoreGetSpecificMetaParamV1 **def _\_init__**()
Creates a new `DataStoreGetSpecificMetaParamV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_ids: list[int]

## DataStoreKeyValue **def _\_init__**()
Creates a new `DataStoreKeyValue` instance. Required fields must be filled in manually. The following fields are defined in this class:
key: str
value: str

## DataStoreMetaInfo **def _\_init__**()
Creates a new `DataStoreMetaInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
owner_id: int
size: int
name: str
data_type: int
meta_binary: bytes
permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
delete_permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
create_time: [DateTime](common.md#datetime)
update_time: [DateTime](common.md#datetime)
period: int
status: int
referred_count: int
refer_data_id: int
flag: int
referred_time: [DateTime](common.md#datetime)
expire_time: [DateTime](common.md#datetime)
tags: list[str]
ratings: list[[DataStoreRatingInfoWithSlot](#datastoreratinginfowithslot)]

## DataStoreNotification **def _\_init__**()
Creates a new `DataStoreNotification` instance. Required fields must be filled in manually. The following fields are defined in this class:
notification_id: int
data_id: int

## DataStoreNotificationV1 **def _\_init__**()
Creates a new `DataStoreNotificationV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
notification_id: int
data_id: int

## DataStorePasswordInfo **def _\_init__**()
Creates a new `DataStorePasswordInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
access_password: int
update_password: int

## DataStorePermission **def _\_init__**()
Creates a new `DataStorePermission` instance. Required fields must be filled in manually. The following fields are defined in this class:
permission: int = 3
recipients: list[int] = []

## DataStorePersistenceInfo **def _\_init__**()
Creates a new `DataStorePersistenceInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
owner_id: int
slot_id: int
data_id: int

## DataStorePersistenceInitParam **def _\_init__**()
Creates a new `DataStorePersistenceInitParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
persistence_id: int = 65535
delete_last_object: bool = True

## DataStorePersistenceTarget **def _\_init__**()
Creates a new `DataStorePersistenceTarget` instance. Required fields must be filled in manually. The following fields are defined in this class:
owner_id: int = 0
persistence_id: int = 65535

## DataStorePrepareGetParam **def _\_init__**()
Creates a new `DataStorePrepareGetParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int = 0
lock_id: int = 0
persistence_target: [DataStorePersistenceTarget](#datastorepersistencetarget) = [DataStorePersistenceTarget](#datastorepersistencetarget)()
access_password: int = 0
If `nex.version` >= 30500:
extra_data: list[str] = []


## DataStorePrepareGetParamV1 **def _\_init__**()
Creates a new `DataStorePrepareGetParamV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
lock_id: int = 0

## DataStorePreparePostParam **def _\_init__**()
Creates a new `DataStorePreparePostParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
size: int
name: str
data_type: int
meta_binary: bytes
permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
delete_permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
flag: int
period: int
refer_data_id: int = 0
tags: list[str] = []
rating_init_param: list[[DataStoreRatingInitParamWithSlot](#datastoreratinginitparamwithslot)] = []
persistence_init_param: [DataStorePersistenceInitParam](#datastorepersistenceinitparam) = [DataStorePersistenceInitParam](#datastorepersistenceinitparam)()
If `nex.version` >= 30500:
extra_data: list[str]


## DataStorePreparePostParamV1 **def _\_init__**()
Creates a new `DataStorePreparePostParamV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
size: int
name: str
data_type: int = 0
meta_binary: bytes = b""
permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
delete_permission: [DataStorePermission](#datastorepermission) = [DataStorePermission](#datastorepermission)()
flag: int
period: int
refer_data_id: int = 0
tags: list[str]
rating_init_param: list[[DataStoreRatingInitParamWithSlot](#datastoreratinginitparamwithslot)]

## DataStorePrepareUpdateParam **def _\_init__**()
Creates a new `DataStorePrepareUpdateParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
size: int
update_password: int
extra_data: list[str]

## DataStoreRateObjectParam **def _\_init__**()
Creates a new `DataStoreRateObjectParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
rating_value: int
access_password: int

## DataStoreRatingInfo **def _\_init__**()
Creates a new `DataStoreRatingInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
total_value: int
count: int
initial_value: int

## DataStoreRatingInfoWithSlot **def _\_init__**()
Creates a new `DataStoreRatingInfoWithSlot` instance. Required fields must be filled in manually. The following fields are defined in this class:
slot: int
info: [DataStoreRatingInfo](#datastoreratinginfo) = [DataStoreRatingInfo](#datastoreratinginfo)()

## DataStoreRatingInitParam **def _\_init__**()
Creates a new `DataStoreRatingInitParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
flag: int
internal_flag: int
lock_type: int
initial_value: int
range_min: int
range_max: int
period_hour: int
period_duration: int

## DataStoreRatingInitParamWithSlot **def _\_init__**()
Creates a new `DataStoreRatingInitParamWithSlot` instance. Required fields must be filled in manually. The following fields are defined in this class:
slot: int
param: [DataStoreRatingInitParam](#datastoreratinginitparam) = [DataStoreRatingInitParam](#datastoreratinginitparam)()

## DataStoreRatingLog **def _\_init__**()
Creates a new `DataStoreRatingLog` instance. Required fields must be filled in manually. The following fields are defined in this class:
is_rated: bool
pid: int
rating_value: int
lock_expiration_time: [DateTime](common.md#datetime)

## DataStoreRatingTarget **def _\_init__**()
Creates a new `DataStoreRatingTarget` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
slot: int

## DataStoreReqGetAdditionalMeta **def _\_init__**()
Creates a new `DataStoreReqGetAdditionalMeta` instance. Required fields must be filled in manually. The following fields are defined in this class:
owner_id: int
data_type: int
version: int
meta_binary: bytes

## DataStoreReqGetInfo **def _\_init__**()
Creates a new `DataStoreReqGetInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
url: str
headers: list[[DataStoreKeyValue](#datastorekeyvalue)]
size: int
root_ca_cert: bytes
If `nex.version` >= 30500:
data_id: int


## DataStoreReqGetInfoV1 **def _\_init__**()
Creates a new `DataStoreReqGetInfoV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
url: str
headers: list[[DataStoreKeyValue](#datastorekeyvalue)]
size: int
root_ca_cert: bytes

## DataStoreReqGetNotificationUrlInfo **def _\_init__**()
Creates a new `DataStoreReqGetNotificationUrlInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
url: str
key: str
query: str
root_ca_cert: bytes

## DataStoreReqPostInfo **def _\_init__**()
Creates a new `DataStoreReqPostInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
url: str
headers: list[[DataStoreKeyValue](#datastorekeyvalue)]
form: list[[DataStoreKeyValue](#datastorekeyvalue)]
root_ca_cert: bytes

## DataStoreReqPostInfoV1 **def _\_init__**()
Creates a new `DataStoreReqPostInfoV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
url: str
headers: list[[DataStoreKeyValue](#datastorekeyvalue)]
form: list[[DataStoreKeyValue](#datastorekeyvalue)]
root_ca_cert: bytes

## DataStoreReqUpdateInfo **def _\_init__**()
Creates a new `DataStoreReqUpdateInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
version: int
url: str
headers: list[[DataStoreKeyValue](#datastorekeyvalue)]
form: list[[DataStoreKeyValue](#datastorekeyvalue)]
root_ca_cert: bytes

## DataStoreSearchParam **def _\_init__**()
Creates a new `DataStoreSearchParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
search_target: int = 1
owner_ids: list[int] = []
owner_type: int = 0
destination_ids: list[int] = []
data_type: int = 65535
created_after: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).future()
created_before: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).future()
updated_after: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).future()
updated_before: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).future()
refer_data_id: int = 0
tags: list[str] = []
result_order_column: int = 0
result_order: int = 0
result_range: [ResultRange](common.md#resultrange) = [ResultRange](common.md#resultrange)()
result_option: int = 0
minimal_rating_frequency: int = 0
use_cache: bool = False
total_count_enabled: bool = True
data_types: list[int] = []

## DataStoreSearchResult **def _\_init__**()
Creates a new `DataStoreSearchResult` instance. Required fields must be filled in manually. The following fields are defined in this class:
total_count: int
result: list[[DataStoreMetaInfo](#datastoremetainfo)]
total_count_type: int

## DataStoreSpecificMetaInfo **def _\_init__**()
Creates a new `DataStoreSpecificMetaInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
owner_id: int
size: int
data_type: int
version: int

## DataStoreSpecificMetaInfoV1 **def _\_init__**()
Creates a new `DataStoreSpecificMetaInfoV1` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
owner_id: int
size: int
data_type: int
version: int

## DataStoreTouchObjectParam **def _\_init__**()
Creates a new `DataStoreTouchObjectParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
lock_id: int
access_password: int

## DeathPositionInfo **def _\_init__**()
Creates a new `DeathPositionInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
x: int
y: int
is_subworld: bool

## EventCourseGhostInfo **def _\_init__**()
Creates a new `EventCourseGhostInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
replay_file: [RelationObjectReqGetInfo](#relationobjectreqgetinfo) = [RelationObjectReqGetInfo](#relationobjectreqgetinfo)()
time: int
pid: int

## EventCourseHistogram **def _\_init__**()
Creates a new `EventCourseHistogram` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
unk1: int
unk2: int
unk3: int
values: list[int]
medals: dict[int, int]
unk4: int

## EventCourseInfo **def _\_init__**()
Creates a new `EventCourseInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
name: str
description: str
game_style: int
course_theme: int
unk1: bool
unk2: bool
upload_time: [DateTime](common.md#datetime)
get_info: [DataStoreReqGetInfo](#datastorereqgetinfo) = [DataStoreReqGetInfo](#datastorereqgetinfo)()
unk3: dict[int, int]
unk4: [UnknownStruct6](#unknownstruct6) = [UnknownStruct6](#unknownstruct6)()
unk5: int
one_screen_thumbnail: [EventCourseThumbnail](#eventcoursethumbnail) = [EventCourseThumbnail](#eventcoursethumbnail)()
entire_thumbnail: [EventCourseThumbnail](#eventcoursethumbnail) = [EventCourseThumbnail](#eventcoursethumbnail)()
If `revision` >= 1:
end_time: [DateTime](common.md#datetime)
unk6: int
unk7: int
unk8: int
unk9: int
best_time: int
unk10: int
medal_time: int
personal_ghost: [RelationObjectReqGetInfo](#relationobjectreqgetinfo) = [RelationObjectReqGetInfo](#relationobjectreqgetinfo)()


## EventCourseStatusInfo **def _\_init__**()
Creates a new `EventCourseStatusInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
unk1: int
unk2: bool
unk3: [DateTime](common.md#datetime)

## EventCourseThumbnail **def _\_init__**()
Creates a new `EventCourseThumbnail` instance. Required fields must be filled in manually. The following fields are defined in this class:
url: str
headers: list[[DataStoreKeyValue](#datastorekeyvalue)]
filesize: int
root_ca_cert: bytes
filename: str

## GetCoursesEventParam **def _\_init__**()
Creates a new `GetCoursesEventParam` instance. Required fields must be filled in manually. The following fields are defined in this class:

## GetCoursesParam **def _\_init__**()
Creates a new `GetCoursesParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_ids: list[int]
option: int = 0

## GetEventCourseGhostParam **def _\_init__**()
Creates a new `GetEventCourseGhostParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
time: int
count: int

## GetEventCourseHistogramParam **def _\_init__**()
Creates a new `GetEventCourseHistogramParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int

## GetUserOrCourseParam **def _\_init__**()
Creates a new `GetUserOrCourseParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
code: str
user_option: int = 0
course_option: int = 0

## GetUsersParam **def _\_init__**()
Creates a new `GetUsersParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
pids: list[int]
option: int = 0

## GetWorldMapParam **def _\_init__**()
Creates a new `GetWorldMapParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
ids: list[str]
option: int = 0

## RegisterUserParam **def _\_init__**()
Creates a new `RegisterUserParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
name: str
unk1: [UnknownStruct1](#unknownstruct1) = [UnknownStruct1](#unknownstruct1)()
unk2: bytes
language: int
country: str
device_id: str

## RelationObjectReqGetInfo **def _\_init__**()
Creates a new `RelationObjectReqGetInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
url: str
data_type: int
size: int
unk: bytes
filename: str

## ReqGetInfoHeadersInfo **def _\_init__**()
Creates a new `ReqGetInfoHeadersInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
headers: list[[DataStoreKeyValue](#datastorekeyvalue)]
expiration: int

## SearchCommentsInOrderParam **def _\_init__**()
Creates a new `SearchCommentsInOrderParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
range: [ResultRange](common.md#resultrange) = [ResultRange](common.md#resultrange)()

## SearchCoursesBestTimeParam **def _\_init__**()
Creates a new `SearchCoursesBestTimeParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
option: int = 0
range: [ResultRange](common.md#resultrange) = [ResultRange](common.md#resultrange)()

## SearchCoursesEndlessModeParam **def _\_init__**()
Creates a new `SearchCoursesEndlessModeParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
option: int = 0
count: int
difficulty: int

## SearchCoursesEventParam **def _\_init__**()
Creates a new `SearchCoursesEventParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
option: int = 0

## SearchCoursesFirstClearParam **def _\_init__**()
Creates a new `SearchCoursesFirstClearParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
option: int = 0
range: [ResultRange](common.md#resultrange) = [ResultRange](common.md#resultrange)()

## SearchCoursesLatestParam **def _\_init__**()
Creates a new `SearchCoursesLatestParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
option: int = 0
range: [ResultRange](common.md#resultrange) = [ResultRange](common.md#resultrange)()

## SearchCoursesPlayedByParam **def _\_init__**()
Creates a new `SearchCoursesPlayedByParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
option: int = 0
count: int
pid: int

## SearchCoursesPointRankingParam **def _\_init__**()
Creates a new `SearchCoursesPointRankingParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
option: int = 0
range: [ResultRange](common.md#resultrange) = [ResultRange](common.md#resultrange)()
difficulty: int
reject_regions: list[int] = []

## SearchCoursesPositiveRatedByParam **def _\_init__**()
Creates a new `SearchCoursesPositiveRatedByParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
option: int = 0
count: int
pid: int

## SearchCoursesPostedByParam **def _\_init__**()
Creates a new `SearchCoursesPostedByParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
option: int = 0
range: [ResultRange](common.md#resultrange) = [ResultRange](common.md#resultrange)()
pids: list[int]

## SearchUsersClearedCourseParam **def _\_init__**()
Creates a new `SearchUsersClearedCourseParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
option: int = 0
count: int

## SearchUsersPlayedCourseParam **def _\_init__**()
Creates a new `SearchUsersPlayedCourseParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
option: int = 0
count: int

## SearchUsersPositiveRatedCourseParam **def _\_init__**()
Creates a new `SearchUsersPositiveRatedCourseParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
data_id: int
option: int = 0
count: int

## SearchUsersUserPointParam **def _\_init__**()
Creates a new `SearchUsersUserPointParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
option: int = 0
buffer: bytes
range: [ResultRange](common.md#resultrange) = [ResultRange](common.md#resultrange)()

## SearchWorldMapPickUpParam **def _\_init__**()
Creates a new `SearchWorldMapPickUpParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
count: int

## SearchWorldMapPlayedByParam **def _\_init__**()
Creates a new `SearchWorldMapPlayedByParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
unk1: int
unk2: int

## SyncUserProfileParam **def _\_init__**()
Creates a new `SyncUserProfileParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
username: str
unk1: [UnknownStruct1](#unknownstruct1) = [UnknownStruct1](#unknownstruct1)()
unk2: bytes
unk3: int
country: str
unk4: bool
unk5: bool
unk_guid: str
unk6: int

## SyncUserProfileResult **def _\_init__**()
Creates a new `SyncUserProfileResult` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
username: str
unk1: [UnknownStruct1](#unknownstruct1) = [UnknownStruct1](#unknownstruct1)()
unk2: bytes
unk3: int
country: str
unk4: int
unk5: bool
unk6: bool

## UnknownStruct1 **def _\_init__**()
Creates a new `UnknownStruct1` instance. Required fields must be filled in manually. The following fields are defined in this class:
unk1: int
unk2: int
unk3: int
unk4: int

## UnknownStruct3 **def _\_init__**()
Creates a new `UnknownStruct3` instance. Required fields must be filled in manually. The following fields are defined in this class:
unk1: bool
unk2: [DateTime](common.md#datetime)

## UnknownStruct6 **def _\_init__**()
Creates a new `UnknownStruct6` instance. Required fields must be filled in manually. The following fields are defined in this class:
unk1: int
unk2: int

## UserInfo **def _\_init__**()
Creates a new `UserInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
code: str
name: str
unk1: [UnknownStruct1](#unknownstruct1) = [UnknownStruct1](#unknownstruct1)()
unk2: bytes
country: str
region: int
last_active: [DateTime](common.md#datetime)
unk3: bool
unk4: bool
unk5: bool
play_stats: dict[int, int]
maker_stats: dict[int, int]
endless_challenge_high_scores: dict[int, int]
multiplayer_stats: dict[int, int]
unk7: dict[int, int]
badges: list[[BadgeInfo](#badgeinfo)]
unk8: dict[int, int]
unk9: dict[int, int]
If `revision` >= 1:
unk10: bool
unk11: [DateTime](common.md#datetime)
unk12: bool

If `revision` >= 2:
unk13: [UnknownStruct3](#unknownstruct3) = [UnknownStruct3](#unknownstruct3)()

If `revision` >= 3:
unk14: str
unk15: dict[int, int]
unk16: bool


## WorldMapInfo **def _\_init__**()
Creates a new `WorldMapInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
id: str
owner_id: int
unk1: bytes
thumbnail: [RelationObjectReqGetInfo](#relationobjectreqgetinfo) = [RelationObjectReqGetInfo](#relationobjectreqgetinfo)()
worlds: int
levels: int
unk2: int
unk3: [DateTime](common.md#datetime)
data_ids: list[int]
unk4: dict[int, int]
unk5: int
unk6: int
unk7: int

================================================ FILE: docs/reference/nex/debug.md ================================================ # Module: nintendo.nex.debug Provides a client and server for the `DebugProtocol`. This page was generated automatically from `debug.proto`. **class** [DebugClient](#debugclient)
The client for the `DebugProtocol`. **class** [DebugServer](#debugserver)
The server for the `DebugProtocol`. **class** [ApiCall](#apicall)([Structure](common.md))
**class** [ApiCallSummary](#apicallsummary)([Structure](common.md))
## DebugClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`DebugClient`](#debugclient). **async def enable_api_recorder**() -> None
Calls method `1` on the server. **async def disable_api_recorder**() -> None
Calls method `2` on the server. **async def is_api_recorder_enabled**() -> bool
Calls method `3` on the server. **async def get_api_calls**(pids: list[int], start: [DateTime](common.md#datetime), end: [DateTime](common.md#datetime)) -> list[[ApiCall](#apicall)]
Calls method `4` on the server. **async def get_api_call_summary**(pid: int, start: [DateTime](common.md#datetime), end: [DateTime](common.md#datetime), only_limit_exceeded: bool) -> list[[ApiCallSummary](#apicallsummary)]
Calls method `7` on the server. ## DebugServer **def _\_init__**()
Creates a new [`DebugServer`](#debugserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def enable_api_recorder**(client: [RMCClient](rmc.md#rmcclient)) -> None
Handler for method `1`. This method should be overridden by a subclass. **async def disable_api_recorder**(client: [RMCClient](rmc.md#rmcclient)) -> None
Handler for method `2`. This method should be overridden by a subclass. **async def is_api_recorder_enabled**(client: [RMCClient](rmc.md#rmcclient)) -> bool
Handler for method `3`. This method should be overridden by a subclass. **async def get_api_calls**(client: [RMCClient](rmc.md#rmcclient), pids: list[int], start: [DateTime](common.md#datetime), end: [DateTime](common.md#datetime)) -> list[[ApiCall](#apicall)]
Handler for method `4`. This method should be overridden by a subclass. **async def get_api_call_summary**(client: [RMCClient](rmc.md#rmcclient), pid: int, start: [DateTime](common.md#datetime), end: [DateTime](common.md#datetime), only_limit_exceeded: bool) -> list[[ApiCallSummary](#apicallsummary)]
Handler for method `7`. This method should be overridden by a subclass. ## ApiCall **def _\_init__**()
Creates a new `ApiCall` instance. Required fields must be filled in manually. The following fields are defined in this class:
name: str
time: [DateTime](common.md#datetime)
pid: int

## ApiCallSummary **def _\_init__**()
Creates a new `ApiCallSummary` instance. Required fields must be filled in manually. The following fields are defined in this class:
name: str
limit_exceeded: int
duration: int
limit: int
start: [DateTime](common.md#datetime)
limit_exceeded_count: int
total_count: int

================================================ FILE: docs/reference/nex/errors.md ================================================ # Module: nintendo.nex.errors Provides descriptions for error codes. The error codes in these tables do **not** have the most significant bit set. `error_names: dict[int, str]`
Provides descriptions for error codes. `error_codes: dict[str, int]`
The reverse of `error_names`. ================================================ FILE: docs/reference/nex/friends.md ================================================ # Module: nintendo.nex.friends Provides a client and server for the `FriendsProtocolV1` and `FriendsProtocolV2`. This page was generated automatically from `friends.proto`. **class** [FriendsClientV1](#friendsclientv1)
The client for the `FriendsProtocolV1`. **class** [FriendsClientV2](#friendsclientv2)
The client for the `FriendsProtocolV2`. **class** [FriendsServerV1](#friendsserverv1)
The server for the `FriendsProtocolV1`. **class** [FriendsServerV2](#friendsserverv2)
The server for the `FriendsProtocolV2`. **class** [AccountExtraInfo](#accountextrainfo)([Structure](common.md))
**class** [BlacklistedPrincipal](#blacklistedprincipal)([Data](common.md))
**class** [Comment](#comment)([Data](common.md))
**class** [FriendComment](#friendcomment)([Data](common.md))
**class** [FriendInfo](#friendinfo)([Data](common.md))
**class** [FriendKey](#friendkey)([Structure](common.md))
**class** [FriendMii](#friendmii)([Data](common.md))
**class** [FriendMiiList](#friendmiilist)([Data](common.md))
**class** [FriendPersistentInfo](#friendpersistentinfo)([Data](common.md))
**class** [FriendPicture](#friendpicture)([Data](common.md))
**class** [FriendPresence](#friendpresence)([Data](common.md))
**class** [FriendRelationship](#friendrelationship)([Data](common.md))
**class** [FriendRequest](#friendrequest)([Data](common.md))
**class** [FriendRequestMessage](#friendrequestmessage)([Data](common.md))
**class** [GameKey](#gamekey)([Data](common.md))
**class** [Mii](#mii)([Data](common.md))
**class** [MiiList](#miilist)([Data](common.md))
**class** [MiiV2](#miiv2)([Data](common.md))
**class** [MyProfile](#myprofile)([Data](common.md))
**class** [NNAInfo](#nnainfo)([Data](common.md))
**class** [NintendoCreateAccountData](#nintendocreateaccountdata)([Data](common.md))
**class** [NintendoPresence](#nintendopresence)([Data](common.md))
**class** [NintendoPresenceV2](#nintendopresencev2)([Data](common.md))
**class** [PersistentNotification](#persistentnotification)([Data](common.md))
**class** [PlayedGame](#playedgame)([Data](common.md))
**class** [PrincipalBasicInfo](#principalbasicinfo)([Data](common.md))
**class** [PrincipalPreference](#principalpreference)([Data](common.md))
**class** [PrincipalRequestBlockSetting](#principalrequestblocksetting)([Data](common.md))
## FriendsClientV1 **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`FriendsClientV1`](#friendsclientv1). **async def update_profile**(profile_data: [MyProfile](#myprofile)) -> None
Calls method `1` on the server. **async def update_mii**(mii: [Mii](#mii)) -> None
Calls method `2` on the server. **async def update_mii_list**(mii_list: [MiiList](#miilist)) -> None
Calls method `3` on the server. **async def update_played_games**(played_games: list[[PlayedGame](#playedgame)]) -> None
Calls method `4` on the server. **async def update_preference**(show_online_status: bool, show_current_title: bool, block_friend_requests: bool) -> None
Calls method `5` on the server. **async def get_friend_mii**(friends: list[[FriendKey](#friendkey)]) -> list[[FriendMii](#friendmii)]
Calls method `6` on the server. **async def get_friend_mii_list**(friends: list[[FriendKey](#friendkey)]) -> list[[FriendMiiList](#friendmiilist)]
Calls method `7` on the server. **async def is_active_game**(unk1: list[int], game_key: [GameKey](#gamekey)) -> list[int]
Calls method `8` on the server. **async def get_principal_id_by_local_friend_code**(unk1: int, unk2: list[int]) -> list[[FriendRelationship](#friendrelationship)]
Calls method `9` on the server. **async def get_friend_relationships**(principal_ids: list[int]) -> list[[FriendRelationship](#friendrelationship)]
Calls method `10` on the server. **async def add_friend_by_principal_id**(friend_seed: int, pid: int) -> [FriendRelationship](#friendrelationship)
Calls method `11` on the server. **async def add_friend_by_principal_ids**(unk: int, pids: list[int]) -> list[[FriendRelationship](#friendrelationship)]
Calls method `12` on the server. **async def remove_friend_by_local_friend_code**(friend_code: int) -> None
Calls method `13` on the server. **async def remove_friend_by_principal_id**(pid: int) -> None
Calls method `14` on the server. **async def get_all_friends**() -> list[[FriendRelationship](#friendrelationship)]
Calls method `15` on the server. **async def update_black_list**(unk: list[int]) -> None
Calls method `16` on the server. **async def sync_friend**(friend_seed: int, principal_ids: list[int], unk: list[int]) -> list[[FriendRelationship](#friendrelationship)]
Calls method `17` on the server. **async def update_presence**(presence_info: [NintendoPresence](#nintendopresence), unk: bool) -> None
Calls method `18` on the server. **async def update_favorite_game_key**(game_key: [GameKey](#gamekey)) -> None
Calls method `19` on the server. **async def update_comment**(comment: str) -> None
Calls method `20` on the server. **async def update_picture**(unk: int, picture: bytes) -> None
Calls method `21` on the server. **async def get_friend_presence**(principal_ids: list[int]) -> list[[FriendPresence](#friendpresence)]
Calls method `22` on the server. **async def get_friend_comment**(friends: list[[FriendKey](#friendkey)]) -> list[[FriendComment](#friendcomment)]
Calls method `23` on the server. **async def get_friend_picture**(principal_ids: list[int]) -> list[[FriendPicture](#friendpicture)]
Calls method `24` on the server. **async def get_friend_persistent_info**(principal_ids: list[int]) -> list[[FriendPersistentInfo](#friendpersistentinfo)]
Calls method `25` on the server. **async def send_invitation**(unk: list[int]) -> None
Calls method `26` on the server. ## FriendsClientV2 **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`FriendsClientV2`](#friendsclientv2). **async def update_and_get_all_information**(nna_info: [NNAInfo](#nnainfo), presence: [NintendoPresenceV2](#nintendopresencev2), birthday: [DateTime](common.md#datetime)) -> [RMCResponse](common.md)
Calls method `1` on the server. The RMC response has the following attributes:
principal_preference: [PrincipalPreference](#principalpreference)
comment: [Comment](#comment)
friends: list[[FriendInfo](#friendinfo)]
sent_requests: list[[FriendRequest](#friendrequest)]
received_requests: list[[FriendRequest](#friendrequest)]
blacklist: list[[BlacklistedPrincipal](#blacklistedprincipal)]
unk1: bool
notifications: list[[PersistentNotification](#persistentnotification)]
unk2: bool
**async def add_friend**(pid: int) -> [RMCResponse](common.md)
Calls method `2` on the server. The RMC response has the following attributes:
request: [FriendRequest](#friendrequest)
info: [FriendInfo](#friendinfo)
**async def add_friend_by_name**(name: str) -> [RMCResponse](common.md)
Calls method `3` on the server. The RMC response has the following attributes:
request: [FriendRequest](#friendrequest)
info: [FriendInfo](#friendinfo)
**async def remove_friend**(pid: int) -> None
Calls method `4` on the server. **async def add_friend_request**(unk1: int, unk2: int, unk3: str, unk4: int, unk5: str, game_key: [GameKey](#gamekey), unk6: [DateTime](common.md#datetime)) -> [RMCResponse](common.md)
Calls method `5` on the server. The RMC response has the following attributes:
request: [FriendRequest](#friendrequest)
info: [FriendInfo](#friendinfo)
**async def cancel_friend_request**(id: int) -> None
Calls method `6` on the server. **async def accept_friend_request**(id: int) -> [FriendInfo](#friendinfo)
Calls method `7` on the server. **async def delete_friend_request**(id: int) -> None
Calls method `8` on the server. **async def deny_friend_request**(id: int) -> [BlacklistedPrincipal](#blacklistedprincipal)
Calls method `9` on the server. **async def mark_friend_requests_as_received**(ids: list[int]) -> None
Calls method `10` on the server. **async def add_black_list**(principal: [BlacklistedPrincipal](#blacklistedprincipal)) -> [BlacklistedPrincipal](#blacklistedprincipal)
Calls method `11` on the server. **async def remove_black_list**(pid: int) -> None
Calls method `12` on the server. **async def update_presence**(presence: [NintendoPresenceV2](#nintendopresencev2)) -> None
Calls method `13` on the server. **async def update_mii**(mii: [MiiV2](#miiv2)) -> [DateTime](common.md#datetime)
Calls method `14` on the server. **async def update_comment**(comment: [Comment](#comment)) -> [DateTime](common.md#datetime)
Calls method `15` on the server. **async def update_preference**(preference: [PrincipalPreference](#principalpreference)) -> None
Calls method `16` on the server. **async def get_basic_info**(pids: list[int]) -> list[[PrincipalBasicInfo](#principalbasicinfo)]
Calls method `17` on the server. **async def delete_persistent_notification**(notifications: list[[PersistentNotification](#persistentnotification)]) -> None
Calls method `18` on the server. **async def check_setting_status**() -> int
Calls method `19` on the server. **async def get_request_block_settings**(unk: list[int]) -> list[[PrincipalRequestBlockSetting](#principalrequestblocksetting)]
Calls method `20` on the server. ## FriendsServerV1 **def _\_init__**()
Creates a new [`FriendsServerV1`](#friendsserverv1). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def update_profile**(client: [RMCClient](rmc.md#rmcclient), profile_data: [MyProfile](#myprofile)) -> None
Handler for method `1`. This method should be overridden by a subclass. **async def update_mii**(client: [RMCClient](rmc.md#rmcclient), mii: [Mii](#mii)) -> None
Handler for method `2`. This method should be overridden by a subclass. **async def update_mii_list**(client: [RMCClient](rmc.md#rmcclient), mii_list: [MiiList](#miilist)) -> None
Handler for method `3`. This method should be overridden by a subclass. **async def update_played_games**(client: [RMCClient](rmc.md#rmcclient), played_games: list[[PlayedGame](#playedgame)]) -> None
Handler for method `4`. This method should be overridden by a subclass. **async def update_preference**(client: [RMCClient](rmc.md#rmcclient), show_online_status: bool, show_current_title: bool, block_friend_requests: bool) -> None
Handler for method `5`. This method should be overridden by a subclass. **async def get_friend_mii**(client: [RMCClient](rmc.md#rmcclient), friends: list[[FriendKey](#friendkey)]) -> list[[FriendMii](#friendmii)]
Handler for method `6`. This method should be overridden by a subclass. **async def get_friend_mii_list**(client: [RMCClient](rmc.md#rmcclient), friends: list[[FriendKey](#friendkey)]) -> list[[FriendMiiList](#friendmiilist)]
Handler for method `7`. This method should be overridden by a subclass. **async def is_active_game**(client: [RMCClient](rmc.md#rmcclient), unk1: list[int], game_key: [GameKey](#gamekey)) -> list[int]
Handler for method `8`. This method should be overridden by a subclass. **async def get_principal_id_by_local_friend_code**(client: [RMCClient](rmc.md#rmcclient), unk1: int, unk2: list[int]) -> list[[FriendRelationship](#friendrelationship)]
Handler for method `9`. This method should be overridden by a subclass. **async def get_friend_relationships**(client: [RMCClient](rmc.md#rmcclient), principal_ids: list[int]) -> list[[FriendRelationship](#friendrelationship)]
Handler for method `10`. This method should be overridden by a subclass. **async def add_friend_by_principal_id**(client: [RMCClient](rmc.md#rmcclient), friend_seed: int, pid: int) -> [FriendRelationship](#friendrelationship)
Handler for method `11`. This method should be overridden by a subclass. **async def add_friend_by_principal_ids**(client: [RMCClient](rmc.md#rmcclient), unk: int, pids: list[int]) -> list[[FriendRelationship](#friendrelationship)]
Handler for method `12`. This method should be overridden by a subclass. **async def remove_friend_by_local_friend_code**(client: [RMCClient](rmc.md#rmcclient), friend_code: int) -> None
Handler for method `13`. This method should be overridden by a subclass. **async def remove_friend_by_principal_id**(client: [RMCClient](rmc.md#rmcclient), pid: int) -> None
Handler for method `14`. This method should be overridden by a subclass. **async def get_all_friends**(client: [RMCClient](rmc.md#rmcclient)) -> list[[FriendRelationship](#friendrelationship)]
Handler for method `15`. This method should be overridden by a subclass. **async def update_black_list**(client: [RMCClient](rmc.md#rmcclient), unk: list[int]) -> None
Handler for method `16`. This method should be overridden by a subclass. **async def sync_friend**(client: [RMCClient](rmc.md#rmcclient), friend_seed: int, principal_ids: list[int], unk: list[int]) -> list[[FriendRelationship](#friendrelationship)]
Handler for method `17`. This method should be overridden by a subclass. **async def update_presence**(client: [RMCClient](rmc.md#rmcclient), presence_info: [NintendoPresence](#nintendopresence), unk: bool) -> None
Handler for method `18`. This method should be overridden by a subclass. **async def update_favorite_game_key**(client: [RMCClient](rmc.md#rmcclient), game_key: [GameKey](#gamekey)) -> None
Handler for method `19`. This method should be overridden by a subclass. **async def update_comment**(client: [RMCClient](rmc.md#rmcclient), comment: str) -> None
Handler for method `20`. This method should be overridden by a subclass. **async def update_picture**(client: [RMCClient](rmc.md#rmcclient), unk: int, picture: bytes) -> None
Handler for method `21`. This method should be overridden by a subclass. **async def get_friend_presence**(client: [RMCClient](rmc.md#rmcclient), principal_ids: list[int]) -> list[[FriendPresence](#friendpresence)]
Handler for method `22`. This method should be overridden by a subclass. **async def get_friend_comment**(client: [RMCClient](rmc.md#rmcclient), friends: list[[FriendKey](#friendkey)]) -> list[[FriendComment](#friendcomment)]
Handler for method `23`. This method should be overridden by a subclass. **async def get_friend_picture**(client: [RMCClient](rmc.md#rmcclient), principal_ids: list[int]) -> list[[FriendPicture](#friendpicture)]
Handler for method `24`. This method should be overridden by a subclass. **async def get_friend_persistent_info**(client: [RMCClient](rmc.md#rmcclient), principal_ids: list[int]) -> list[[FriendPersistentInfo](#friendpersistentinfo)]
Handler for method `25`. This method should be overridden by a subclass. **async def send_invitation**(client: [RMCClient](rmc.md#rmcclient), unk: list[int]) -> None
Handler for method `26`. This method should be overridden by a subclass. ## FriendsServerV2 **def _\_init__**()
Creates a new [`FriendsServerV2`](#friendsserverv2). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def update_and_get_all_information**(client: [RMCClient](rmc.md#rmcclient), nna_info: [NNAInfo](#nnainfo), presence: [NintendoPresenceV2](#nintendopresencev2), birthday: [DateTime](common.md#datetime)) -> [RMCResponse](common.md)
Handler for method `1`. This method should be overridden by a subclass. The RMC response must have the following attributes:
principal_preference: [PrincipalPreference](#principalpreference)
comment: [Comment](#comment)
friends: list[[FriendInfo](#friendinfo)]
sent_requests: list[[FriendRequest](#friendrequest)]
received_requests: list[[FriendRequest](#friendrequest)]
blacklist: list[[BlacklistedPrincipal](#blacklistedprincipal)]
unk1: bool
notifications: list[[PersistentNotification](#persistentnotification)]
unk2: bool
**async def add_friend**(client: [RMCClient](rmc.md#rmcclient), pid: int) -> [RMCResponse](common.md)
Handler for method `2`. This method should be overridden by a subclass. The RMC response must have the following attributes:
request: [FriendRequest](#friendrequest)
info: [FriendInfo](#friendinfo)
**async def add_friend_by_name**(client: [RMCClient](rmc.md#rmcclient), name: str) -> [RMCResponse](common.md)
Handler for method `3`. This method should be overridden by a subclass. The RMC response must have the following attributes:
request: [FriendRequest](#friendrequest)
info: [FriendInfo](#friendinfo)
**async def remove_friend**(client: [RMCClient](rmc.md#rmcclient), pid: int) -> None
Handler for method `4`. This method should be overridden by a subclass. **async def add_friend_request**(client: [RMCClient](rmc.md#rmcclient), unk1: int, unk2: int, unk3: str, unk4: int, unk5: str, game_key: [GameKey](#gamekey), unk6: [DateTime](common.md#datetime)) -> [RMCResponse](common.md)
Handler for method `5`. This method should be overridden by a subclass. The RMC response must have the following attributes:
request: [FriendRequest](#friendrequest)
info: [FriendInfo](#friendinfo)
**async def cancel_friend_request**(client: [RMCClient](rmc.md#rmcclient), id: int) -> None
Handler for method `6`. This method should be overridden by a subclass. **async def accept_friend_request**(client: [RMCClient](rmc.md#rmcclient), id: int) -> [FriendInfo](#friendinfo)
Handler for method `7`. This method should be overridden by a subclass. **async def delete_friend_request**(client: [RMCClient](rmc.md#rmcclient), id: int) -> None
Handler for method `8`. This method should be overridden by a subclass. **async def deny_friend_request**(client: [RMCClient](rmc.md#rmcclient), id: int) -> [BlacklistedPrincipal](#blacklistedprincipal)
Handler for method `9`. This method should be overridden by a subclass. **async def mark_friend_requests_as_received**(client: [RMCClient](rmc.md#rmcclient), ids: list[int]) -> None
Handler for method `10`. This method should be overridden by a subclass. **async def add_black_list**(client: [RMCClient](rmc.md#rmcclient), principal: [BlacklistedPrincipal](#blacklistedprincipal)) -> [BlacklistedPrincipal](#blacklistedprincipal)
Handler for method `11`. This method should be overridden by a subclass. **async def remove_black_list**(client: [RMCClient](rmc.md#rmcclient), pid: int) -> None
Handler for method `12`. This method should be overridden by a subclass. **async def update_presence**(client: [RMCClient](rmc.md#rmcclient), presence: [NintendoPresenceV2](#nintendopresencev2)) -> None
Handler for method `13`. This method should be overridden by a subclass. **async def update_mii**(client: [RMCClient](rmc.md#rmcclient), mii: [MiiV2](#miiv2)) -> [DateTime](common.md#datetime)
Handler for method `14`. This method should be overridden by a subclass. **async def update_comment**(client: [RMCClient](rmc.md#rmcclient), comment: [Comment](#comment)) -> [DateTime](common.md#datetime)
Handler for method `15`. This method should be overridden by a subclass. **async def update_preference**(client: [RMCClient](rmc.md#rmcclient), preference: [PrincipalPreference](#principalpreference)) -> None
Handler for method `16`. This method should be overridden by a subclass. **async def get_basic_info**(client: [RMCClient](rmc.md#rmcclient), pids: list[int]) -> list[[PrincipalBasicInfo](#principalbasicinfo)]
Handler for method `17`. This method should be overridden by a subclass. **async def delete_persistent_notification**(client: [RMCClient](rmc.md#rmcclient), notifications: list[[PersistentNotification](#persistentnotification)]) -> None
Handler for method `18`. This method should be overridden by a subclass. **async def check_setting_status**(client: [RMCClient](rmc.md#rmcclient)) -> int
Handler for method `19`. This method should be overridden by a subclass. **async def get_request_block_settings**(client: [RMCClient](rmc.md#rmcclient), unk: list[int]) -> list[[PrincipalRequestBlockSetting](#principalrequestblocksetting)]
Handler for method `20`. This method should be overridden by a subclass. ## AccountExtraInfo **def _\_init__**()
Creates a new `AccountExtraInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
local_friend_code: int
move_count: int
token: str

## BlacklistedPrincipal **def _\_init__**()
Creates a new `BlacklistedPrincipal` instance. Required fields must be filled in manually. The following fields are defined in this class:
principal_info: [PrincipalBasicInfo](#principalbasicinfo) = [PrincipalBasicInfo](#principalbasicinfo)()
game_key: [GameKey](#gamekey) = [GameKey](#gamekey)()
since: [DateTime](common.md#datetime)

## Comment **def _\_init__**()
Creates a new `Comment` instance. Required fields must be filled in manually. The following fields are defined in this class:
unk: int
text: str
changed: [DateTime](common.md#datetime)

## FriendComment **def _\_init__**()
Creates a new `FriendComment` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
comment: str
modified_at: [DateTime](common.md#datetime)

## FriendInfo **def _\_init__**()
Creates a new `FriendInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
nna_info: [NNAInfo](#nnainfo) = [NNAInfo](#nnainfo)()
presence: [NintendoPresenceV2](#nintendopresencev2) = [NintendoPresenceV2](#nintendopresencev2)()
comment: [Comment](#comment) = [Comment](#comment)()
befriended: [DateTime](common.md#datetime)
last_online: [DateTime](common.md#datetime)
unk: int

## FriendKey **def _\_init__**()
Creates a new `FriendKey` instance. Required fields must be filled in manually. The following fields are defined in this class:
unk1: int
unk2: [DateTime](common.md#datetime)

## FriendMii **def _\_init__**()
Creates a new `FriendMii` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
mii: [Mii](#mii) = [Mii](#mii)()
modified_at: [DateTime](common.md#datetime)

## FriendMiiList **def _\_init__**()
Creates a new `FriendMiiList` instance. Required fields must be filled in manually. The following fields are defined in this class:
unk1: int
mii: [MiiList](#miilist) = [MiiList](#miilist)()
unk2: [DateTime](common.md#datetime)

## FriendPersistentInfo **def _\_init__**()
Creates a new `FriendPersistentInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
region: int
country: int
area: int
language: int
platform: int
game_key: [GameKey](#gamekey) = [GameKey](#gamekey)()
message: str
message_updated: [DateTime](common.md#datetime)
friended: [DateTime](common.md#datetime)
last_online: [DateTime](common.md#datetime)

## FriendPicture **def _\_init__**()
Creates a new `FriendPicture` instance. Required fields must be filled in manually. The following fields are defined in this class:
unk: int
data: bytes
datetime: [DateTime](common.md#datetime)

## FriendPresence **def _\_init__**()
Creates a new `FriendPresence` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
presence: [NintendoPresence](#nintendopresence) = [NintendoPresence](#nintendopresence)()

## FriendRelationship **def _\_init__**()
Creates a new `FriendRelationship` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
friend_code: int
is_complete: int

## FriendRequest **def _\_init__**()
Creates a new `FriendRequest` instance. Required fields must be filled in manually. The following fields are defined in this class:
principal_info: [PrincipalBasicInfo](#principalbasicinfo) = [PrincipalBasicInfo](#principalbasicinfo)()
message: [FriendRequestMessage](#friendrequestmessage) = [FriendRequestMessage](#friendrequestmessage)()
sent: [DateTime](common.md#datetime)

## FriendRequestMessage **def _\_init__**()
Creates a new `FriendRequestMessage` instance. Required fields must be filled in manually. The following fields are defined in this class:
friend_request_id: int
unk1: int
unk2: int
message: str
unk3: int
string: str
game_key: [GameKey](#gamekey) = [GameKey](#gamekey)()
datetime: [DateTime](common.md#datetime)
expires: [DateTime](common.md#datetime)

## GameKey **def _\_init__**()
Creates a new `GameKey` instance. Required fields must be filled in manually. The following fields are defined in this class:
title_id: int = 0
title_version: int = 0

## Mii **def _\_init__**()
Creates a new `Mii` instance. Required fields must be filled in manually. The following fields are defined in this class:
name: str
unk1: bool
unk2: int
mii_data: bytes

## MiiList **def _\_init__**()
Creates a new `MiiList` instance. Required fields must be filled in manually. The following fields are defined in this class:
unk1: str
unk2: bool
unk3: int
mii_datas: list[bytes]

## MiiV2 **def _\_init__**()
Creates a new `MiiV2` instance. Required fields must be filled in manually. The following fields are defined in this class:
name: str
unk1: int = 0
unk2: int = 0
data: bytes
datetime: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).never()

## MyProfile **def _\_init__**()
Creates a new `MyProfile` instance. Required fields must be filled in manually. The following fields are defined in this class:
region: int
country: int
area: int
language: int
platform: int
local_friend_code_seed: int
mac_address: str
serial_number: str

## NNAInfo **def _\_init__**()
Creates a new `NNAInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
principal_info: [PrincipalBasicInfo](#principalbasicinfo) = [PrincipalBasicInfo](#principalbasicinfo)()
unk1: int = 94
unk2: int = 11

## NintendoCreateAccountData **def _\_init__**()
Creates a new `NintendoCreateAccountData` instance. Required fields must be filled in manually. The following fields are defined in this class:
info: [NNAInfo](#nnainfo) = [NNAInfo](#nnainfo)()
token: str
birthday: [DateTime](common.md#datetime)
unk: int

## NintendoPresence **def _\_init__**()
Creates a new `NintendoPresence` instance. Required fields must be filled in manually. The following fields are defined in this class:
changed_bit_flag: int
game_key: [GameKey](#gamekey) = [GameKey](#gamekey)()
game_mode_description: str
join_availability_flag: int
matchmake_system_type: int
join_game_id: int
join_game_mode: int
owner_pid: int
join_group_id: int
application_data: bytes

## NintendoPresenceV2 **def _\_init__**()
Creates a new `NintendoPresenceV2` instance. Required fields must be filled in manually. The following fields are defined in this class:
flags: int = 0
is_online: bool = False
game_key: [GameKey](#gamekey) = [GameKey](#gamekey)()
unk1: int = 0
message: str = ""
unk2: int = 0
unk3: int = 0
game_server_id: int = 0
unk4: int = 0
pid: int = 0
gathering_id: int = 0
application_data: bytes = b""
unk5: int = 3
unk6: int = 3
unk7: int = 3

## PersistentNotification **def _\_init__**()
Creates a new `PersistentNotification` instance. Required fields must be filled in manually. The following fields are defined in this class:
unk1: int
unk2: int
unk3: int
unk4: int
string: str

## PlayedGame **def _\_init__**()
Creates a new `PlayedGame` instance. Required fields must be filled in manually. The following fields are defined in this class:
game_key: [GameKey](#gamekey) = [GameKey](#gamekey)()
datetime: [DateTime](common.md#datetime)

## PrincipalBasicInfo **def _\_init__**()
Creates a new `PrincipalBasicInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
nnid: str
mii: [MiiV2](#miiv2) = [MiiV2](#miiv2)()
unk: int = 2

## PrincipalPreference **def _\_init__**()
Creates a new `PrincipalPreference` instance. Required fields must be filled in manually. The following fields are defined in this class:
show_online_status: bool
show_current_title: bool
block_friend_requests: bool

## PrincipalRequestBlockSetting **def _\_init__**()
Creates a new `PrincipalRequestBlockSetting` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
blocked: bool

================================================ FILE: docs/reference/nex/friends_3ds.md ================================================ # Module: nintendo.nex.friends_3ds Provides a client and server for the `FriendsProtocolV1`. This page was generated automatically from `friends_3ds.proto`. **class** [FriendsClientV1](#friendsclientv1)
The client for the `FriendsProtocolV1`. **class** [FriendsServerV1](#friendsserverv1)
The server for the `FriendsProtocolV1`. **class** [FriendMii](#friendmii)([Structure](common.md))
**class** [FriendMiiList](#friendmiilist)([Structure](common.md))
**class** [FriendMiiRequest](#friendmiirequest)([Structure](common.md))
**class** [FriendPersistentInfo](#friendpersistentinfo)([Structure](common.md))
**class** [FriendPicture](#friendpicture)([Structure](common.md))
**class** [FriendPresence](#friendpresence)([Structure](common.md))
**class** [FriendRelationship](#friendrelationship)([Structure](common.md))
**class** [GameKey](#gamekey)([Data](common.md))
**class** [Mii](#mii)([Structure](common.md))
**class** [MiiList](#miilist)([Structure](common.md))
**class** [MyProfile](#myprofile)([Structure](common.md))
**class** [NintendoPresence](#nintendopresence)([Structure](common.md))
**class** [PlayedGame](#playedgame)([Structure](common.md))
## FriendsClientV1 **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`FriendsClientV1`](#friendsclientv1). **async def update_profile**(profile_data: [MyProfile](#myprofile)) -> None
Calls method `1` on the server. **async def update_mii**(mii: [Mii](#mii)) -> None
Calls method `2` on the server. **async def update_mii_list**(mii_list: [MiiList](#miilist)) -> None
Calls method `3` on the server. **async def update_played_games**(played_games: list[[PlayedGame](#playedgame)]) -> None
Calls method `4` on the server. **async def update_preference**(unk1: bool, unk2: bool, unk3: bool) -> None
Calls method `5` on the server. **async def get_friend_mii**(friends: list[[FriendMiiRequest](#friendmiirequest)]) -> list[[FriendMii](#friendmii)]
Calls method `6` on the server. **async def get_friend_mii_list**(friends: list[[FriendMiiRequest](#friendmiirequest)]) -> list[[FriendMiiList](#friendmiilist)]
Calls method `7` on the server. **async def get_friend_relationships**(unk: list[int]) -> list[[FriendRelationship](#friendrelationship)]
Calls method `10` on the server. **async def add_friend_by_principal_id**(unk: int, pid: int) -> [FriendRelationship](#friendrelationship)
Calls method `11` on the server. **async def get_all_friends**() -> list[[FriendRelationship](#friendrelationship)]
Calls method `15` on the server. **async def sync_friend**(unk1: int, unk2: list[int], unk3: list[int]) -> list[[FriendRelationship](#friendrelationship)]
Calls method `17` on the server. **async def update_presence**(presence_info: [NintendoPresence](#nintendopresence), unk: bool) -> None
Calls method `18` on the server. **async def update_favorite_game_key**(game_key: [GameKey](#gamekey)) -> None
Calls method `19` on the server. **async def update_comment**(comment: str) -> None
Calls method `20` on the server. **async def get_friend_presence**(unk: list[int]) -> list[[FriendPresence](#friendpresence)]
Calls method `22` on the server. **async def get_friend_picture**(unk: list[int]) -> list[[FriendPicture](#friendpicture)]
Calls method `24` on the server. **async def get_friend_persistent_info**(unk: list[int]) -> list[[FriendPersistentInfo](#friendpersistentinfo)]
Calls method `25` on the server. **async def send_invitation**(unk: list[int]) -> None
Calls method `26` on the server. ## FriendsServerV1 **def _\_init__**()
Creates a new [`FriendsServerV1`](#friendsserverv1). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def update_profile**(client: [RMCClient](rmc.md#rmcclient), profile_data: [MyProfile](#myprofile)) -> None
Handler for method `1`. This method should be overridden by a subclass. **async def update_mii**(client: [RMCClient](rmc.md#rmcclient), mii: [Mii](#mii)) -> None
Handler for method `2`. This method should be overridden by a subclass. **async def update_mii_list**(client: [RMCClient](rmc.md#rmcclient), mii_list: [MiiList](#miilist)) -> None
Handler for method `3`. This method should be overridden by a subclass. **async def update_played_games**(client: [RMCClient](rmc.md#rmcclient), played_games: list[[PlayedGame](#playedgame)]) -> None
Handler for method `4`. This method should be overridden by a subclass. **async def update_preference**(client: [RMCClient](rmc.md#rmcclient), unk1: bool, unk2: bool, unk3: bool) -> None
Handler for method `5`. This method should be overridden by a subclass. **async def get_friend_mii**(client: [RMCClient](rmc.md#rmcclient), friends: list[[FriendMiiRequest](#friendmiirequest)]) -> list[[FriendMii](#friendmii)]
Handler for method `6`. This method should be overridden by a subclass. **async def get_friend_mii_list**(client: [RMCClient](rmc.md#rmcclient), friends: list[[FriendMiiRequest](#friendmiirequest)]) -> list[[FriendMiiList](#friendmiilist)]
Handler for method `7`. This method should be overridden by a subclass. **async def get_friend_relationships**(client: [RMCClient](rmc.md#rmcclient), unk: list[int]) -> list[[FriendRelationship](#friendrelationship)]
Handler for method `10`. This method should be overridden by a subclass. **async def add_friend_by_principal_id**(client: [RMCClient](rmc.md#rmcclient), unk: int, pid: int) -> [FriendRelationship](#friendrelationship)
Handler for method `11`. This method should be overridden by a subclass. **async def get_all_friends**(client: [RMCClient](rmc.md#rmcclient)) -> list[[FriendRelationship](#friendrelationship)]
Handler for method `15`. This method should be overridden by a subclass. **async def sync_friend**(client: [RMCClient](rmc.md#rmcclient), unk1: int, unk2: list[int], unk3: list[int]) -> list[[FriendRelationship](#friendrelationship)]
Handler for method `17`. This method should be overridden by a subclass. **async def update_presence**(client: [RMCClient](rmc.md#rmcclient), presence_info: [NintendoPresence](#nintendopresence), unk: bool) -> None
Handler for method `18`. This method should be overridden by a subclass. **async def update_favorite_game_key**(client: [RMCClient](rmc.md#rmcclient), game_key: [GameKey](#gamekey)) -> None
Handler for method `19`. This method should be overridden by a subclass. **async def update_comment**(client: [RMCClient](rmc.md#rmcclient), comment: str) -> None
Handler for method `20`. This method should be overridden by a subclass. **async def get_friend_presence**(client: [RMCClient](rmc.md#rmcclient), unk: list[int]) -> list[[FriendPresence](#friendpresence)]
Handler for method `22`. This method should be overridden by a subclass. **async def get_friend_picture**(client: [RMCClient](rmc.md#rmcclient), unk: list[int]) -> list[[FriendPicture](#friendpicture)]
Handler for method `24`. This method should be overridden by a subclass. **async def get_friend_persistent_info**(client: [RMCClient](rmc.md#rmcclient), unk: list[int]) -> list[[FriendPersistentInfo](#friendpersistentinfo)]
Handler for method `25`. This method should be overridden by a subclass. **async def send_invitation**(client: [RMCClient](rmc.md#rmcclient), unk: list[int]) -> None
Handler for method `26`. This method should be overridden by a subclass. ## FriendMii **def _\_init__**()
Creates a new `FriendMii` instance. Required fields must be filled in manually. The following fields are defined in this class:
unk1: int
mii: [Mii](#mii) = [Mii](#mii)()
unk2: [DateTime](common.md#datetime)

## FriendMiiList **def _\_init__**()
Creates a new `FriendMiiList` instance. Required fields must be filled in manually. The following fields are defined in this class:
unk1: int
mii: [MiiList](#miilist) = [MiiList](#miilist)()
unk2: [DateTime](common.md#datetime)

## FriendMiiRequest **def _\_init__**()
Creates a new `FriendMiiRequest` instance. Required fields must be filled in manually. The following fields are defined in this class:
unk1: int
unk2: [DateTime](common.md#datetime)

## FriendPersistentInfo **def _\_init__**()
Creates a new `FriendPersistentInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
region: int
country: int
area: int
language: int
platform: int
game_key: [GameKey](#gamekey) = [GameKey](#gamekey)()
message: str
message_updated: [DateTime](common.md#datetime)
friended: [DateTime](common.md#datetime)
unk: [DateTime](common.md#datetime)

## FriendPicture **def _\_init__**()
Creates a new `FriendPicture` instance. Required fields must be filled in manually. The following fields are defined in this class:
unk: int
data: bytes
datetime: [DateTime](common.md#datetime)

## FriendPresence **def _\_init__**()
Creates a new `FriendPresence` instance. Required fields must be filled in manually. The following fields are defined in this class:
unk: int
presence: [NintendoPresence](#nintendopresence) = [NintendoPresence](#nintendopresence)()

## FriendRelationship **def _\_init__**()
Creates a new `FriendRelationship` instance. Required fields must be filled in manually. The following fields are defined in this class:
unk1: int
unk2: int
unk3: int

## GameKey **def _\_init__**()
Creates a new `GameKey` instance. Required fields must be filled in manually. The following fields are defined in this class:
title_id: int = 0
title_version: int = 0

## Mii **def _\_init__**()
Creates a new `Mii` instance. Required fields must be filled in manually. The following fields are defined in this class:
unk1: str
unk2: bool
unk3: int
mii_data: bytes

## MiiList **def _\_init__**()
Creates a new `MiiList` instance. Required fields must be filled in manually. The following fields are defined in this class:
unk1: str
unk2: bool
unk3: int
mii_datas: list[bytes]

## MyProfile **def _\_init__**()
Creates a new `MyProfile` instance. Required fields must be filled in manually. The following fields are defined in this class:
region: int
country: int
area: int
language: int
platform: int
unk1: int
unk2: str
unk3: str

## NintendoPresence **def _\_init__**()
Creates a new `NintendoPresence` instance. Required fields must be filled in manually. The following fields are defined in this class:
changed_bit_flag: int
game_key: [GameKey](#gamekey) = [GameKey](#gamekey)()
game_mode_description: str
join_availability_flag: int
matchmake_system_type: int
join_game_id: int
join_game_mode: int
owner_pid: int
join_group_id: int
application_data: bytes

## PlayedGame **def _\_init__**()
Creates a new `PlayedGame` instance. Required fields must be filled in manually. The following fields are defined in this class:
game_key: [GameKey](#gamekey) = [GameKey](#gamekey)()
datetime: [DateTime](common.md#datetime)

================================================ FILE: docs/reference/nex/health.md ================================================ # Module: nintendo.nex.health Provides a client and server for the `HealthProtocol`. This page was generated automatically from `health.proto`. **class** [HealthClient](#healthclient)
The client for the `HealthProtocol`. **class** [HealthServer](#healthserver)
The server for the `HealthProtocol`. ## HealthClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`HealthClient`](#healthclient). **async def ping_daemon**() -> bool
Calls method `1` on the server. **async def ping_database**() -> bool
Calls method `2` on the server. **async def run_sanity_check**() -> bool
Calls method `3` on the server. **async def fix_sanity_errors**() -> bool
Calls method `4` on the server. ## HealthServer **def _\_init__**()
Creates a new [`HealthServer`](#healthserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def ping_daemon**(client: [RMCClient](rmc.md#rmcclient)) -> bool
Handler for method `1`. This method should be overridden by a subclass. **async def ping_database**(client: [RMCClient](rmc.md#rmcclient)) -> bool
Handler for method `2`. This method should be overridden by a subclass. **async def run_sanity_check**(client: [RMCClient](rmc.md#rmcclient)) -> bool
Handler for method `3`. This method should be overridden by a subclass. **async def fix_sanity_errors**(client: [RMCClient](rmc.md#rmcclient)) -> bool
Handler for method `4`. This method should be overridden by a subclass. ================================================ FILE: docs/reference/nex/hpp.md ================================================ # Module: nintendo.nex.hpp Provides a client that performs remote method calls through HTTP. **class** [HppClient](#hppclient)
The HTTP RMC client. ## HppClient **def _\_init__**(settings: [Settings](settings.md#settings), game_server_id: int, nex_version: str, pid: int, password: str)
Creates a new `hpp` client. **def set_environment**(env: str) -> None
Changes the environment. The default is `"L1"` (production).
**async def request**(protocol: int, method: int, body: bytes) -> bytes
Performs a remote method call. Blocks until the RMC is complete. Returns the body of the RMC response on success. Raises [`RMCError`](common.md#rmcerror) if the server returns an error code. ================================================ FILE: docs/reference/nex/kerberos.md ================================================ # Module: nintendo.nex.kerberos Provides classes for Kerberos authentication. For details, click [here](https://github.com/kinnay/nintendo/wiki/Kerberos-Authentication). **class** [KeyDerivationOld](#keyderivationold)
Implements the old key derivation method (used by 3DS and Wii U servers). **class** [KeyDerivationNew](#keyderivationnew)
Implements the new key derivation method (used by Switch servers). **class** [KerberosEncryption](#kerberosencryption)
Implements Kerberos encryption (RC4 + HMAC). **class** [ClientTicket](#clientticket)
The Kerberos ticket that's visible to the client. **class** [ServerTicket](#serverticket)
The internal part of the Kerberos ticket that's only visible to the server. **class** [Credentials](#credentials)
Holds information that's required to log in on a secure server. ## KeyDerivationOld **def _\_init__**(base_count: int = 65000, pid_count: int = 1024)
Creates a new key derivation instance. **def derive_key**(password: bytes, pid: int) -> bytes
Derives the Kerberos key from the given password and user id. ## KeyDerivationNew **def _\_init__**(base_count: int = 1, pid_count: int = 1)
Creates a new key derivation instance. **def derive_key**(password: bytes, pid: int) -> bytes
Derives the Kerberos key from the given password and user id. ## KerberosEncryption **def _\_init__**(key: bytes)
Creates a `KerberosEncryption` instance. **def check**(data: bytes) -> bool
Checks the HMAC. Returns `True` if it is correct. **def decrypt**(data: bytes) -> bytes
Checks the HMAC and decrypts the given data. Raises `ValueError` if the HMAC is incorrect. **def encrypt**(data: bytes) -> bytes
Encrypts the given data and adds a HMAC. ## ClientTicket `session_key: bytes = None`
The session key of the ticket.
`target: int = None`
The target user id of the ticket.
`internal: bytes = None`
The internal ticket data that can only be decrypted by the target user.
**def _\_init__**()
Creates a new [`ClientTicket`](#clientticket) instance. The attributes must be filled in manually. **def encrypt**(key: bytes, settings: [Settings](settings.md#settings)) -> bytes
Encodes the ticket and encrypts it with the given Kerberos key. @classmethod
**def decrypt**(data: bytes, key: bytes, settings: [Settings](settings.md#settings)) -> [`ClientTicket`](#clientticket)
Decrypts `data` with the given Kerberos key and parses the ticket. ## ServerTicket timestamp: [DateTime](common.md#datetime) = None
Time at which the ticket was issued.
`source: int = None`
The source user id of the ticket.
`session_key: bytes = None`
The session key of the ticket.
**def _\_init__**()
Creates a new [`ServerTicket`](#serverticket) instance. The attributes must be filled in manually. **def encrypt**(key: bytes, settings: [Settings](settings.md#settings)) -> bytes
Encodes the ticket and encrypts it with the given Kerberos key. @classmethod
**def decrypt**(data: bytes, key: bytes, settings: [Settings](settings.md#settings)) -> [`ServerTicket`](#serverticket)
Decrypts `data` with the given Kerberos key and parses the ticket. ## Credentials ticket: [ClientTicket](#clientticket)
The ticket received from the authentication server.
`pid: int`
The source user id of the ticket.
`cid: int`
The connection id.
**def _\_init__**(ticket: [ClientTicket](#clientticket), pid: int, cid: int)
Creates a new [`Credentials`](#credentials) object from the given ticket, user id and connection id. ================================================ FILE: docs/reference/nex/matchmaking.md ================================================ # Module: nintendo.nex.matchmaking Provides a client and server for the `MatchMakingProtocol`, `MatchMakingProtocolExt`, `MatchmakeExtensionProtocol` and `MatchmakeRefereeProtocol`. This page was generated automatically from `matchmaking.proto`. **class** [MatchMakingClient](#matchmakingclient)
The client for the `MatchMakingProtocol`. **class** [MatchMakingClientExt](#matchmakingclientext)
The client for the `MatchMakingProtocolExt`. **class** [MatchmakeExtensionClient](#matchmakeextensionclient)
The client for the `MatchmakeExtensionProtocol`. **class** [MatchmakeRefereeClient](#matchmakerefereeclient)
The client for the `MatchmakeRefereeProtocol`. **class** [MatchMakingServer](#matchmakingserver)
The server for the `MatchMakingProtocol`. **class** [MatchMakingServerExt](#matchmakingserverext)
The server for the `MatchMakingProtocolExt`. **class** [MatchmakeExtensionServer](#matchmakeextensionserver)
The server for the `MatchmakeExtensionProtocol`. **class** [MatchmakeRefereeServer](#matchmakerefereeserver)
The server for the `MatchmakeRefereeProtocol`. **class** [MatchmakeSystem](#matchmakesystem)
**class** [AutoMatchmakeParam](#automatchmakeparam)([Structure](common.md))
**class** [CreateMatchmakeSessionParam](#creatematchmakesessionparam)([Structure](common.md))
**class** [DeletionEntry](#deletionentry)([Structure](common.md))
**class** [FindMatchmakeSessionByParticipantParam](#findmatchmakesessionbyparticipantparam)([Structure](common.md))
**class** [FindMatchmakeSessionByParticipantResult](#findmatchmakesessionbyparticipantresult)([Structure](common.md))
**class** [Gathering](#gathering)([Structure](common.md))
**class** [GatheringStats](#gatheringstats)([Structure](common.md))
**class** [GatheringURLs](#gatheringurls)([Structure](common.md))
**class** [Invitation](#invitation)([Structure](common.md))
**class** [JoinMatchmakeSessionParam](#joinmatchmakesessionparam)([Structure](common.md))
**class** [MatchmakeBlockListParam](#matchmakeblocklistparam)([Structure](common.md))
**class** [MatchmakeParam](#matchmakeparam)([Structure](common.md))
**class** [MatchmakeRefereeEndRoundParam](#matchmakerefereeendroundparam)([Structure](common.md))
**class** [MatchmakeRefereePersonalRoundResult](#matchmakerefereepersonalroundresult)([Structure](common.md))
**class** [MatchmakeRefereeRound](#matchmakerefereeround)([Structure](common.md))
**class** [MatchmakeRefereeStartRoundParam](#matchmakerefereestartroundparam)([Structure](common.md))
**class** [MatchmakeRefereeStats](#matchmakerefereestats)([Structure](common.md))
**class** [MatchmakeRefereeStatsInitParam](#matchmakerefereestatsinitparam)([Structure](common.md))
**class** [MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)([Structure](common.md))
**class** [MatchmakeSession](#matchmakesession)([Gathering](#gathering))
**class** [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)([Structure](common.md))
**class** [ParticipantDetails](#participantdetails)([Structure](common.md))
**class** [PersistentGathering](#persistentgathering)([Gathering](#gathering))
**class** [PlayingSession](#playingsession)([Structure](common.md))
**class** [SimpleCommunity](#simplecommunity)([Structure](common.md))
**class** [SimplePlayingSession](#simpleplayingsession)([Structure](common.md))
**class** [UpdateMatchmakeSessionParam](#updatematchmakesessionparam)([Structure](common.md))
## MatchMakingClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`MatchMakingClient`](#matchmakingclient). **async def register_gathering**(gathering: [Gathering](#gathering)) -> int
Calls method `1` on the server. **async def unregister_gathering**(gid: int) -> bool
Calls method `2` on the server. **async def unregister_gatherings**(gids: list[int]) -> bool
Calls method `3` on the server. **async def update_gathering**(gathering: [Gathering](#gathering)) -> bool
Calls method `4` on the server. **async def invite**(gid: int, pids: list[int], message: str) -> bool
Calls method `5` on the server. **async def accept_invitation**(gid: int, message: str) -> bool
Calls method `6` on the server. **async def decline_invitation**(gid: int, message: str) -> bool
Calls method `7` on the server. **async def cancel_invitation**(gid: int, pids: list[int], message: str) -> bool
Calls method `8` on the server. **async def get_invitations_sent**(gid: int) -> list[[Invitation](#invitation)]
Calls method `9` on the server. **async def get_invitations_received**() -> list[[Invitation](#invitation)]
Calls method `10` on the server. **async def participate**(gid: int, message: str) -> bool
Calls method `11` on the server. **async def cancel_participation**(gid: int, message: str) -> bool
Calls method `12` on the server. **async def get_participants**(gid: int) -> list[int]
Calls method `13` on the server. **async def add_participants**(gid: int, pids: list[int], message: str) -> bool
Calls method `14` on the server. **async def get_detailed_participants**(gid: int) -> list[[ParticipantDetails](#participantdetails)]
Calls method `15` on the server. **async def get_participants_urls**(gid: int) -> list[[StationURL](common.md#stationurl)]
Calls method `16` on the server. **async def find_by_type**(type: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `17` on the server. **async def find_by_description**(description: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `18` on the server. **async def find_by_description_regex**(regex: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `19` on the server. **async def find_by_id**(ids: list[int]) -> list[[Gathering](#gathering)]
Calls method `20` on the server. **async def find_by_single_id**(gid: int) -> [RMCResponse](common.md)
Calls method `21` on the server. The RMC response has the following attributes:
result: bool
gathering: [Gathering](#gathering)
**async def find_by_owner**(owner: int, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `22` on the server. **async def find_by_participants**(pids: list[int]) -> list[[Gathering](#gathering)]
Calls method `23` on the server. **async def find_invitations**(range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `24` on the server. **async def find_by_sql_query**(query: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `25` on the server. **async def launch_session**(gid: int, url: str) -> bool
Calls method `26` on the server. **async def update_session_url**(gid: int, url: str) -> bool
Calls method `27` on the server. **async def get_session_url**(gid: int) -> [RMCResponse](common.md)
Calls method `28` on the server. The RMC response has the following attributes:
result: bool
url: str
**async def get_state**(gid: int) -> [RMCResponse](common.md)
Calls method `29` on the server. The RMC response has the following attributes:
result: bool
state: int
**async def set_state**(gid: int, state: int) -> bool
Calls method `30` on the server. **async def report_stats**(gid: int, stats: list[[GatheringStats](#gatheringstats)]) -> bool
Calls method `31` on the server. **async def get_stats**(gid: int, pids: list[int], columns: list[int]) -> [RMCResponse](common.md)
Calls method `32` on the server. The RMC response has the following attributes:
result: bool
stats: list[[GatheringStats](#gatheringstats)]
**async def delete_gathering**(gid: int) -> bool
Calls method `33` on the server. **async def get_pending_deletions**(reason: int, range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Calls method `34` on the server. The RMC response has the following attributes:
result: bool
deletions: list[[DeletionEntry](#deletionentry)]
**async def delete_from_deletions**(deletions: list[int]) -> bool
Calls method `35` on the server. **async def migrate_gathering_ownership_v1**(gid: int, potential_owners: list[int]) -> bool
Calls method `36` on the server. **async def find_by_description_like**(description: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `37` on the server. **async def register_local_url**(gid: int, url: [StationURL](common.md#stationurl)) -> None
Calls method `38` on the server. **async def register_local_urls**(gid: int, urls: list[[StationURL](common.md#stationurl)]) -> None
Calls method `39` on the server. **async def update_session_host_v1**(gid: int) -> None
Calls method `40` on the server. **async def get_session_urls**(gid: int) -> list[[StationURL](common.md#stationurl)]
Calls method `41` on the server. **async def update_session_host**(gid: int, is_migrate_owner: bool) -> None
Calls method `42` on the server. **async def update_gathering_ownership**(gid: int, participants_only: bool) -> bool
Calls method `43` on the server. **async def migrate_gathering_ownership**(gid: int, potential_owners: list[int], participants_only: bool) -> None
Calls method `44` on the server. ## MatchMakingClientExt **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`MatchMakingClientExt`](#matchmakingclientext). **async def end_participation**(gid: int, message: str) -> bool
Calls method `1` on the server. **async def get_participants**(gid: int, only_active: bool) -> list[int]
Calls method `2` on the server. **async def get_detailed_participants**(gid: int, only_active: bool) -> list[[ParticipantDetails](#participantdetails)]
Calls method `3` on the server. **async def get_participants_urls**(gids: list[int]) -> list[[GatheringURLs](#gatheringurls)]
Calls method `4` on the server. **async def get_gathering_relations**(id: int, descr: str) -> str
Calls method `5` on the server. **async def delete_from_deletions**(deletions: list[int], pid: int) -> None
Calls method `6` on the server. ## MatchmakeExtensionClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`MatchmakeExtensionClient`](#matchmakeextensionclient). **async def close_participation**(gid: int) -> None
Calls method `1` on the server. **async def open_participation**(gid: int) -> None
Calls method `2` on the server. **async def auto_matchmake_postpone**(gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Calls method `3` on the server. **async def browse_matchmake_session**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `4` on the server. **async def browse_matchmake_session_with_host_urls**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Calls method `5` on the server. The RMC response has the following attributes:
gatherings: list[[Gathering](#gathering)]
urls: list[[GatheringURLs](#gatheringurls)]
**async def create_matchmake_session**(gathering: [Gathering](#gathering), description: str, num_participants: int) -> [RMCResponse](common.md)
Calls method `6` on the server. The RMC response has the following attributes:
gid: int
session_key: bytes
**async def join_matchmake_session**(gid: int, message: str) -> bytes
Calls method `7` on the server. **async def modify_current_game_attribute**(gid: int, attrib: int, value: int) -> None
Calls method `8` on the server. **async def update_notification_data**(type: int, param1: int, param2: int, param3: str) -> None
Calls method `9` on the server. **async def get_friend_notification_data**(type: int) -> list[[NotificationEvent](notification.md#notificationevent)]
Calls method `10` on the server. **async def update_application_buffer**(gid: int, buffer: bytes) -> None
Calls method `11` on the server. **async def update_matchmake_session_attribute**(gid: int, attribs: list[int]) -> None
Calls method `12` on the server. **async def get_friend_notification_data_list**(types: list[int]) -> list[[NotificationEvent](notification.md#notificationevent)]
Calls method `13` on the server. **async def update_matchmake_session**(gathering: [Gathering](#gathering)) -> None
Calls method `14` on the server. **async def auto_matchmake_with_search_criteria_postpone**(search_criteria: list[[MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)], gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Calls method `15` on the server. **async def get_playing_session**(pids: list[int]) -> list[[PlayingSession](#playingsession)]
Calls method `16` on the server. **async def create_community**(community: [PersistentGathering](#persistentgathering), message: str) -> int
Calls method `17` on the server. **async def update_community**(community: [PersistentGathering](#persistentgathering)) -> None
Calls method `18` on the server. **async def join_community**(gid: int, message: str, password: str) -> None
Calls method `19` on the server. **async def find_community_by_gathering_id**(gids: list[int]) -> list[[PersistentGathering](#persistentgathering)]
Calls method `20` on the server. **async def find_official_community**(available_only: bool, range: [ResultRange](common.md#resultrange)) -> list[[PersistentGathering](#persistentgathering)]
Calls method `21` on the server. **async def find_community_by_participant**(pid: int, range: [ResultRange](common.md#resultrange)) -> list[[PersistentGathering](#persistentgathering)]
Calls method `22` on the server. **async def update_privacy_setting**(online_status: bool, community_participation: bool) -> None
Calls method `23` on the server. **async def get_my_block_list**() -> list[int]
Calls method `24` on the server. **async def add_to_block_list**(pids: list[int]) -> None
Calls method `25` on the server. **async def remove_from_block_list**(pids: list[int]) -> None
Calls method `26` on the server. **async def clear_my_block_list**() -> None
Calls method `27` on the server. **async def report_violation**(pid: int, username: str, violation_code: int) -> None
Calls method `28` on the server. **async def is_violation_user**() -> [RMCResponse](common.md)
Calls method `29` on the server. The RMC response has the following attributes:
flag: bool
score: int
**async def join_matchmake_session_ex**(gid: int, gmessage: str, ignore_block_list: bool, num_participants: int) -> bytes
Calls method `30` on the server. **async def get_simple_playing_session**(pids: list[int], include_login_user: bool) -> list[[SimplePlayingSession](#simpleplayingsession)]
Calls method `31` on the server. **async def get_simple_community**(gids: list[int]) -> list[[SimpleCommunity](#simplecommunity)]
Calls method `32` on the server. **async def auto_matchmake_with_gathering_id_postpone**(gids: list[int], gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Calls method `33` on the server. **async def update_progress_score**(gid: int, score: int) -> None
Calls method `34` on the server. **async def debug_notify_event**(pid: int, main_type: int, sub_type: int, param1: int, param2: int, param3: str) -> None
Calls method `35` on the server. **async def generate_matchmake_session_system_password**(gid: int) -> str
Calls method `36` on the server. **async def clear_matchmake_session_system_password**(gid: int) -> None
Calls method `37` on the server. **async def create_matchmake_session_with_param**(param: [CreateMatchmakeSessionParam](#creatematchmakesessionparam)) -> [MatchmakeSession](#matchmakesession)
Calls method `38` on the server. **async def join_matchmake_session_with_param**(param: [JoinMatchmakeSessionParam](#joinmatchmakesessionparam)) -> [MatchmakeSession](#matchmakesession)
Calls method `39` on the server. **async def auto_matchmake_with_param_postpone**(param: [AutoMatchmakeParam](#automatchmakeparam)) -> [MatchmakeSession](#matchmakesession)
Calls method `40` on the server. **async def find_matchmake_session_by_gathering_id_detail**(gid: int) -> [MatchmakeSession](#matchmakesession)
Calls method `41` on the server. **async def browse_matchmake_session_no_holder**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> list[[MatchmakeSession](#matchmakesession)]
Calls method `42` on the server. **async def browse_matchmake_session_with_host_urls_no_holder**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Calls method `43` on the server. The RMC response has the following attributes:
sessions: list[[MatchmakeSession](#matchmakesession)]
urls: list[[GatheringURLs](#gatheringurls)]
**async def update_matchmake_session_part**(param: [UpdateMatchmakeSessionParam](#updatematchmakesessionparam)) -> None
Calls method `44` on the server. **async def request_matchmaking**(param: [AutoMatchmakeParam](#automatchmakeparam)) -> int
Calls method `45` on the server. **async def withdraw_matchmaking**(request_id: int) -> None
Calls method `46` on the server. **async def withdraw_matchmaking_all**() -> None
Calls method `47` on the server. **async def find_matchmake_session_by_gathering_id**(gids: list[int]) -> list[[MatchmakeSession](#matchmakesession)]
Calls method `48` on the server. **async def find_matchmake_session_by_single_gathering_id**(gid: int) -> [MatchmakeSession](#matchmakesession)
Calls method `49` on the server. **async def find_matchmake_session_by_owner**(pid: int, range: [ResultRange](common.md#resultrange)) -> list[[MatchmakeSession](#matchmakesession)]
Calls method `50` on the server. **async def find_matchmake_session_by_participant**(param: [FindMatchmakeSessionByParticipantParam](#findmatchmakesessionbyparticipantparam)) -> list[[FindMatchmakeSessionByParticipantResult](#findmatchmakesessionbyparticipantresult)]
Calls method `51` on the server. **async def browse_matchmake_session_no_holder_no_result_range**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)) -> list[[MatchmakeSession](#matchmakesession)]
Calls method `52` on the server. **async def browse_matchmake_session_with_host_urls_no_holder_no_result_range**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)) -> [RMCResponse](common.md)
Calls method `53` on the server. The RMC response has the following attributes:
sessions: list[[MatchmakeSession](#matchmakesession)]
urls: list[[GatheringURLs](#gatheringurls)]
## MatchmakeRefereeClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`MatchmakeRefereeClient`](#matchmakerefereeclient). **async def start_round**(param: [MatchmakeRefereeStartRoundParam](#matchmakerefereestartroundparam)) -> int
Calls method `1` on the server. **async def get_start_round_param**(round_id: int) -> [MatchmakeRefereeStartRoundParam](#matchmakerefereestartroundparam)
Calls method `2` on the server. **async def end_round**(param: [MatchmakeRefereeEndRoundParam](#matchmakerefereeendroundparam)) -> None
Calls method `3` on the server. **async def end_round_without_report**(round_id: int) -> None
Calls method `4` on the server. **async def get_round_participants**(round_id: int) -> list[int]
Calls method `5` on the server. **async def get_not_summarized_round**() -> list[[MatchmakeRefereeRound](#matchmakerefereeround)]
Calls method `6` on the server. **async def get_round**(round: int) -> [MatchmakeRefereeRound](#matchmakerefereeround)
Calls method `7` on the server. **async def get_stats_primary**(target: [MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Calls method `8` on the server. **async def get_stats_primaries**(targets: list[[MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)]) -> [RMCResponse](common.md)
Calls method `9` on the server. The RMC response has the following attributes:
stats: list[[MatchmakeRefereeStats](#matchmakerefereestats)]
results: list[[Result](common.md#result)]
**async def get_stats_all**(target: [MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)) -> list[[MatchmakeRefereeStats](#matchmakerefereestats)]
Calls method `10` on the server. **async def create_stats**(param: [MatchmakeRefereeStatsInitParam](#matchmakerefereestatsinitparam)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Calls method `11` on the server. **async def get_or_create_stats**(param: [MatchmakeRefereeStatsInitParam](#matchmakerefereestatsinitparam)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Calls method `12` on the server. **async def reset_stats**() -> None
Calls method `13` on the server. ## MatchMakingServer **def _\_init__**()
Creates a new [`MatchMakingServer`](#matchmakingserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def register_gathering**(client: [RMCClient](rmc.md#rmcclient), gathering: [Gathering](#gathering)) -> int
Handler for method `1`. This method should be overridden by a subclass. **async def unregister_gathering**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> bool
Handler for method `2`. This method should be overridden by a subclass. **async def unregister_gatherings**(client: [RMCClient](rmc.md#rmcclient), gids: list[int]) -> bool
Handler for method `3`. This method should be overridden by a subclass. **async def update_gathering**(client: [RMCClient](rmc.md#rmcclient), gathering: [Gathering](#gathering)) -> bool
Handler for method `4`. This method should be overridden by a subclass. **async def invite**(client: [RMCClient](rmc.md#rmcclient), gid: int, pids: list[int], message: str) -> bool
Handler for method `5`. This method should be overridden by a subclass. **async def accept_invitation**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bool
Handler for method `6`. This method should be overridden by a subclass. **async def decline_invitation**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bool
Handler for method `7`. This method should be overridden by a subclass. **async def cancel_invitation**(client: [RMCClient](rmc.md#rmcclient), gid: int, pids: list[int], message: str) -> bool
Handler for method `8`. This method should be overridden by a subclass. **async def get_invitations_sent**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> list[[Invitation](#invitation)]
Handler for method `9`. This method should be overridden by a subclass. **async def get_invitations_received**(client: [RMCClient](rmc.md#rmcclient)) -> list[[Invitation](#invitation)]
Handler for method `10`. This method should be overridden by a subclass. **async def participate**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bool
Handler for method `11`. This method should be overridden by a subclass. **async def cancel_participation**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bool
Handler for method `12`. This method should be overridden by a subclass. **async def get_participants**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> list[int]
Handler for method `13`. This method should be overridden by a subclass. **async def add_participants**(client: [RMCClient](rmc.md#rmcclient), gid: int, pids: list[int], message: str) -> bool
Handler for method `14`. This method should be overridden by a subclass. **async def get_detailed_participants**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> list[[ParticipantDetails](#participantdetails)]
Handler for method `15`. This method should be overridden by a subclass. **async def get_participants_urls**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> list[[StationURL](common.md#stationurl)]
Handler for method `16`. This method should be overridden by a subclass. **async def find_by_type**(client: [RMCClient](rmc.md#rmcclient), type: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `17`. This method should be overridden by a subclass. **async def find_by_description**(client: [RMCClient](rmc.md#rmcclient), description: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `18`. This method should be overridden by a subclass. **async def find_by_description_regex**(client: [RMCClient](rmc.md#rmcclient), regex: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `19`. This method should be overridden by a subclass. **async def find_by_id**(client: [RMCClient](rmc.md#rmcclient), ids: list[int]) -> list[[Gathering](#gathering)]
Handler for method `20`. This method should be overridden by a subclass. **async def find_by_single_id**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> [RMCResponse](common.md)
Handler for method `21`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
gathering: [Gathering](#gathering)
**async def find_by_owner**(client: [RMCClient](rmc.md#rmcclient), owner: int, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `22`. This method should be overridden by a subclass. **async def find_by_participants**(client: [RMCClient](rmc.md#rmcclient), pids: list[int]) -> list[[Gathering](#gathering)]
Handler for method `23`. This method should be overridden by a subclass. **async def find_invitations**(client: [RMCClient](rmc.md#rmcclient), range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `24`. This method should be overridden by a subclass. **async def find_by_sql_query**(client: [RMCClient](rmc.md#rmcclient), query: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `25`. This method should be overridden by a subclass. **async def launch_session**(client: [RMCClient](rmc.md#rmcclient), gid: int, url: str) -> bool
Handler for method `26`. This method should be overridden by a subclass. **async def update_session_url**(client: [RMCClient](rmc.md#rmcclient), gid: int, url: str) -> bool
Handler for method `27`. This method should be overridden by a subclass. **async def get_session_url**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> [RMCResponse](common.md)
Handler for method `28`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
url: str
**async def get_state**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> [RMCResponse](common.md)
Handler for method `29`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
state: int
**async def set_state**(client: [RMCClient](rmc.md#rmcclient), gid: int, state: int) -> bool
Handler for method `30`. This method should be overridden by a subclass. **async def report_stats**(client: [RMCClient](rmc.md#rmcclient), gid: int, stats: list[[GatheringStats](#gatheringstats)]) -> bool
Handler for method `31`. This method should be overridden by a subclass. **async def get_stats**(client: [RMCClient](rmc.md#rmcclient), gid: int, pids: list[int], columns: list[int]) -> [RMCResponse](common.md)
Handler for method `32`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
stats: list[[GatheringStats](#gatheringstats)]
**async def delete_gathering**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> bool
Handler for method `33`. This method should be overridden by a subclass. **async def get_pending_deletions**(client: [RMCClient](rmc.md#rmcclient), reason: int, range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Handler for method `34`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
deletions: list[[DeletionEntry](#deletionentry)]
**async def delete_from_deletions**(client: [RMCClient](rmc.md#rmcclient), deletions: list[int]) -> bool
Handler for method `35`. This method should be overridden by a subclass. **async def migrate_gathering_ownership_v1**(client: [RMCClient](rmc.md#rmcclient), gid: int, potential_owners: list[int]) -> bool
Handler for method `36`. This method should be overridden by a subclass. **async def find_by_description_like**(client: [RMCClient](rmc.md#rmcclient), description: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `37`. This method should be overridden by a subclass. **async def register_local_url**(client: [RMCClient](rmc.md#rmcclient), gid: int, url: [StationURL](common.md#stationurl)) -> None
Handler for method `38`. This method should be overridden by a subclass. **async def register_local_urls**(client: [RMCClient](rmc.md#rmcclient), gid: int, urls: list[[StationURL](common.md#stationurl)]) -> None
Handler for method `39`. This method should be overridden by a subclass. **async def update_session_host_v1**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> None
Handler for method `40`. This method should be overridden by a subclass. **async def get_session_urls**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> list[[StationURL](common.md#stationurl)]
Handler for method `41`. This method should be overridden by a subclass. **async def update_session_host**(client: [RMCClient](rmc.md#rmcclient), gid: int, is_migrate_owner: bool) -> None
Handler for method `42`. This method should be overridden by a subclass. **async def update_gathering_ownership**(client: [RMCClient](rmc.md#rmcclient), gid: int, participants_only: bool) -> bool
Handler for method `43`. This method should be overridden by a subclass. **async def migrate_gathering_ownership**(client: [RMCClient](rmc.md#rmcclient), gid: int, potential_owners: list[int], participants_only: bool) -> None
Handler for method `44`. This method should be overridden by a subclass. ## MatchMakingServerExt **def _\_init__**()
Creates a new [`MatchMakingServerExt`](#matchmakingserverext). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def end_participation**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bool
Handler for method `1`. This method should be overridden by a subclass. **async def get_participants**(client: [RMCClient](rmc.md#rmcclient), gid: int, only_active: bool) -> list[int]
Handler for method `2`. This method should be overridden by a subclass. **async def get_detailed_participants**(client: [RMCClient](rmc.md#rmcclient), gid: int, only_active: bool) -> list[[ParticipantDetails](#participantdetails)]
Handler for method `3`. This method should be overridden by a subclass. **async def get_participants_urls**(client: [RMCClient](rmc.md#rmcclient), gids: list[int]) -> list[[GatheringURLs](#gatheringurls)]
Handler for method `4`. This method should be overridden by a subclass. **async def get_gathering_relations**(client: [RMCClient](rmc.md#rmcclient), id: int, descr: str) -> str
Handler for method `5`. This method should be overridden by a subclass. **async def delete_from_deletions**(client: [RMCClient](rmc.md#rmcclient), deletions: list[int], pid: int) -> None
Handler for method `6`. This method should be overridden by a subclass. ## MatchmakeExtensionServer **def _\_init__**()
Creates a new [`MatchmakeExtensionServer`](#matchmakeextensionserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def close_participation**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> None
Handler for method `1`. This method should be overridden by a subclass. **async def open_participation**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> None
Handler for method `2`. This method should be overridden by a subclass. **async def auto_matchmake_postpone**(client: [RMCClient](rmc.md#rmcclient), gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Handler for method `3`. This method should be overridden by a subclass. **async def browse_matchmake_session**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `4`. This method should be overridden by a subclass. **async def browse_matchmake_session_with_host_urls**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Handler for method `5`. This method should be overridden by a subclass. The RMC response must have the following attributes:
gatherings: list[[Gathering](#gathering)]
urls: list[[GatheringURLs](#gatheringurls)]
**async def create_matchmake_session**(client: [RMCClient](rmc.md#rmcclient), gathering: [Gathering](#gathering), description: str, num_participants: int) -> [RMCResponse](common.md)
Handler for method `6`. This method should be overridden by a subclass. The RMC response must have the following attributes:
gid: int
session_key: bytes
**async def join_matchmake_session**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bytes
Handler for method `7`. This method should be overridden by a subclass. **async def modify_current_game_attribute**(client: [RMCClient](rmc.md#rmcclient), gid: int, attrib: int, value: int) -> None
Handler for method `8`. This method should be overridden by a subclass. **async def update_notification_data**(client: [RMCClient](rmc.md#rmcclient), type: int, param1: int, param2: int, param3: str) -> None
Handler for method `9`. This method should be overridden by a subclass. **async def get_friend_notification_data**(client: [RMCClient](rmc.md#rmcclient), type: int) -> list[[NotificationEvent](notification.md#notificationevent)]
Handler for method `10`. This method should be overridden by a subclass. **async def update_application_buffer**(client: [RMCClient](rmc.md#rmcclient), gid: int, buffer: bytes) -> None
Handler for method `11`. This method should be overridden by a subclass. **async def update_matchmake_session_attribute**(client: [RMCClient](rmc.md#rmcclient), gid: int, attribs: list[int]) -> None
Handler for method `12`. This method should be overridden by a subclass. **async def get_friend_notification_data_list**(client: [RMCClient](rmc.md#rmcclient), types: list[int]) -> list[[NotificationEvent](notification.md#notificationevent)]
Handler for method `13`. This method should be overridden by a subclass. **async def update_matchmake_session**(client: [RMCClient](rmc.md#rmcclient), gathering: [Gathering](#gathering)) -> None
Handler for method `14`. This method should be overridden by a subclass. **async def auto_matchmake_with_search_criteria_postpone**(client: [RMCClient](rmc.md#rmcclient), search_criteria: list[[MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)], gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Handler for method `15`. This method should be overridden by a subclass. **async def get_playing_session**(client: [RMCClient](rmc.md#rmcclient), pids: list[int]) -> list[[PlayingSession](#playingsession)]
Handler for method `16`. This method should be overridden by a subclass. **async def create_community**(client: [RMCClient](rmc.md#rmcclient), community: [PersistentGathering](#persistentgathering), message: str) -> int
Handler for method `17`. This method should be overridden by a subclass. **async def update_community**(client: [RMCClient](rmc.md#rmcclient), community: [PersistentGathering](#persistentgathering)) -> None
Handler for method `18`. This method should be overridden by a subclass. **async def join_community**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str, password: str) -> None
Handler for method `19`. This method should be overridden by a subclass. **async def find_community_by_gathering_id**(client: [RMCClient](rmc.md#rmcclient), gids: list[int]) -> list[[PersistentGathering](#persistentgathering)]
Handler for method `20`. This method should be overridden by a subclass. **async def find_official_community**(client: [RMCClient](rmc.md#rmcclient), available_only: bool, range: [ResultRange](common.md#resultrange)) -> list[[PersistentGathering](#persistentgathering)]
Handler for method `21`. This method should be overridden by a subclass. **async def find_community_by_participant**(client: [RMCClient](rmc.md#rmcclient), pid: int, range: [ResultRange](common.md#resultrange)) -> list[[PersistentGathering](#persistentgathering)]
Handler for method `22`. This method should be overridden by a subclass. **async def update_privacy_setting**(client: [RMCClient](rmc.md#rmcclient), online_status: bool, community_participation: bool) -> None
Handler for method `23`. This method should be overridden by a subclass. **async def get_my_block_list**(client: [RMCClient](rmc.md#rmcclient)) -> list[int]
Handler for method `24`. This method should be overridden by a subclass. **async def add_to_block_list**(client: [RMCClient](rmc.md#rmcclient), pids: list[int]) -> None
Handler for method `25`. This method should be overridden by a subclass. **async def remove_from_block_list**(client: [RMCClient](rmc.md#rmcclient), pids: list[int]) -> None
Handler for method `26`. This method should be overridden by a subclass. **async def clear_my_block_list**(client: [RMCClient](rmc.md#rmcclient)) -> None
Handler for method `27`. This method should be overridden by a subclass. **async def report_violation**(client: [RMCClient](rmc.md#rmcclient), pid: int, username: str, violation_code: int) -> None
Handler for method `28`. This method should be overridden by a subclass. **async def is_violation_user**(client: [RMCClient](rmc.md#rmcclient)) -> [RMCResponse](common.md)
Handler for method `29`. This method should be overridden by a subclass. The RMC response must have the following attributes:
flag: bool
score: int
**async def join_matchmake_session_ex**(client: [RMCClient](rmc.md#rmcclient), gid: int, gmessage: str, ignore_block_list: bool, num_participants: int) -> bytes
Handler for method `30`. This method should be overridden by a subclass. **async def get_simple_playing_session**(client: [RMCClient](rmc.md#rmcclient), pids: list[int], include_login_user: bool) -> list[[SimplePlayingSession](#simpleplayingsession)]
Handler for method `31`. This method should be overridden by a subclass. **async def get_simple_community**(client: [RMCClient](rmc.md#rmcclient), gids: list[int]) -> list[[SimpleCommunity](#simplecommunity)]
Handler for method `32`. This method should be overridden by a subclass. **async def auto_matchmake_with_gathering_id_postpone**(client: [RMCClient](rmc.md#rmcclient), gids: list[int], gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Handler for method `33`. This method should be overridden by a subclass. **async def update_progress_score**(client: [RMCClient](rmc.md#rmcclient), gid: int, score: int) -> None
Handler for method `34`. This method should be overridden by a subclass. **async def debug_notify_event**(client: [RMCClient](rmc.md#rmcclient), pid: int, main_type: int, sub_type: int, param1: int, param2: int, param3: str) -> None
Handler for method `35`. This method should be overridden by a subclass. **async def generate_matchmake_session_system_password**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> str
Handler for method `36`. This method should be overridden by a subclass. **async def clear_matchmake_session_system_password**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> None
Handler for method `37`. This method should be overridden by a subclass. **async def create_matchmake_session_with_param**(client: [RMCClient](rmc.md#rmcclient), param: [CreateMatchmakeSessionParam](#creatematchmakesessionparam)) -> [MatchmakeSession](#matchmakesession)
Handler for method `38`. This method should be overridden by a subclass. **async def join_matchmake_session_with_param**(client: [RMCClient](rmc.md#rmcclient), param: [JoinMatchmakeSessionParam](#joinmatchmakesessionparam)) -> [MatchmakeSession](#matchmakesession)
Handler for method `39`. This method should be overridden by a subclass. **async def auto_matchmake_with_param_postpone**(client: [RMCClient](rmc.md#rmcclient), param: [AutoMatchmakeParam](#automatchmakeparam)) -> [MatchmakeSession](#matchmakesession)
Handler for method `40`. This method should be overridden by a subclass. **async def find_matchmake_session_by_gathering_id_detail**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> [MatchmakeSession](#matchmakesession)
Handler for method `41`. This method should be overridden by a subclass. **async def browse_matchmake_session_no_holder**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> list[[MatchmakeSession](#matchmakesession)]
Handler for method `42`. This method should be overridden by a subclass. **async def browse_matchmake_session_with_host_urls_no_holder**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Handler for method `43`. This method should be overridden by a subclass. The RMC response must have the following attributes:
sessions: list[[MatchmakeSession](#matchmakesession)]
urls: list[[GatheringURLs](#gatheringurls)]
**async def update_matchmake_session_part**(client: [RMCClient](rmc.md#rmcclient), param: [UpdateMatchmakeSessionParam](#updatematchmakesessionparam)) -> None
Handler for method `44`. This method should be overridden by a subclass. **async def request_matchmaking**(client: [RMCClient](rmc.md#rmcclient), param: [AutoMatchmakeParam](#automatchmakeparam)) -> int
Handler for method `45`. This method should be overridden by a subclass. **async def withdraw_matchmaking**(client: [RMCClient](rmc.md#rmcclient), request_id: int) -> None
Handler for method `46`. This method should be overridden by a subclass. **async def withdraw_matchmaking_all**(client: [RMCClient](rmc.md#rmcclient)) -> None
Handler for method `47`. This method should be overridden by a subclass. **async def find_matchmake_session_by_gathering_id**(client: [RMCClient](rmc.md#rmcclient), gids: list[int]) -> list[[MatchmakeSession](#matchmakesession)]
Handler for method `48`. This method should be overridden by a subclass. **async def find_matchmake_session_by_single_gathering_id**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> [MatchmakeSession](#matchmakesession)
Handler for method `49`. This method should be overridden by a subclass. **async def find_matchmake_session_by_owner**(client: [RMCClient](rmc.md#rmcclient), pid: int, range: [ResultRange](common.md#resultrange)) -> list[[MatchmakeSession](#matchmakesession)]
Handler for method `50`. This method should be overridden by a subclass. **async def find_matchmake_session_by_participant**(client: [RMCClient](rmc.md#rmcclient), param: [FindMatchmakeSessionByParticipantParam](#findmatchmakesessionbyparticipantparam)) -> list[[FindMatchmakeSessionByParticipantResult](#findmatchmakesessionbyparticipantresult)]
Handler for method `51`. This method should be overridden by a subclass. **async def browse_matchmake_session_no_holder_no_result_range**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)) -> list[[MatchmakeSession](#matchmakesession)]
Handler for method `52`. This method should be overridden by a subclass. **async def browse_matchmake_session_with_host_urls_no_holder_no_result_range**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)) -> [RMCResponse](common.md)
Handler for method `53`. This method should be overridden by a subclass. The RMC response must have the following attributes:
sessions: list[[MatchmakeSession](#matchmakesession)]
urls: list[[GatheringURLs](#gatheringurls)]
## MatchmakeRefereeServer **def _\_init__**()
Creates a new [`MatchmakeRefereeServer`](#matchmakerefereeserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def start_round**(client: [RMCClient](rmc.md#rmcclient), param: [MatchmakeRefereeStartRoundParam](#matchmakerefereestartroundparam)) -> int
Handler for method `1`. This method should be overridden by a subclass. **async def get_start_round_param**(client: [RMCClient](rmc.md#rmcclient), round_id: int) -> [MatchmakeRefereeStartRoundParam](#matchmakerefereestartroundparam)
Handler for method `2`. This method should be overridden by a subclass. **async def end_round**(client: [RMCClient](rmc.md#rmcclient), param: [MatchmakeRefereeEndRoundParam](#matchmakerefereeendroundparam)) -> None
Handler for method `3`. This method should be overridden by a subclass. **async def end_round_without_report**(client: [RMCClient](rmc.md#rmcclient), round_id: int) -> None
Handler for method `4`. This method should be overridden by a subclass. **async def get_round_participants**(client: [RMCClient](rmc.md#rmcclient), round_id: int) -> list[int]
Handler for method `5`. This method should be overridden by a subclass. **async def get_not_summarized_round**(client: [RMCClient](rmc.md#rmcclient)) -> list[[MatchmakeRefereeRound](#matchmakerefereeround)]
Handler for method `6`. This method should be overridden by a subclass. **async def get_round**(client: [RMCClient](rmc.md#rmcclient), round: int) -> [MatchmakeRefereeRound](#matchmakerefereeround)
Handler for method `7`. This method should be overridden by a subclass. **async def get_stats_primary**(client: [RMCClient](rmc.md#rmcclient), target: [MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Handler for method `8`. This method should be overridden by a subclass. **async def get_stats_primaries**(client: [RMCClient](rmc.md#rmcclient), targets: list[[MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)]) -> [RMCResponse](common.md)
Handler for method `9`. This method should be overridden by a subclass. The RMC response must have the following attributes:
stats: list[[MatchmakeRefereeStats](#matchmakerefereestats)]
results: list[[Result](common.md#result)]
**async def get_stats_all**(client: [RMCClient](rmc.md#rmcclient), target: [MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)) -> list[[MatchmakeRefereeStats](#matchmakerefereestats)]
Handler for method `10`. This method should be overridden by a subclass. **async def create_stats**(client: [RMCClient](rmc.md#rmcclient), param: [MatchmakeRefereeStatsInitParam](#matchmakerefereestatsinitparam)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Handler for method `11`. This method should be overridden by a subclass. **async def get_or_create_stats**(client: [RMCClient](rmc.md#rmcclient), param: [MatchmakeRefereeStatsInitParam](#matchmakerefereestatsinitparam)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Handler for method `12`. This method should be overridden by a subclass. **async def reset_stats**(client: [RMCClient](rmc.md#rmcclient)) -> None
Handler for method `13`. This method should be overridden by a subclass. ## MatchmakeSystem This class defines the following constants:
`GLOBAL = 1`
`FRIENDS = 2`
## AutoMatchmakeParam **def _\_init__**()
Creates a new `AutoMatchmakeParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
session: [MatchmakeSession](#matchmakesession) = [MatchmakeSession](#matchmakesession)()
participants: list[int]
gid_for_participation_check: int
options: int
join_message: str
num_participants: int
search_criteria: list[[MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)]
target_gids: list[int]
block_list: [MatchmakeBlockListParam](#matchmakeblocklistparam) = [MatchmakeBlockListParam](#matchmakeblocklistparam)()

## CreateMatchmakeSessionParam **def _\_init__**()
Creates a new `CreateMatchmakeSessionParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
session: [MatchmakeSession](#matchmakesession) = [MatchmakeSession](#matchmakesession)()
additional_participants: list[int]
gid_for_participation_check: int
options: int
join_message: str
num_participants: int

## DeletionEntry **def _\_init__**()
Creates a new `DeletionEntry` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
pid: int
reason: int

## FindMatchmakeSessionByParticipantParam **def _\_init__**()
Creates a new `FindMatchmakeSessionByParticipantParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
pids: list[int]
options: int
block_list: [MatchmakeBlockListParam](#matchmakeblocklistparam) = [MatchmakeBlockListParam](#matchmakeblocklistparam)()

## FindMatchmakeSessionByParticipantResult **def _\_init__**()
Creates a new `FindMatchmakeSessionByParticipantResult` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
session: [MatchmakeSession](#matchmakesession) = [MatchmakeSession](#matchmakesession)()

## Gathering **def _\_init__**()
Creates a new `Gathering` instance. Required fields must be filled in manually. The following fields are defined in this class:
id: int = 0
owner: int = 0
host: int = 0
min_participants: int = 0
max_participants: int = 0
participation_policy: int = 1
policy_argument: int = 0
flags: int = 512
state: int = 0
description: str = ""

## GatheringStats **def _\_init__**()
Creates a new `GatheringStats` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
flags: int
values: list[float]

## GatheringURLs **def _\_init__**()
Creates a new `GatheringURLs` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
urls: list[[StationURL](common.md#stationurl)]

## Invitation **def _\_init__**()
Creates a new `Invitation` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
guest: int
message: str

## JoinMatchmakeSessionParam **def _\_init__**()
Creates a new `JoinMatchmakeSessionParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
participants: list[int]
gid_for_participation_check: int
options: int
behavior: int
user_password: str
system_password: str
join_message: str
num_participants: int
extra_participants: int
block_list: [MatchmakeBlockListParam](#matchmakeblocklistparam) = [MatchmakeBlockListParam](#matchmakeblocklistparam)()

## MatchmakeBlockListParam **def _\_init__**()
Creates a new `MatchmakeBlockListParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
options: int = 0

## MatchmakeParam **def _\_init__**()
Creates a new `MatchmakeParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
param: dict[str, object] = {}

## MatchmakeRefereeEndRoundParam **def _\_init__**()
Creates a new `MatchmakeRefereeEndRoundParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
round_id: int
results: list[[MatchmakeRefereePersonalRoundResult](#matchmakerefereepersonalroundresult)]

## MatchmakeRefereePersonalRoundResult **def _\_init__**()
Creates a new `MatchmakeRefereePersonalRoundResult` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
personal_round_result_flag: int
round_win_loss: int
rating_change: int
buffer: bytes

## MatchmakeRefereeRound **def _\_init__**()
Creates a new `MatchmakeRefereeRound` instance. Required fields must be filled in manually. The following fields are defined in this class:
id: int
gid: int
state: int
personal_data_category: int
results: list[[MatchmakeRefereePersonalRoundResult](#matchmakerefereepersonalroundresult)]

## MatchmakeRefereeStartRoundParam **def _\_init__**()
Creates a new `MatchmakeRefereeStartRoundParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
personal_data_category: int
gid: int
pids: list[int]

## MatchmakeRefereeStats **def _\_init__**()
Creates a new `MatchmakeRefereeStats` instance. Required fields must be filled in manually. The following fields are defined in this class:
unique_id: int
category: int
pid: int
recent_disconnection: int
recent_violation: int
recent_mismatch: int
recent_win: int
recent_loss: int
recent_draw: int
total_disconnect: int
total_violation: int
total_mismatch: int
total_win: int
total_loss: int
total_draw: int
rating_value: int

## MatchmakeRefereeStatsInitParam **def _\_init__**()
Creates a new `MatchmakeRefereeStatsInitParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
category: int
initial_rating: int

## MatchmakeRefereeStatsTarget **def _\_init__**()
Creates a new `MatchmakeRefereeStatsTarget` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
category: int

## MatchmakeSession **def _\_init__**()
Creates a new `MatchmakeSession` instance. Required fields must be filled in manually. The following fields are defined in this class:
game_mode: int = 0
attribs: list[int] = [0, 0, 0, 0, 0, 0]
open_participation: bool = True
matchmake_system: int = 0
application_data: bytes = b""
num_participants: int = 0
If 30000 <= `nex.version` < 40000:
If `nex.version` >= 30500:
progress_score: int = 100

If `nex.version` >= 30000:
session_key: bytes = b""

If `nex.version` >= 30500:
option: int = 0

If `nex.version` >= 30600:
If `revision` >= 1:
param: [MatchmakeParam](#matchmakeparam) = [MatchmakeParam](#matchmakeparam)()
started_time: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).never()


If `nex.version` >= 30700:
If `revision` >= 2:
user_password: str = ""


If `nex.version` >= 30800:
If `revision` >= 3:
refer_gid: int = 0
user_password_enabled: bool = False
system_password_enabled: bool = False



If `nex.version` >= 40000:
progress_score: int = 100
session_key: bytes = b""
option: int = 0
param: [MatchmakeParam](#matchmakeparam) = [MatchmakeParam](#matchmakeparam)()
started_time: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).never()
user_password: str = ""
refer_gid: int = 0
user_password_enabled: bool = False
system_password_enabled: bool = False
codeword: str = ""


## MatchmakeSessionSearchCriteria **def _\_init__**()
Creates a new `MatchmakeSessionSearchCriteria` instance. Required fields must be filled in manually. The following fields are defined in this class:
attribs: list[str] = ["", "", "", "", "", ""]
game_mode: str = ""
min_participants: str = ""
max_participants: str = ""
matchmake_system: str = ""
vacant_only: bool = True
exclude_locked: bool = True
exclude_non_host_pid: bool = False
selection_method: int = 0
If `nex.version` >= 30500:
vacant_participants: int = 1

If `nex.version` >= 40000:
param: [MatchmakeParam](#matchmakeparam) = [MatchmakeParam](#matchmakeparam)()
exclude_user_password: bool = False
exclude_system_password: bool = False
refer_gid: int = 0
codeword: str = ""
range: [ResultRange](common.md#resultrange) = [ResultRange](common.md#resultrange)()


## ParticipantDetails **def _\_init__**()
Creates a new `ParticipantDetails` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
name: str
message: str
participants: int

## PersistentGathering **def _\_init__**()
Creates a new `PersistentGathering` instance. Required fields must be filled in manually. The following fields are defined in this class:
type: int
password: str
attribs: list[int]
application_buffer: bytes
participation_start: [DateTime](common.md#datetime)
participation_end: [DateTime](common.md#datetime)
matchmake_session_count: int
num_participants: int

## PlayingSession **def _\_init__**()
Creates a new `PlayingSession` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
gathering: [Gathering](#gathering)

## SimpleCommunity **def _\_init__**()
Creates a new `SimpleCommunity` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
matchmake_session_count: int

## SimplePlayingSession **def _\_init__**()
Creates a new `SimplePlayingSession` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
gid: int
game_mode: int
attribute: int

## UpdateMatchmakeSessionParam **def _\_init__**()
Creates a new `UpdateMatchmakeSessionParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
modification_flags: int
attributes: list[int]
open_participation: bool
application_buffer: bytes
progress_score: int
param: [MatchmakeParam](#matchmakeparam) = [MatchmakeParam](#matchmakeparam)()
started_time: [DateTime](common.md#datetime)
user_password: str
game_mode: int
description: str
min_participants: int
max_participants: int
matchmake_system: int
participation_policy: int
policy_argument: int
codeword: str

================================================ FILE: docs/reference/nex/matchmaking_eagle.md ================================================ # Module: nintendo.nex.matchmaking_eagle Provides a client and server for the `MatchMakingProtocol`, `MatchMakingProtocolExt`, `MatchmakeExtensionProtocol` and `MatchmakeRefereeProtocol`. This page was generated automatically from `matchmaking_eagle.proto`. **class** [MatchMakingClient](#matchmakingclient)
The client for the `MatchMakingProtocol`. **class** [MatchMakingClientExt](#matchmakingclientext)
The client for the `MatchMakingProtocolExt`. **class** [MatchmakeExtensionClient](#matchmakeextensionclient)
The client for the `MatchmakeExtensionProtocol`. **class** [MatchmakeRefereeClient](#matchmakerefereeclient)
The client for the `MatchmakeRefereeProtocol`. **class** [MatchMakingServer](#matchmakingserver)
The server for the `MatchMakingProtocol`. **class** [MatchMakingServerExt](#matchmakingserverext)
The server for the `MatchMakingProtocolExt`. **class** [MatchmakeExtensionServer](#matchmakeextensionserver)
The server for the `MatchmakeExtensionProtocol`. **class** [MatchmakeRefereeServer](#matchmakerefereeserver)
The server for the `MatchmakeRefereeProtocol`. **class** [MatchmakeSystem](#matchmakesystem)
**class** [AutoMatchmakeParam](#automatchmakeparam)([Structure](common.md))
**class** [CreateMatchmakeSessionParam](#creatematchmakesessionparam)([Structure](common.md))
**class** [DeletionEntry](#deletionentry)([Structure](common.md))
**class** [FindMatchmakeSessionByParticipantParam](#findmatchmakesessionbyparticipantparam)([Structure](common.md))
**class** [FindMatchmakeSessionByParticipantResult](#findmatchmakesessionbyparticipantresult)([Structure](common.md))
**class** [Gathering](#gathering)([Structure](common.md))
**class** [GatheringStats](#gatheringstats)([Structure](common.md))
**class** [GatheringURLs](#gatheringurls)([Structure](common.md))
**class** [Invitation](#invitation)([Structure](common.md))
**class** [JoinMatchmakeSessionParam](#joinmatchmakesessionparam)([Structure](common.md))
**class** [MatchmakeBlockListParam](#matchmakeblocklistparam)([Structure](common.md))
**class** [MatchmakeParam](#matchmakeparam)([Structure](common.md))
**class** [MatchmakeRefereeEndRoundParam](#matchmakerefereeendroundparam)([Structure](common.md))
**class** [MatchmakeRefereePersonalRoundResult](#matchmakerefereepersonalroundresult)([Structure](common.md))
**class** [MatchmakeRefereeRound](#matchmakerefereeround)([Structure](common.md))
**class** [MatchmakeRefereeStartRoundParam](#matchmakerefereestartroundparam)([Structure](common.md))
**class** [MatchmakeRefereeStats](#matchmakerefereestats)([Structure](common.md))
**class** [MatchmakeRefereeStatsInitParam](#matchmakerefereestatsinitparam)([Structure](common.md))
**class** [MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)([Structure](common.md))
**class** [MatchmakeSession](#matchmakesession)([Gathering](#gathering))
**class** [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)([Structure](common.md))
**class** [ParticipantDetails](#participantdetails)([Structure](common.md))
**class** [PersistentGathering](#persistentgathering)([Gathering](#gathering))
**class** [PlayingSession](#playingsession)([Structure](common.md))
**class** [SimpleCommunity](#simplecommunity)([Structure](common.md))
**class** [SimplePlayingSession](#simpleplayingsession)([Structure](common.md))
**class** [UpdateMatchmakeSessionParam](#updatematchmakesessionparam)([Structure](common.md))
## MatchMakingClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`MatchMakingClient`](#matchmakingclient). **async def register_gathering**(gathering: [Gathering](#gathering)) -> int
Calls method `1` on the server. **async def unregister_gathering**(gid: int) -> bool
Calls method `2` on the server. **async def unregister_gatherings**(gids: list[int]) -> bool
Calls method `3` on the server. **async def update_gathering**(gathering: [Gathering](#gathering)) -> bool
Calls method `4` on the server. **async def invite**(gid: int, pids: list[int], message: str) -> bool
Calls method `5` on the server. **async def accept_invitation**(gid: int, message: str) -> bool
Calls method `6` on the server. **async def decline_invitation**(gid: int, message: str) -> bool
Calls method `7` on the server. **async def cancel_invitation**(gid: int, pids: list[int], message: str) -> bool
Calls method `8` on the server. **async def get_invitations_sent**(gid: int) -> list[[Invitation](#invitation)]
Calls method `9` on the server. **async def get_invitations_received**() -> list[[Invitation](#invitation)]
Calls method `10` on the server. **async def participate**(gid: int, message: str) -> bool
Calls method `11` on the server. **async def cancel_participation**(gid: int, message: str) -> bool
Calls method `12` on the server. **async def get_participants**(gid: int) -> list[int]
Calls method `13` on the server. **async def add_participants**(gid: int, pids: list[int], message: str) -> bool
Calls method `14` on the server. **async def get_detailed_participants**(gid: int) -> list[[ParticipantDetails](#participantdetails)]
Calls method `15` on the server. **async def get_participants_urls**(gid: int) -> list[[StationURL](common.md#stationurl)]
Calls method `16` on the server. **async def find_by_type**(type: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `17` on the server. **async def find_by_description**(description: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `18` on the server. **async def find_by_description_regex**(regex: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `19` on the server. **async def find_by_id**(ids: list[int]) -> list[[Gathering](#gathering)]
Calls method `20` on the server. **async def find_by_single_id**(gid: int) -> [RMCResponse](common.md)
Calls method `21` on the server. The RMC response has the following attributes:
result: bool
gathering: [Gathering](#gathering)
**async def find_by_owner**(owner: int, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `22` on the server. **async def find_by_participants**(pids: list[int]) -> list[[Gathering](#gathering)]
Calls method `23` on the server. **async def find_invitations**(range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `24` on the server. **async def find_by_sql_query**(query: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `25` on the server. **async def launch_session**(gid: int, url: str) -> bool
Calls method `26` on the server. **async def update_session_url**(gid: int, url: str) -> bool
Calls method `27` on the server. **async def get_session_url**(gid: int) -> [RMCResponse](common.md)
Calls method `28` on the server. The RMC response has the following attributes:
result: bool
url: str
**async def get_state**(gid: int) -> [RMCResponse](common.md)
Calls method `29` on the server. The RMC response has the following attributes:
result: bool
state: int
**async def set_state**(gid: int, state: int) -> bool
Calls method `30` on the server. **async def report_stats**(gid: int, stats: list[[GatheringStats](#gatheringstats)]) -> bool
Calls method `31` on the server. **async def get_stats**(gid: int, pids: list[int], columns: list[int]) -> [RMCResponse](common.md)
Calls method `32` on the server. The RMC response has the following attributes:
result: bool
stats: list[[GatheringStats](#gatheringstats)]
**async def delete_gathering**(gid: int) -> bool
Calls method `33` on the server. **async def get_pending_deletions**(reason: int, range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Calls method `34` on the server. The RMC response has the following attributes:
result: bool
deletions: list[[DeletionEntry](#deletionentry)]
**async def delete_from_deletions**(deletions: list[int]) -> bool
Calls method `35` on the server. **async def migrate_gathering_ownership_v1**(gid: int, potential_owners: list[int]) -> bool
Calls method `36` on the server. **async def find_by_description_like**(description: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `37` on the server. **async def register_local_url**(gid: int, url: [StationURL](common.md#stationurl)) -> None
Calls method `38` on the server. **async def register_local_urls**(gid: int, urls: list[[StationURL](common.md#stationurl)]) -> None
Calls method `39` on the server. **async def update_session_host_v1**(gid: int) -> None
Calls method `40` on the server. **async def get_session_urls**(gid: int) -> list[[StationURL](common.md#stationurl)]
Calls method `41` on the server. **async def update_session_host**(gid: int, is_migrate_owner: bool) -> None
Calls method `42` on the server. **async def update_gathering_ownership**(gid: int, participants_only: bool) -> bool
Calls method `43` on the server. **async def migrate_gathering_ownership**(gid: int, potential_owners: list[int], participants_only: bool) -> None
Calls method `44` on the server. ## MatchMakingClientExt **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`MatchMakingClientExt`](#matchmakingclientext). **async def end_participation**(gid: int, message: str) -> bool
Calls method `1` on the server. **async def get_participants**(gid: int, only_active: bool) -> list[int]
Calls method `2` on the server. **async def get_detailed_participants**(gid: int, only_active: bool) -> list[[ParticipantDetails](#participantdetails)]
Calls method `3` on the server. **async def get_participants_urls**(gids: list[int]) -> list[[GatheringURLs](#gatheringurls)]
Calls method `4` on the server. **async def get_gathering_relations**(id: int, descr: str) -> str
Calls method `5` on the server. **async def delete_from_deletions**(deletions: list[int], pid: int) -> None
Calls method `6` on the server. ## MatchmakeExtensionClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`MatchmakeExtensionClient`](#matchmakeextensionclient). **async def close_participation**(gid: int) -> None
Calls method `1` on the server. **async def open_participation**(gid: int) -> None
Calls method `2` on the server. **async def auto_matchmake_postpone**(gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Calls method `3` on the server. **async def browse_matchmake_session**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `4` on the server. **async def browse_matchmake_session_with_host_urls**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Calls method `5` on the server. The RMC response has the following attributes:
gatherings: list[[Gathering](#gathering)]
urls: list[[GatheringURLs](#gatheringurls)]
**async def create_matchmake_session**(gathering: [Gathering](#gathering), description: str, num_participants: int) -> [RMCResponse](common.md)
Calls method `6` on the server. The RMC response has the following attributes:
gid: int
session_key: bytes
**async def join_matchmake_session**(gid: int, message: str) -> bytes
Calls method `7` on the server. **async def modify_current_game_attribute**(gid: int, attrib: int, value: int) -> None
Calls method `8` on the server. **async def update_notification_data**(type: int, param1: int, param2: int, param3: str) -> None
Calls method `9` on the server. **async def get_friend_notification_data**(type: int) -> list[[NotificationEvent](notification.md#notificationevent)]
Calls method `10` on the server. **async def update_application_buffer**(gid: int, buffer: bytes) -> None
Calls method `11` on the server. **async def update_matchmake_session_attribute**(gid: int, attribs: list[int]) -> None
Calls method `12` on the server. **async def get_friend_notification_data_list**(types: list[int]) -> list[[NotificationEvent](notification.md#notificationevent)]
Calls method `13` on the server. **async def update_matchmake_session**(gathering: [Gathering](#gathering)) -> None
Calls method `14` on the server. **async def auto_matchmake_with_search_criteria_postpone**(search_criteria: list[[MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)], gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Calls method `15` on the server. **async def get_playing_session**(pids: list[int]) -> list[[PlayingSession](#playingsession)]
Calls method `16` on the server. **async def create_community**(community: [PersistentGathering](#persistentgathering), message: str) -> int
Calls method `17` on the server. **async def update_community**(community: [PersistentGathering](#persistentgathering)) -> None
Calls method `18` on the server. **async def join_community**(gid: int, message: str, password: str) -> None
Calls method `19` on the server. **async def find_community_by_gathering_id**(gids: list[int]) -> list[[PersistentGathering](#persistentgathering)]
Calls method `20` on the server. **async def find_official_community**(available_only: bool, range: [ResultRange](common.md#resultrange)) -> list[[PersistentGathering](#persistentgathering)]
Calls method `21` on the server. **async def find_community_by_participant**(pid: int, range: [ResultRange](common.md#resultrange)) -> list[[PersistentGathering](#persistentgathering)]
Calls method `22` on the server. **async def update_privacy_setting**(online_status: bool, community_participation: bool) -> None
Calls method `23` on the server. **async def get_my_block_list**() -> list[int]
Calls method `24` on the server. **async def add_to_block_list**(pids: list[int]) -> None
Calls method `25` on the server. **async def remove_from_block_list**(pids: list[int]) -> None
Calls method `26` on the server. **async def clear_my_block_list**() -> None
Calls method `27` on the server. **async def report_violation**(pid: int, username: str, violation_code: int) -> None
Calls method `28` on the server. **async def is_violation_user**() -> [RMCResponse](common.md)
Calls method `29` on the server. The RMC response has the following attributes:
flag: bool
score: int
**async def join_matchmake_session_ex**(gid: int, gmessage: str, ignore_block_list: bool, num_participants: int) -> bytes
Calls method `30` on the server. **async def get_simple_playing_session**(pids: list[int], include_login_user: bool) -> list[[SimplePlayingSession](#simpleplayingsession)]
Calls method `31` on the server. **async def get_simple_community**(gids: list[int]) -> list[[SimpleCommunity](#simplecommunity)]
Calls method `32` on the server. **async def auto_matchmake_with_gathering_id_postpone**(gids: list[int], gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Calls method `33` on the server. **async def update_progress_score**(gid: int, score: int) -> None
Calls method `34` on the server. **async def debug_notify_event**(pid: int, main_type: int, sub_type: int, param1: int, param2: int, param3: str) -> None
Calls method `35` on the server. **async def generate_matchmake_session_system_password**(gid: int) -> str
Calls method `36` on the server. **async def clear_matchmake_session_system_password**(gid: int) -> None
Calls method `37` on the server. **async def create_matchmake_session_with_param**(param: [CreateMatchmakeSessionParam](#creatematchmakesessionparam)) -> [MatchmakeSession](#matchmakesession)
Calls method `38` on the server. **async def join_matchmake_session_with_param**(param: [JoinMatchmakeSessionParam](#joinmatchmakesessionparam)) -> [MatchmakeSession](#matchmakesession)
Calls method `39` on the server. **async def auto_matchmake_with_param_postpone**(param: [AutoMatchmakeParam](#automatchmakeparam)) -> [MatchmakeSession](#matchmakesession)
Calls method `40` on the server. **async def find_matchmake_session_by_gathering_id_detail**(gid: int) -> [MatchmakeSession](#matchmakesession)
Calls method `41` on the server. **async def browse_matchmake_session_no_holder**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> list[[MatchmakeSession](#matchmakesession)]
Calls method `42` on the server. **async def browse_matchmake_session_with_host_urls_no_holder**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Calls method `43` on the server. The RMC response has the following attributes:
sessions: list[[MatchmakeSession](#matchmakesession)]
urls: list[[GatheringURLs](#gatheringurls)]
**async def update_matchmake_session_part**(param: [UpdateMatchmakeSessionParam](#updatematchmakesessionparam)) -> None
Calls method `44` on the server. **async def request_matchmaking**(param: [AutoMatchmakeParam](#automatchmakeparam)) -> int
Calls method `45` on the server. **async def withdraw_matchmaking**(request_id: int) -> None
Calls method `46` on the server. **async def withdraw_matchmaking_all**() -> None
Calls method `47` on the server. **async def find_matchmake_session_by_gathering_id**(gids: list[int]) -> list[[MatchmakeSession](#matchmakesession)]
Calls method `48` on the server. **async def find_matchmake_session_by_single_gathering_id**(gid: int) -> [MatchmakeSession](#matchmakesession)
Calls method `49` on the server. **async def find_matchmake_session_by_owner**(pid: int, range: [ResultRange](common.md#resultrange)) -> list[[MatchmakeSession](#matchmakesession)]
Calls method `50` on the server. **async def find_matchmake_session_by_participant**(param: [FindMatchmakeSessionByParticipantParam](#findmatchmakesessionbyparticipantparam)) -> list[[FindMatchmakeSessionByParticipantResult](#findmatchmakesessionbyparticipantresult)]
Calls method `51` on the server. **async def browse_matchmake_session_no_holder_no_result_range**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)) -> list[[MatchmakeSession](#matchmakesession)]
Calls method `52` on the server. **async def browse_matchmake_session_with_host_urls_no_holder_no_result_range**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)) -> [RMCResponse](common.md)
Calls method `53` on the server. The RMC response has the following attributes:
sessions: list[[MatchmakeSession](#matchmakesession)]
urls: list[[GatheringURLs](#gatheringurls)]
## MatchmakeRefereeClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`MatchmakeRefereeClient`](#matchmakerefereeclient). **async def start_round**(param: [MatchmakeRefereeStartRoundParam](#matchmakerefereestartroundparam)) -> int
Calls method `1` on the server. **async def get_start_round_param**(round_id: int) -> [MatchmakeRefereeStartRoundParam](#matchmakerefereestartroundparam)
Calls method `2` on the server. **async def end_round**(param: [MatchmakeRefereeEndRoundParam](#matchmakerefereeendroundparam)) -> None
Calls method `3` on the server. **async def end_round_with_partial_report**(param: [MatchmakeRefereeEndRoundParam](#matchmakerefereeendroundparam)) -> None
Calls method `4` on the server. **async def end_round_without_report**(round_id: int) -> None
Calls method `5` on the server. **async def get_round_participants**(round_id: int) -> list[int]
Calls method `6` on the server. **async def get_not_summarized_round**() -> list[[MatchmakeRefereeRound](#matchmakerefereeround)]
Calls method `7` on the server. **async def get_round**(round: int) -> [MatchmakeRefereeRound](#matchmakerefereeround)
Calls method `8` on the server. **async def get_stats_primary**(target: [MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Calls method `9` on the server. **async def get_stats_primaries**(targets: list[[MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)]) -> [RMCResponse](common.md)
Calls method `10` on the server. The RMC response has the following attributes:
stats: list[[MatchmakeRefereeStats](#matchmakerefereestats)]
results: list[[Result](common.md#result)]
**async def get_stats_all**(target: [MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)) -> list[[MatchmakeRefereeStats](#matchmakerefereestats)]
Calls method `11` on the server. **async def create_stats**(param: [MatchmakeRefereeStatsInitParam](#matchmakerefereestatsinitparam)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Calls method `12` on the server. **async def get_or_create_stats**(param: [MatchmakeRefereeStatsInitParam](#matchmakerefereestatsinitparam)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Calls method `13` on the server. **async def reset_stats**() -> None
Calls method `14` on the server. ## MatchMakingServer **def _\_init__**()
Creates a new [`MatchMakingServer`](#matchmakingserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def register_gathering**(client: [RMCClient](rmc.md#rmcclient), gathering: [Gathering](#gathering)) -> int
Handler for method `1`. This method should be overridden by a subclass. **async def unregister_gathering**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> bool
Handler for method `2`. This method should be overridden by a subclass. **async def unregister_gatherings**(client: [RMCClient](rmc.md#rmcclient), gids: list[int]) -> bool
Handler for method `3`. This method should be overridden by a subclass. **async def update_gathering**(client: [RMCClient](rmc.md#rmcclient), gathering: [Gathering](#gathering)) -> bool
Handler for method `4`. This method should be overridden by a subclass. **async def invite**(client: [RMCClient](rmc.md#rmcclient), gid: int, pids: list[int], message: str) -> bool
Handler for method `5`. This method should be overridden by a subclass. **async def accept_invitation**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bool
Handler for method `6`. This method should be overridden by a subclass. **async def decline_invitation**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bool
Handler for method `7`. This method should be overridden by a subclass. **async def cancel_invitation**(client: [RMCClient](rmc.md#rmcclient), gid: int, pids: list[int], message: str) -> bool
Handler for method `8`. This method should be overridden by a subclass. **async def get_invitations_sent**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> list[[Invitation](#invitation)]
Handler for method `9`. This method should be overridden by a subclass. **async def get_invitations_received**(client: [RMCClient](rmc.md#rmcclient)) -> list[[Invitation](#invitation)]
Handler for method `10`. This method should be overridden by a subclass. **async def participate**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bool
Handler for method `11`. This method should be overridden by a subclass. **async def cancel_participation**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bool
Handler for method `12`. This method should be overridden by a subclass. **async def get_participants**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> list[int]
Handler for method `13`. This method should be overridden by a subclass. **async def add_participants**(client: [RMCClient](rmc.md#rmcclient), gid: int, pids: list[int], message: str) -> bool
Handler for method `14`. This method should be overridden by a subclass. **async def get_detailed_participants**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> list[[ParticipantDetails](#participantdetails)]
Handler for method `15`. This method should be overridden by a subclass. **async def get_participants_urls**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> list[[StationURL](common.md#stationurl)]
Handler for method `16`. This method should be overridden by a subclass. **async def find_by_type**(client: [RMCClient](rmc.md#rmcclient), type: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `17`. This method should be overridden by a subclass. **async def find_by_description**(client: [RMCClient](rmc.md#rmcclient), description: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `18`. This method should be overridden by a subclass. **async def find_by_description_regex**(client: [RMCClient](rmc.md#rmcclient), regex: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `19`. This method should be overridden by a subclass. **async def find_by_id**(client: [RMCClient](rmc.md#rmcclient), ids: list[int]) -> list[[Gathering](#gathering)]
Handler for method `20`. This method should be overridden by a subclass. **async def find_by_single_id**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> [RMCResponse](common.md)
Handler for method `21`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
gathering: [Gathering](#gathering)
**async def find_by_owner**(client: [RMCClient](rmc.md#rmcclient), owner: int, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `22`. This method should be overridden by a subclass. **async def find_by_participants**(client: [RMCClient](rmc.md#rmcclient), pids: list[int]) -> list[[Gathering](#gathering)]
Handler for method `23`. This method should be overridden by a subclass. **async def find_invitations**(client: [RMCClient](rmc.md#rmcclient), range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `24`. This method should be overridden by a subclass. **async def find_by_sql_query**(client: [RMCClient](rmc.md#rmcclient), query: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `25`. This method should be overridden by a subclass. **async def launch_session**(client: [RMCClient](rmc.md#rmcclient), gid: int, url: str) -> bool
Handler for method `26`. This method should be overridden by a subclass. **async def update_session_url**(client: [RMCClient](rmc.md#rmcclient), gid: int, url: str) -> bool
Handler for method `27`. This method should be overridden by a subclass. **async def get_session_url**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> [RMCResponse](common.md)
Handler for method `28`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
url: str
**async def get_state**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> [RMCResponse](common.md)
Handler for method `29`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
state: int
**async def set_state**(client: [RMCClient](rmc.md#rmcclient), gid: int, state: int) -> bool
Handler for method `30`. This method should be overridden by a subclass. **async def report_stats**(client: [RMCClient](rmc.md#rmcclient), gid: int, stats: list[[GatheringStats](#gatheringstats)]) -> bool
Handler for method `31`. This method should be overridden by a subclass. **async def get_stats**(client: [RMCClient](rmc.md#rmcclient), gid: int, pids: list[int], columns: list[int]) -> [RMCResponse](common.md)
Handler for method `32`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
stats: list[[GatheringStats](#gatheringstats)]
**async def delete_gathering**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> bool
Handler for method `33`. This method should be overridden by a subclass. **async def get_pending_deletions**(client: [RMCClient](rmc.md#rmcclient), reason: int, range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Handler for method `34`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
deletions: list[[DeletionEntry](#deletionentry)]
**async def delete_from_deletions**(client: [RMCClient](rmc.md#rmcclient), deletions: list[int]) -> bool
Handler for method `35`. This method should be overridden by a subclass. **async def migrate_gathering_ownership_v1**(client: [RMCClient](rmc.md#rmcclient), gid: int, potential_owners: list[int]) -> bool
Handler for method `36`. This method should be overridden by a subclass. **async def find_by_description_like**(client: [RMCClient](rmc.md#rmcclient), description: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `37`. This method should be overridden by a subclass. **async def register_local_url**(client: [RMCClient](rmc.md#rmcclient), gid: int, url: [StationURL](common.md#stationurl)) -> None
Handler for method `38`. This method should be overridden by a subclass. **async def register_local_urls**(client: [RMCClient](rmc.md#rmcclient), gid: int, urls: list[[StationURL](common.md#stationurl)]) -> None
Handler for method `39`. This method should be overridden by a subclass. **async def update_session_host_v1**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> None
Handler for method `40`. This method should be overridden by a subclass. **async def get_session_urls**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> list[[StationURL](common.md#stationurl)]
Handler for method `41`. This method should be overridden by a subclass. **async def update_session_host**(client: [RMCClient](rmc.md#rmcclient), gid: int, is_migrate_owner: bool) -> None
Handler for method `42`. This method should be overridden by a subclass. **async def update_gathering_ownership**(client: [RMCClient](rmc.md#rmcclient), gid: int, participants_only: bool) -> bool
Handler for method `43`. This method should be overridden by a subclass. **async def migrate_gathering_ownership**(client: [RMCClient](rmc.md#rmcclient), gid: int, potential_owners: list[int], participants_only: bool) -> None
Handler for method `44`. This method should be overridden by a subclass. ## MatchMakingServerExt **def _\_init__**()
Creates a new [`MatchMakingServerExt`](#matchmakingserverext). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def end_participation**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bool
Handler for method `1`. This method should be overridden by a subclass. **async def get_participants**(client: [RMCClient](rmc.md#rmcclient), gid: int, only_active: bool) -> list[int]
Handler for method `2`. This method should be overridden by a subclass. **async def get_detailed_participants**(client: [RMCClient](rmc.md#rmcclient), gid: int, only_active: bool) -> list[[ParticipantDetails](#participantdetails)]
Handler for method `3`. This method should be overridden by a subclass. **async def get_participants_urls**(client: [RMCClient](rmc.md#rmcclient), gids: list[int]) -> list[[GatheringURLs](#gatheringurls)]
Handler for method `4`. This method should be overridden by a subclass. **async def get_gathering_relations**(client: [RMCClient](rmc.md#rmcclient), id: int, descr: str) -> str
Handler for method `5`. This method should be overridden by a subclass. **async def delete_from_deletions**(client: [RMCClient](rmc.md#rmcclient), deletions: list[int], pid: int) -> None
Handler for method `6`. This method should be overridden by a subclass. ## MatchmakeExtensionServer **def _\_init__**()
Creates a new [`MatchmakeExtensionServer`](#matchmakeextensionserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def close_participation**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> None
Handler for method `1`. This method should be overridden by a subclass. **async def open_participation**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> None
Handler for method `2`. This method should be overridden by a subclass. **async def auto_matchmake_postpone**(client: [RMCClient](rmc.md#rmcclient), gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Handler for method `3`. This method should be overridden by a subclass. **async def browse_matchmake_session**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `4`. This method should be overridden by a subclass. **async def browse_matchmake_session_with_host_urls**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Handler for method `5`. This method should be overridden by a subclass. The RMC response must have the following attributes:
gatherings: list[[Gathering](#gathering)]
urls: list[[GatheringURLs](#gatheringurls)]
**async def create_matchmake_session**(client: [RMCClient](rmc.md#rmcclient), gathering: [Gathering](#gathering), description: str, num_participants: int) -> [RMCResponse](common.md)
Handler for method `6`. This method should be overridden by a subclass. The RMC response must have the following attributes:
gid: int
session_key: bytes
**async def join_matchmake_session**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bytes
Handler for method `7`. This method should be overridden by a subclass. **async def modify_current_game_attribute**(client: [RMCClient](rmc.md#rmcclient), gid: int, attrib: int, value: int) -> None
Handler for method `8`. This method should be overridden by a subclass. **async def update_notification_data**(client: [RMCClient](rmc.md#rmcclient), type: int, param1: int, param2: int, param3: str) -> None
Handler for method `9`. This method should be overridden by a subclass. **async def get_friend_notification_data**(client: [RMCClient](rmc.md#rmcclient), type: int) -> list[[NotificationEvent](notification.md#notificationevent)]
Handler for method `10`. This method should be overridden by a subclass. **async def update_application_buffer**(client: [RMCClient](rmc.md#rmcclient), gid: int, buffer: bytes) -> None
Handler for method `11`. This method should be overridden by a subclass. **async def update_matchmake_session_attribute**(client: [RMCClient](rmc.md#rmcclient), gid: int, attribs: list[int]) -> None
Handler for method `12`. This method should be overridden by a subclass. **async def get_friend_notification_data_list**(client: [RMCClient](rmc.md#rmcclient), types: list[int]) -> list[[NotificationEvent](notification.md#notificationevent)]
Handler for method `13`. This method should be overridden by a subclass. **async def update_matchmake_session**(client: [RMCClient](rmc.md#rmcclient), gathering: [Gathering](#gathering)) -> None
Handler for method `14`. This method should be overridden by a subclass. **async def auto_matchmake_with_search_criteria_postpone**(client: [RMCClient](rmc.md#rmcclient), search_criteria: list[[MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)], gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Handler for method `15`. This method should be overridden by a subclass. **async def get_playing_session**(client: [RMCClient](rmc.md#rmcclient), pids: list[int]) -> list[[PlayingSession](#playingsession)]
Handler for method `16`. This method should be overridden by a subclass. **async def create_community**(client: [RMCClient](rmc.md#rmcclient), community: [PersistentGathering](#persistentgathering), message: str) -> int
Handler for method `17`. This method should be overridden by a subclass. **async def update_community**(client: [RMCClient](rmc.md#rmcclient), community: [PersistentGathering](#persistentgathering)) -> None
Handler for method `18`. This method should be overridden by a subclass. **async def join_community**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str, password: str) -> None
Handler for method `19`. This method should be overridden by a subclass. **async def find_community_by_gathering_id**(client: [RMCClient](rmc.md#rmcclient), gids: list[int]) -> list[[PersistentGathering](#persistentgathering)]
Handler for method `20`. This method should be overridden by a subclass. **async def find_official_community**(client: [RMCClient](rmc.md#rmcclient), available_only: bool, range: [ResultRange](common.md#resultrange)) -> list[[PersistentGathering](#persistentgathering)]
Handler for method `21`. This method should be overridden by a subclass. **async def find_community_by_participant**(client: [RMCClient](rmc.md#rmcclient), pid: int, range: [ResultRange](common.md#resultrange)) -> list[[PersistentGathering](#persistentgathering)]
Handler for method `22`. This method should be overridden by a subclass. **async def update_privacy_setting**(client: [RMCClient](rmc.md#rmcclient), online_status: bool, community_participation: bool) -> None
Handler for method `23`. This method should be overridden by a subclass. **async def get_my_block_list**(client: [RMCClient](rmc.md#rmcclient)) -> list[int]
Handler for method `24`. This method should be overridden by a subclass. **async def add_to_block_list**(client: [RMCClient](rmc.md#rmcclient), pids: list[int]) -> None
Handler for method `25`. This method should be overridden by a subclass. **async def remove_from_block_list**(client: [RMCClient](rmc.md#rmcclient), pids: list[int]) -> None
Handler for method `26`. This method should be overridden by a subclass. **async def clear_my_block_list**(client: [RMCClient](rmc.md#rmcclient)) -> None
Handler for method `27`. This method should be overridden by a subclass. **async def report_violation**(client: [RMCClient](rmc.md#rmcclient), pid: int, username: str, violation_code: int) -> None
Handler for method `28`. This method should be overridden by a subclass. **async def is_violation_user**(client: [RMCClient](rmc.md#rmcclient)) -> [RMCResponse](common.md)
Handler for method `29`. This method should be overridden by a subclass. The RMC response must have the following attributes:
flag: bool
score: int
**async def join_matchmake_session_ex**(client: [RMCClient](rmc.md#rmcclient), gid: int, gmessage: str, ignore_block_list: bool, num_participants: int) -> bytes
Handler for method `30`. This method should be overridden by a subclass. **async def get_simple_playing_session**(client: [RMCClient](rmc.md#rmcclient), pids: list[int], include_login_user: bool) -> list[[SimplePlayingSession](#simpleplayingsession)]
Handler for method `31`. This method should be overridden by a subclass. **async def get_simple_community**(client: [RMCClient](rmc.md#rmcclient), gids: list[int]) -> list[[SimpleCommunity](#simplecommunity)]
Handler for method `32`. This method should be overridden by a subclass. **async def auto_matchmake_with_gathering_id_postpone**(client: [RMCClient](rmc.md#rmcclient), gids: list[int], gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Handler for method `33`. This method should be overridden by a subclass. **async def update_progress_score**(client: [RMCClient](rmc.md#rmcclient), gid: int, score: int) -> None
Handler for method `34`. This method should be overridden by a subclass. **async def debug_notify_event**(client: [RMCClient](rmc.md#rmcclient), pid: int, main_type: int, sub_type: int, param1: int, param2: int, param3: str) -> None
Handler for method `35`. This method should be overridden by a subclass. **async def generate_matchmake_session_system_password**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> str
Handler for method `36`. This method should be overridden by a subclass. **async def clear_matchmake_session_system_password**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> None
Handler for method `37`. This method should be overridden by a subclass. **async def create_matchmake_session_with_param**(client: [RMCClient](rmc.md#rmcclient), param: [CreateMatchmakeSessionParam](#creatematchmakesessionparam)) -> [MatchmakeSession](#matchmakesession)
Handler for method `38`. This method should be overridden by a subclass. **async def join_matchmake_session_with_param**(client: [RMCClient](rmc.md#rmcclient), param: [JoinMatchmakeSessionParam](#joinmatchmakesessionparam)) -> [MatchmakeSession](#matchmakesession)
Handler for method `39`. This method should be overridden by a subclass. **async def auto_matchmake_with_param_postpone**(client: [RMCClient](rmc.md#rmcclient), param: [AutoMatchmakeParam](#automatchmakeparam)) -> [MatchmakeSession](#matchmakesession)
Handler for method `40`. This method should be overridden by a subclass. **async def find_matchmake_session_by_gathering_id_detail**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> [MatchmakeSession](#matchmakesession)
Handler for method `41`. This method should be overridden by a subclass. **async def browse_matchmake_session_no_holder**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> list[[MatchmakeSession](#matchmakesession)]
Handler for method `42`. This method should be overridden by a subclass. **async def browse_matchmake_session_with_host_urls_no_holder**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Handler for method `43`. This method should be overridden by a subclass. The RMC response must have the following attributes:
sessions: list[[MatchmakeSession](#matchmakesession)]
urls: list[[GatheringURLs](#gatheringurls)]
**async def update_matchmake_session_part**(client: [RMCClient](rmc.md#rmcclient), param: [UpdateMatchmakeSessionParam](#updatematchmakesessionparam)) -> None
Handler for method `44`. This method should be overridden by a subclass. **async def request_matchmaking**(client: [RMCClient](rmc.md#rmcclient), param: [AutoMatchmakeParam](#automatchmakeparam)) -> int
Handler for method `45`. This method should be overridden by a subclass. **async def withdraw_matchmaking**(client: [RMCClient](rmc.md#rmcclient), request_id: int) -> None
Handler for method `46`. This method should be overridden by a subclass. **async def withdraw_matchmaking_all**(client: [RMCClient](rmc.md#rmcclient)) -> None
Handler for method `47`. This method should be overridden by a subclass. **async def find_matchmake_session_by_gathering_id**(client: [RMCClient](rmc.md#rmcclient), gids: list[int]) -> list[[MatchmakeSession](#matchmakesession)]
Handler for method `48`. This method should be overridden by a subclass. **async def find_matchmake_session_by_single_gathering_id**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> [MatchmakeSession](#matchmakesession)
Handler for method `49`. This method should be overridden by a subclass. **async def find_matchmake_session_by_owner**(client: [RMCClient](rmc.md#rmcclient), pid: int, range: [ResultRange](common.md#resultrange)) -> list[[MatchmakeSession](#matchmakesession)]
Handler for method `50`. This method should be overridden by a subclass. **async def find_matchmake_session_by_participant**(client: [RMCClient](rmc.md#rmcclient), param: [FindMatchmakeSessionByParticipantParam](#findmatchmakesessionbyparticipantparam)) -> list[[FindMatchmakeSessionByParticipantResult](#findmatchmakesessionbyparticipantresult)]
Handler for method `51`. This method should be overridden by a subclass. **async def browse_matchmake_session_no_holder_no_result_range**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)) -> list[[MatchmakeSession](#matchmakesession)]
Handler for method `52`. This method should be overridden by a subclass. **async def browse_matchmake_session_with_host_urls_no_holder_no_result_range**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)) -> [RMCResponse](common.md)
Handler for method `53`. This method should be overridden by a subclass. The RMC response must have the following attributes:
sessions: list[[MatchmakeSession](#matchmakesession)]
urls: list[[GatheringURLs](#gatheringurls)]
## MatchmakeRefereeServer **def _\_init__**()
Creates a new [`MatchmakeRefereeServer`](#matchmakerefereeserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def start_round**(client: [RMCClient](rmc.md#rmcclient), param: [MatchmakeRefereeStartRoundParam](#matchmakerefereestartroundparam)) -> int
Handler for method `1`. This method should be overridden by a subclass. **async def get_start_round_param**(client: [RMCClient](rmc.md#rmcclient), round_id: int) -> [MatchmakeRefereeStartRoundParam](#matchmakerefereestartroundparam)
Handler for method `2`. This method should be overridden by a subclass. **async def end_round**(client: [RMCClient](rmc.md#rmcclient), param: [MatchmakeRefereeEndRoundParam](#matchmakerefereeendroundparam)) -> None
Handler for method `3`. This method should be overridden by a subclass. **async def end_round_with_partial_report**(client: [RMCClient](rmc.md#rmcclient), param: [MatchmakeRefereeEndRoundParam](#matchmakerefereeendroundparam)) -> None
Handler for method `4`. This method should be overridden by a subclass. **async def end_round_without_report**(client: [RMCClient](rmc.md#rmcclient), round_id: int) -> None
Handler for method `5`. This method should be overridden by a subclass. **async def get_round_participants**(client: [RMCClient](rmc.md#rmcclient), round_id: int) -> list[int]
Handler for method `6`. This method should be overridden by a subclass. **async def get_not_summarized_round**(client: [RMCClient](rmc.md#rmcclient)) -> list[[MatchmakeRefereeRound](#matchmakerefereeround)]
Handler for method `7`. This method should be overridden by a subclass. **async def get_round**(client: [RMCClient](rmc.md#rmcclient), round: int) -> [MatchmakeRefereeRound](#matchmakerefereeround)
Handler for method `8`. This method should be overridden by a subclass. **async def get_stats_primary**(client: [RMCClient](rmc.md#rmcclient), target: [MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Handler for method `9`. This method should be overridden by a subclass. **async def get_stats_primaries**(client: [RMCClient](rmc.md#rmcclient), targets: list[[MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)]) -> [RMCResponse](common.md)
Handler for method `10`. This method should be overridden by a subclass. The RMC response must have the following attributes:
stats: list[[MatchmakeRefereeStats](#matchmakerefereestats)]
results: list[[Result](common.md#result)]
**async def get_stats_all**(client: [RMCClient](rmc.md#rmcclient), target: [MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)) -> list[[MatchmakeRefereeStats](#matchmakerefereestats)]
Handler for method `11`. This method should be overridden by a subclass. **async def create_stats**(client: [RMCClient](rmc.md#rmcclient), param: [MatchmakeRefereeStatsInitParam](#matchmakerefereestatsinitparam)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Handler for method `12`. This method should be overridden by a subclass. **async def get_or_create_stats**(client: [RMCClient](rmc.md#rmcclient), param: [MatchmakeRefereeStatsInitParam](#matchmakerefereestatsinitparam)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Handler for method `13`. This method should be overridden by a subclass. **async def reset_stats**(client: [RMCClient](rmc.md#rmcclient)) -> None
Handler for method `14`. This method should be overridden by a subclass. ## MatchmakeSystem This class defines the following constants:
`GLOBAL = 1`
`FRIENDS = 2`
## AutoMatchmakeParam **def _\_init__**()
Creates a new `AutoMatchmakeParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
session: [MatchmakeSession](#matchmakesession) = [MatchmakeSession](#matchmakesession)()
participants: list[int]
gid_for_participation_check: int
options: int
join_message: str
num_participants: int
search_criteria: list[[MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)]
target_gids: list[int]
block_list: [MatchmakeBlockListParam](#matchmakeblocklistparam) = [MatchmakeBlockListParam](#matchmakeblocklistparam)()

## CreateMatchmakeSessionParam **def _\_init__**()
Creates a new `CreateMatchmakeSessionParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
session: [MatchmakeSession](#matchmakesession) = [MatchmakeSession](#matchmakesession)()
additional_participants: list[int]
gid_for_participation_check: int
options: int
join_message: str
num_participants: int

## DeletionEntry **def _\_init__**()
Creates a new `DeletionEntry` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
pid: int
reason: int

## FindMatchmakeSessionByParticipantParam **def _\_init__**()
Creates a new `FindMatchmakeSessionByParticipantParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
pids: list[int]
options: int
block_list: [MatchmakeBlockListParam](#matchmakeblocklistparam) = [MatchmakeBlockListParam](#matchmakeblocklistparam)()

## FindMatchmakeSessionByParticipantResult **def _\_init__**()
Creates a new `FindMatchmakeSessionByParticipantResult` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
session: [MatchmakeSession](#matchmakesession) = [MatchmakeSession](#matchmakesession)()

## Gathering **def _\_init__**()
Creates a new `Gathering` instance. Required fields must be filled in manually. The following fields are defined in this class:
id: int = 0
owner: int = 0
host: int = 0
min_participants: int = 0
max_participants: int = 0
participation_policy: int = 1
policy_argument: int = 0
flags: int = 512
state: int = 0
description: str = ""

## GatheringStats **def _\_init__**()
Creates a new `GatheringStats` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
flags: int
values: list[float]

## GatheringURLs **def _\_init__**()
Creates a new `GatheringURLs` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
urls: list[[StationURL](common.md#stationurl)]

## Invitation **def _\_init__**()
Creates a new `Invitation` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
guest: int
message: str

## JoinMatchmakeSessionParam **def _\_init__**()
Creates a new `JoinMatchmakeSessionParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
participants: list[int]
gid_for_participation_check: int
options: int
behavior: int
user_password: str
system_password: str
join_message: str
num_participants: int
extra_participants: int
block_list: [MatchmakeBlockListParam](#matchmakeblocklistparam) = [MatchmakeBlockListParam](#matchmakeblocklistparam)()

## MatchmakeBlockListParam **def _\_init__**()
Creates a new `MatchmakeBlockListParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
options: int = 0

## MatchmakeParam **def _\_init__**()
Creates a new `MatchmakeParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
param: dict[str, object] = {}

## MatchmakeRefereeEndRoundParam **def _\_init__**()
Creates a new `MatchmakeRefereeEndRoundParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
round_id: int
results: list[[MatchmakeRefereePersonalRoundResult](#matchmakerefereepersonalroundresult)]

## MatchmakeRefereePersonalRoundResult **def _\_init__**()
Creates a new `MatchmakeRefereePersonalRoundResult` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
personal_round_result_flag: int
round_win_loss: int
rating_value_change: int
buffer: bytes
report_summary_mode: int
event_id: int

## MatchmakeRefereeRound **def _\_init__**()
Creates a new `MatchmakeRefereeRound` instance. Required fields must be filled in manually. The following fields are defined in this class:
id: int
gid: int
state: int
personal_data_category: int
results: list[[MatchmakeRefereePersonalRoundResult](#matchmakerefereepersonalroundresult)]

## MatchmakeRefereeStartRoundParam **def _\_init__**()
Creates a new `MatchmakeRefereeStartRoundParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
personal_data_category: int
gid: int
pids: list[int]
report_summary_mode: int
event_id: int

## MatchmakeRefereeStats **def _\_init__**()
Creates a new `MatchmakeRefereeStats` instance. Required fields must be filled in manually. The following fields are defined in this class:
unique_id: int
category: int
pid: int
recent_disconnection: int
recent_violation: int
recent_mismatch: int
recent_win: int
recent_loss: int
recent_draw: int
total_disconnect: int
total_violation: int
total_mismatch: int
total_win: int
total_loss: int
total_draw: int
rating_value: int

## MatchmakeRefereeStatsInitParam **def _\_init__**()
Creates a new `MatchmakeRefereeStatsInitParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
category: int
initial_rating: int

## MatchmakeRefereeStatsTarget **def _\_init__**()
Creates a new `MatchmakeRefereeStatsTarget` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
category: int

## MatchmakeSession **def _\_init__**()
Creates a new `MatchmakeSession` instance. Required fields must be filled in manually. The following fields are defined in this class:
game_mode: int = 0
attribs: list[int] = [0, 0, 0, 0, 0, 0]
open_participation: bool = True
matchmake_system: int = 0
application_data: bytes = b""
num_participants: int = 0
If 30000 <= `nex.version` < 40000:
If `nex.version` >= 30500:
progress_score: int = 100

If `nex.version` >= 30000:
session_key: bytes = b""

If `nex.version` >= 30500:
option: int = 0

If `nex.version` >= 30600:
If `revision` >= 1:
param: [MatchmakeParam](#matchmakeparam) = [MatchmakeParam](#matchmakeparam)()
started_time: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).never()


If `nex.version` >= 30700:
If `revision` >= 2:
user_password: str = ""


If `nex.version` >= 30800:
If `revision` >= 3:
refer_gid: int = 0
user_password_enabled: bool = False
system_password_enabled: bool = False



If `nex.version` >= 40000:
progress_score: int = 100
session_key: bytes = b""
option: int = 0
param: [MatchmakeParam](#matchmakeparam) = [MatchmakeParam](#matchmakeparam)()
started_time: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).never()
user_password: str = ""
refer_gid: int = 0
user_password_enabled: bool = False
system_password_enabled: bool = False
codeword: str = ""


## MatchmakeSessionSearchCriteria **def _\_init__**()
Creates a new `MatchmakeSessionSearchCriteria` instance. Required fields must be filled in manually. The following fields are defined in this class:
attribs: list[str] = ["", "", "", "", "", ""]
game_mode: str = ""
min_participants: str = ""
max_participants: str = ""
matchmake_system: str = ""
vacant_only: bool = True
exclude_locked: bool = True
exclude_non_host_pid: bool = False
selection_method: int = 0
If `nex.version` >= 30500:
vacant_participants: int = 1

If `nex.version` >= 40000:
param: [MatchmakeParam](#matchmakeparam) = [MatchmakeParam](#matchmakeparam)()
exclude_user_password: bool = False
exclude_system_password: bool = False
refer_gid: int = 0
codeword: str = ""
range: [ResultRange](common.md#resultrange) = [ResultRange](common.md#resultrange)()


## ParticipantDetails **def _\_init__**()
Creates a new `ParticipantDetails` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
name: str
message: str
participants: int

## PersistentGathering **def _\_init__**()
Creates a new `PersistentGathering` instance. Required fields must be filled in manually. The following fields are defined in this class:
type: int
password: str
attribs: list[int]
application_buffer: bytes
participation_start: [DateTime](common.md#datetime)
participation_end: [DateTime](common.md#datetime)
matchmake_session_count: int
num_participants: int

## PlayingSession **def _\_init__**()
Creates a new `PlayingSession` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
gathering: [Gathering](#gathering)

## SimpleCommunity **def _\_init__**()
Creates a new `SimpleCommunity` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
matchmake_session_count: int

## SimplePlayingSession **def _\_init__**()
Creates a new `SimplePlayingSession` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
gid: int
game_mode: int
attribute: int

## UpdateMatchmakeSessionParam **def _\_init__**()
Creates a new `UpdateMatchmakeSessionParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
modification_flags: int
attributes: list[int]
open_participation: bool
application_buffer: bytes
progress_score: int
param: [MatchmakeParam](#matchmakeparam) = [MatchmakeParam](#matchmakeparam)()
started_time: [DateTime](common.md#datetime)
user_password: str
game_mode: int
description: str
min_participants: int
max_participants: int
matchmake_system: int
participation_policy: int
policy_argument: int
codeword: str

================================================ FILE: docs/reference/nex/matchmaking_mhxx.md ================================================ # Module: nintendo.nex.matchmaking_mhxx Provides a client and server for the `MatchMakingProtocol`, `MatchMakingProtocolExt`, `MatchmakeRefereeProtocol` and `MatchmakeExtensionProtocolMHXX`. This page was generated automatically from `matchmaking_mhxx.proto`. **class** [MatchMakingClient](#matchmakingclient)
The client for the `MatchMakingProtocol`. **class** [MatchMakingClientExt](#matchmakingclientext)
The client for the `MatchMakingProtocolExt`. **class** [MatchmakeRefereeClient](#matchmakerefereeclient)
The client for the `MatchmakeRefereeProtocol`. **class** [MatchmakeExtensionClientMHXX](#matchmakeextensionclientmhxx)
The client for the `MatchmakeExtensionProtocolMHXX`. **class** [MatchMakingServer](#matchmakingserver)
The server for the `MatchMakingProtocol`. **class** [MatchMakingServerExt](#matchmakingserverext)
The server for the `MatchMakingProtocolExt`. **class** [MatchmakeRefereeServer](#matchmakerefereeserver)
The server for the `MatchmakeRefereeProtocol`. **class** [MatchmakeExtensionServerMHXX](#matchmakeextensionservermhxx)
The server for the `MatchmakeExtensionProtocolMHXX`. **class** [MatchmakeSystem](#matchmakesystem)
**class** [AutoMatchmakeParam](#automatchmakeparam)([Structure](common.md))
**class** [CreateMatchmakeSessionParam](#creatematchmakesessionparam)([Structure](common.md))
**class** [DeletionEntry](#deletionentry)([Structure](common.md))
**class** [FindMatchmakeSessionByParticipantParam](#findmatchmakesessionbyparticipantparam)([Structure](common.md))
**class** [FindMatchmakeSessionByParticipantResult](#findmatchmakesessionbyparticipantresult)([Structure](common.md))
**class** [FriendUserInfo](#frienduserinfo)([Structure](common.md))
**class** [FriendUserParam](#frienduserparam)([Structure](common.md))
**class** [Gathering](#gathering)([Structure](common.md))
**class** [GatheringStats](#gatheringstats)([Structure](common.md))
**class** [GatheringURLs](#gatheringurls)([Structure](common.md))
**class** [Invitation](#invitation)([Structure](common.md))
**class** [JoinMatchmakeSessionParam](#joinmatchmakesessionparam)([Structure](common.md))
**class** [MatchmakeBlockListParam](#matchmakeblocklistparam)([Structure](common.md))
**class** [MatchmakeParam](#matchmakeparam)([Structure](common.md))
**class** [MatchmakeRefereeEndRoundParam](#matchmakerefereeendroundparam)([Structure](common.md))
**class** [MatchmakeRefereePersonalRoundResult](#matchmakerefereepersonalroundresult)([Structure](common.md))
**class** [MatchmakeRefereeRound](#matchmakerefereeround)([Structure](common.md))
**class** [MatchmakeRefereeStartRoundParam](#matchmakerefereestartroundparam)([Structure](common.md))
**class** [MatchmakeRefereeStats](#matchmakerefereestats)([Structure](common.md))
**class** [MatchmakeRefereeStatsInitParam](#matchmakerefereestatsinitparam)([Structure](common.md))
**class** [MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)([Structure](common.md))
**class** [MatchmakeSession](#matchmakesession)([Gathering](#gathering))
**class** [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)([Structure](common.md))
**class** [ParticipantDetails](#participantdetails)([Structure](common.md))
**class** [PersistentGathering](#persistentgathering)([Gathering](#gathering))
**class** [PlayingSession](#playingsession)([Structure](common.md))
**class** [SimpleCommunity](#simplecommunity)([Structure](common.md))
**class** [SimplePlayingSession](#simpleplayingsession)([Structure](common.md))
**class** [UpdateMatchmakeSessionParam](#updatematchmakesessionparam)([Structure](common.md))
## MatchMakingClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`MatchMakingClient`](#matchmakingclient). **async def register_gathering**(gathering: [Gathering](#gathering)) -> int
Calls method `1` on the server. **async def unregister_gathering**(gid: int) -> bool
Calls method `2` on the server. **async def unregister_gatherings**(gids: list[int]) -> bool
Calls method `3` on the server. **async def update_gathering**(gathering: [Gathering](#gathering)) -> bool
Calls method `4` on the server. **async def invite**(gid: int, pids: list[int], message: str) -> bool
Calls method `5` on the server. **async def accept_invitation**(gid: int, message: str) -> bool
Calls method `6` on the server. **async def decline_invitation**(gid: int, message: str) -> bool
Calls method `7` on the server. **async def cancel_invitation**(gid: int, pids: list[int], message: str) -> bool
Calls method `8` on the server. **async def get_invitations_sent**(gid: int) -> list[[Invitation](#invitation)]
Calls method `9` on the server. **async def get_invitations_received**() -> list[[Invitation](#invitation)]
Calls method `10` on the server. **async def participate**(gid: int, message: str) -> bool
Calls method `11` on the server. **async def cancel_participation**(gid: int, message: str) -> bool
Calls method `12` on the server. **async def get_participants**(gid: int) -> list[int]
Calls method `13` on the server. **async def add_participants**(gid: int, pids: list[int], message: str) -> bool
Calls method `14` on the server. **async def get_detailed_participants**(gid: int) -> list[[ParticipantDetails](#participantdetails)]
Calls method `15` on the server. **async def get_participants_urls**(gid: int) -> list[[StationURL](common.md#stationurl)]
Calls method `16` on the server. **async def find_by_type**(type: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `17` on the server. **async def find_by_description**(description: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `18` on the server. **async def find_by_description_regex**(regex: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `19` on the server. **async def find_by_id**(ids: list[int]) -> list[[Gathering](#gathering)]
Calls method `20` on the server. **async def find_by_single_id**(gid: int) -> [RMCResponse](common.md)
Calls method `21` on the server. The RMC response has the following attributes:
result: bool
gathering: [Gathering](#gathering)
**async def find_by_owner**(owner: int, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `22` on the server. **async def find_by_participants**(pids: list[int]) -> list[[Gathering](#gathering)]
Calls method `23` on the server. **async def find_invitations**(range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `24` on the server. **async def find_by_sql_query**(query: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `25` on the server. **async def launch_session**(gid: int, url: str) -> bool
Calls method `26` on the server. **async def update_session_url**(gid: int, url: str) -> bool
Calls method `27` on the server. **async def get_session_url**(gid: int) -> [RMCResponse](common.md)
Calls method `28` on the server. The RMC response has the following attributes:
result: bool
url: str
**async def get_state**(gid: int) -> [RMCResponse](common.md)
Calls method `29` on the server. The RMC response has the following attributes:
result: bool
state: int
**async def set_state**(gid: int, state: int) -> bool
Calls method `30` on the server. **async def report_stats**(gid: int, stats: list[[GatheringStats](#gatheringstats)]) -> bool
Calls method `31` on the server. **async def get_stats**(gid: int, pids: list[int], columns: list[int]) -> [RMCResponse](common.md)
Calls method `32` on the server. The RMC response has the following attributes:
result: bool
stats: list[[GatheringStats](#gatheringstats)]
**async def delete_gathering**(gid: int) -> bool
Calls method `33` on the server. **async def get_pending_deletions**(reason: int, range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Calls method `34` on the server. The RMC response has the following attributes:
result: bool
deletions: list[[DeletionEntry](#deletionentry)]
**async def delete_from_deletions**(deletions: list[int]) -> bool
Calls method `35` on the server. **async def migrate_gathering_ownership_v1**(gid: int, potential_owners: list[int]) -> bool
Calls method `36` on the server. **async def find_by_description_like**(description: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `37` on the server. **async def register_local_url**(gid: int, url: [StationURL](common.md#stationurl)) -> None
Calls method `38` on the server. **async def register_local_urls**(gid: int, urls: list[[StationURL](common.md#stationurl)]) -> None
Calls method `39` on the server. **async def update_session_host_v1**(gid: int) -> None
Calls method `40` on the server. **async def get_session_urls**(gid: int) -> list[[StationURL](common.md#stationurl)]
Calls method `41` on the server. **async def update_session_host**(gid: int, is_migrate_owner: bool) -> None
Calls method `42` on the server. **async def update_gathering_ownership**(gid: int, participants_only: bool) -> bool
Calls method `43` on the server. **async def migrate_gathering_ownership**(gid: int, potential_owners: list[int], participants_only: bool) -> None
Calls method `44` on the server. ## MatchMakingClientExt **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`MatchMakingClientExt`](#matchmakingclientext). **async def end_participation**(gid: int, message: str) -> bool
Calls method `1` on the server. **async def get_participants**(gid: int, only_active: bool) -> list[int]
Calls method `2` on the server. **async def get_detailed_participants**(gid: int, only_active: bool) -> list[[ParticipantDetails](#participantdetails)]
Calls method `3` on the server. **async def get_participants_urls**(gids: list[int]) -> list[[GatheringURLs](#gatheringurls)]
Calls method `4` on the server. **async def get_gathering_relations**(id: int, descr: str) -> str
Calls method `5` on the server. **async def delete_from_deletions**(deletions: list[int], pid: int) -> None
Calls method `6` on the server. ## MatchmakeRefereeClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`MatchmakeRefereeClient`](#matchmakerefereeclient). **async def start_round**(param: [MatchmakeRefereeStartRoundParam](#matchmakerefereestartroundparam)) -> int
Calls method `1` on the server. **async def get_start_round_param**(round_id: int) -> [MatchmakeRefereeStartRoundParam](#matchmakerefereestartroundparam)
Calls method `2` on the server. **async def end_round**(param: [MatchmakeRefereeEndRoundParam](#matchmakerefereeendroundparam)) -> None
Calls method `3` on the server. **async def end_round_without_report**(round_id: int) -> None
Calls method `4` on the server. **async def get_round_participants**(round_id: int) -> list[int]
Calls method `5` on the server. **async def get_not_summarized_round**() -> list[[MatchmakeRefereeRound](#matchmakerefereeround)]
Calls method `6` on the server. **async def get_round**(round: int) -> [MatchmakeRefereeRound](#matchmakerefereeround)
Calls method `7` on the server. **async def get_stats_primary**(target: [MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Calls method `8` on the server. **async def get_stats_primaries**(targets: list[[MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)]) -> [RMCResponse](common.md)
Calls method `9` on the server. The RMC response has the following attributes:
stats: list[[MatchmakeRefereeStats](#matchmakerefereestats)]
results: list[[Result](common.md#result)]
**async def get_stats_all**(target: [MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)) -> list[[MatchmakeRefereeStats](#matchmakerefereestats)]
Calls method `10` on the server. **async def create_stats**(param: [MatchmakeRefereeStatsInitParam](#matchmakerefereestatsinitparam)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Calls method `11` on the server. **async def get_or_create_stats**(param: [MatchmakeRefereeStatsInitParam](#matchmakerefereestatsinitparam)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Calls method `12` on the server. **async def reset_stats**() -> None
Calls method `13` on the server. ## MatchmakeExtensionClientMHXX **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`MatchmakeExtensionClientMHXX`](#matchmakeextensionclientmhxx). **async def close_participation**(gid: int) -> None
Calls method `1` on the server. **async def open_participation**(gid: int) -> None
Calls method `2` on the server. **async def auto_matchmake_postpone**(gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Calls method `3` on the server. **async def browse_matchmake_session**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `4` on the server. **async def browse_matchmake_session_with_host_urls**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Calls method `5` on the server. The RMC response has the following attributes:
gatherings: list[[Gathering](#gathering)]
urls: list[[GatheringURLs](#gatheringurls)]
**async def create_matchmake_session**(gathering: [Gathering](#gathering), description: str, num_participants: int) -> [RMCResponse](common.md)
Calls method `6` on the server. The RMC response has the following attributes:
gid: int
session_key: bytes
**async def join_matchmake_session**(gid: int, message: str) -> bytes
Calls method `7` on the server. **async def modify_current_game_attribute**(gid: int, attrib: int, value: int) -> None
Calls method `8` on the server. **async def update_notification_data**(type: int, param1: int, param2: int, param3: str) -> None
Calls method `9` on the server. **async def get_friend_notification_data**(type: int) -> list[[NotificationEvent](notification.md#notificationevent)]
Calls method `10` on the server. **async def update_application_buffer**(gid: int, buffer: bytes) -> None
Calls method `11` on the server. **async def update_matchmake_session_attribute**(gid: int, attribs: list[int]) -> None
Calls method `12` on the server. **async def get_friend_notification_data_list**(types: list[int]) -> list[[NotificationEvent](notification.md#notificationevent)]
Calls method `13` on the server. **async def update_matchmake_session**(gathering: [Gathering](#gathering)) -> None
Calls method `14` on the server. **async def auto_matchmake_with_search_criteria_postpone**(search_criteria: list[[MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)], gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Calls method `15` on the server. **async def get_playing_session**(pids: list[int]) -> list[[PlayingSession](#playingsession)]
Calls method `16` on the server. **async def create_community**(community: [PersistentGathering](#persistentgathering), message: str) -> int
Calls method `17` on the server. **async def update_community**(community: [PersistentGathering](#persistentgathering)) -> None
Calls method `18` on the server. **async def join_community**(gid: int, message: str, password: str) -> None
Calls method `19` on the server. **async def find_community_by_gathering_id**(gids: list[int]) -> list[[PersistentGathering](#persistentgathering)]
Calls method `20` on the server. **async def find_official_community**(available_only: bool, range: [ResultRange](common.md#resultrange)) -> list[[PersistentGathering](#persistentgathering)]
Calls method `21` on the server. **async def find_community_by_participant**(pid: int, range: [ResultRange](common.md#resultrange)) -> list[[PersistentGathering](#persistentgathering)]
Calls method `22` on the server. **async def update_privacy_setting**(online_status: bool, community_participation: bool) -> None
Calls method `23` on the server. **async def get_my_block_list**() -> list[int]
Calls method `24` on the server. **async def add_to_block_list**(pids: list[int]) -> None
Calls method `25` on the server. **async def remove_from_block_list**(pids: list[int]) -> None
Calls method `26` on the server. **async def clear_my_block_list**() -> None
Calls method `27` on the server. **async def report_violation**(pid: int, username: str, violation_code: int) -> None
Calls method `28` on the server. **async def is_violation_user**() -> [RMCResponse](common.md)
Calls method `29` on the server. The RMC response has the following attributes:
flag: bool
score: int
**async def join_matchmake_session_ex**(gid: int, gmessage: str, ignore_block_list: bool, num_participants: int) -> bytes
Calls method `30` on the server. **async def get_simple_playing_session**(pids: list[int], include_login_user: bool) -> list[[SimplePlayingSession](#simpleplayingsession)]
Calls method `31` on the server. **async def get_simple_community**(gids: list[int]) -> list[[SimpleCommunity](#simplecommunity)]
Calls method `32` on the server. **async def auto_matchmake_with_gathering_id_postpone**(gids: list[int], gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Calls method `33` on the server. **async def update_progress_score**(gid: int, score: int) -> None
Calls method `34` on the server. **async def debug_notify_event**(pid: int, main_type: int, sub_type: int, param1: int, param2: int, param3: str) -> None
Calls method `35` on the server. **async def generate_matchmake_session_system_password**(gid: int) -> str
Calls method `36` on the server. **async def clear_matchmake_session_system_password**(gid: int) -> None
Calls method `37` on the server. **async def create_matchmake_session_with_param**(param: [CreateMatchmakeSessionParam](#creatematchmakesessionparam)) -> [MatchmakeSession](#matchmakesession)
Calls method `38` on the server. **async def join_matchmake_session_with_param**(param: [JoinMatchmakeSessionParam](#joinmatchmakesessionparam)) -> [MatchmakeSession](#matchmakesession)
Calls method `39` on the server. **async def auto_matchmake_with_param_postpone**(param: [AutoMatchmakeParam](#automatchmakeparam)) -> [MatchmakeSession](#matchmakesession)
Calls method `40` on the server. **async def find_matchmake_session_by_gathering_id_detail**(gid: int) -> [MatchmakeSession](#matchmakesession)
Calls method `41` on the server. **async def browse_matchmake_session_no_holder**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> list[[MatchmakeSession](#matchmakesession)]
Calls method `42` on the server. **async def browse_matchmake_session_with_host_urls_no_holder**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Calls method `43` on the server. The RMC response has the following attributes:
sessions: list[[MatchmakeSession](#matchmakesession)]
urls: list[[GatheringURLs](#gatheringurls)]
**async def update_matchmake_session_part**(param: [UpdateMatchmakeSessionParam](#updatematchmakesessionparam)) -> None
Calls method `44` on the server. **async def request_matchmaking**(param: [AutoMatchmakeParam](#automatchmakeparam)) -> int
Calls method `45` on the server. **async def withdraw_matchmaking**(request_id: int) -> None
Calls method `46` on the server. **async def withdraw_matchmaking_all**() -> None
Calls method `47` on the server. **async def find_matchmake_session_by_gathering_id**(gids: list[int]) -> list[[MatchmakeSession](#matchmakesession)]
Calls method `48` on the server. **async def find_matchmake_session_by_single_gathering_id**(gid: int) -> [MatchmakeSession](#matchmakesession)
Calls method `49` on the server. **async def find_matchmake_session_by_owner**(pid: int, range: [ResultRange](common.md#resultrange)) -> list[[MatchmakeSession](#matchmakesession)]
Calls method `50` on the server. **async def find_matchmake_session_by_participant**(param: [FindMatchmakeSessionByParticipantParam](#findmatchmakesessionbyparticipantparam)) -> list[[FindMatchmakeSessionByParticipantResult](#findmatchmakesessionbyparticipantresult)]
Calls method `51` on the server. **async def browse_matchmake_session_no_holder_no_result_range**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)) -> list[[MatchmakeSession](#matchmakesession)]
Calls method `52` on the server. **async def browse_matchmake_session_with_host_urls_no_holder_no_result_range**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)) -> [RMCResponse](common.md)
Calls method `53` on the server. The RMC response has the following attributes:
sessions: list[[MatchmakeSession](#matchmakesession)]
urls: list[[GatheringURLs](#gatheringurls)]
**async def update_friend_user_profile**(param: [FriendUserParam](#frienduserparam)) -> None
Calls method `54` on the server. **async def get_friend_user_profiles**(pids: list[int]) -> list[[FriendUserInfo](#frienduserinfo)]
Calls method `55` on the server. **async def get_friends**() -> list[[FriendUserInfo](#frienduserinfo)]
Calls method `56` on the server. **async def add_friends**(pids: list[int]) -> None
Calls method `57` on the server. **async def remove_friend**(pid: int) -> None
Calls method `58` on the server. **async def find_community_by_owner**(id: int, range: [ResultRange](common.md#resultrange)) -> list[[PersistentGathering](#persistentgathering)]
Calls method `59` on the server. ## MatchMakingServer **def _\_init__**()
Creates a new [`MatchMakingServer`](#matchmakingserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def register_gathering**(client: [RMCClient](rmc.md#rmcclient), gathering: [Gathering](#gathering)) -> int
Handler for method `1`. This method should be overridden by a subclass. **async def unregister_gathering**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> bool
Handler for method `2`. This method should be overridden by a subclass. **async def unregister_gatherings**(client: [RMCClient](rmc.md#rmcclient), gids: list[int]) -> bool
Handler for method `3`. This method should be overridden by a subclass. **async def update_gathering**(client: [RMCClient](rmc.md#rmcclient), gathering: [Gathering](#gathering)) -> bool
Handler for method `4`. This method should be overridden by a subclass. **async def invite**(client: [RMCClient](rmc.md#rmcclient), gid: int, pids: list[int], message: str) -> bool
Handler for method `5`. This method should be overridden by a subclass. **async def accept_invitation**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bool
Handler for method `6`. This method should be overridden by a subclass. **async def decline_invitation**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bool
Handler for method `7`. This method should be overridden by a subclass. **async def cancel_invitation**(client: [RMCClient](rmc.md#rmcclient), gid: int, pids: list[int], message: str) -> bool
Handler for method `8`. This method should be overridden by a subclass. **async def get_invitations_sent**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> list[[Invitation](#invitation)]
Handler for method `9`. This method should be overridden by a subclass. **async def get_invitations_received**(client: [RMCClient](rmc.md#rmcclient)) -> list[[Invitation](#invitation)]
Handler for method `10`. This method should be overridden by a subclass. **async def participate**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bool
Handler for method `11`. This method should be overridden by a subclass. **async def cancel_participation**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bool
Handler for method `12`. This method should be overridden by a subclass. **async def get_participants**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> list[int]
Handler for method `13`. This method should be overridden by a subclass. **async def add_participants**(client: [RMCClient](rmc.md#rmcclient), gid: int, pids: list[int], message: str) -> bool
Handler for method `14`. This method should be overridden by a subclass. **async def get_detailed_participants**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> list[[ParticipantDetails](#participantdetails)]
Handler for method `15`. This method should be overridden by a subclass. **async def get_participants_urls**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> list[[StationURL](common.md#stationurl)]
Handler for method `16`. This method should be overridden by a subclass. **async def find_by_type**(client: [RMCClient](rmc.md#rmcclient), type: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `17`. This method should be overridden by a subclass. **async def find_by_description**(client: [RMCClient](rmc.md#rmcclient), description: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `18`. This method should be overridden by a subclass. **async def find_by_description_regex**(client: [RMCClient](rmc.md#rmcclient), regex: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `19`. This method should be overridden by a subclass. **async def find_by_id**(client: [RMCClient](rmc.md#rmcclient), ids: list[int]) -> list[[Gathering](#gathering)]
Handler for method `20`. This method should be overridden by a subclass. **async def find_by_single_id**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> [RMCResponse](common.md)
Handler for method `21`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
gathering: [Gathering](#gathering)
**async def find_by_owner**(client: [RMCClient](rmc.md#rmcclient), owner: int, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `22`. This method should be overridden by a subclass. **async def find_by_participants**(client: [RMCClient](rmc.md#rmcclient), pids: list[int]) -> list[[Gathering](#gathering)]
Handler for method `23`. This method should be overridden by a subclass. **async def find_invitations**(client: [RMCClient](rmc.md#rmcclient), range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `24`. This method should be overridden by a subclass. **async def find_by_sql_query**(client: [RMCClient](rmc.md#rmcclient), query: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `25`. This method should be overridden by a subclass. **async def launch_session**(client: [RMCClient](rmc.md#rmcclient), gid: int, url: str) -> bool
Handler for method `26`. This method should be overridden by a subclass. **async def update_session_url**(client: [RMCClient](rmc.md#rmcclient), gid: int, url: str) -> bool
Handler for method `27`. This method should be overridden by a subclass. **async def get_session_url**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> [RMCResponse](common.md)
Handler for method `28`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
url: str
**async def get_state**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> [RMCResponse](common.md)
Handler for method `29`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
state: int
**async def set_state**(client: [RMCClient](rmc.md#rmcclient), gid: int, state: int) -> bool
Handler for method `30`. This method should be overridden by a subclass. **async def report_stats**(client: [RMCClient](rmc.md#rmcclient), gid: int, stats: list[[GatheringStats](#gatheringstats)]) -> bool
Handler for method `31`. This method should be overridden by a subclass. **async def get_stats**(client: [RMCClient](rmc.md#rmcclient), gid: int, pids: list[int], columns: list[int]) -> [RMCResponse](common.md)
Handler for method `32`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
stats: list[[GatheringStats](#gatheringstats)]
**async def delete_gathering**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> bool
Handler for method `33`. This method should be overridden by a subclass. **async def get_pending_deletions**(client: [RMCClient](rmc.md#rmcclient), reason: int, range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Handler for method `34`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
deletions: list[[DeletionEntry](#deletionentry)]
**async def delete_from_deletions**(client: [RMCClient](rmc.md#rmcclient), deletions: list[int]) -> bool
Handler for method `35`. This method should be overridden by a subclass. **async def migrate_gathering_ownership_v1**(client: [RMCClient](rmc.md#rmcclient), gid: int, potential_owners: list[int]) -> bool
Handler for method `36`. This method should be overridden by a subclass. **async def find_by_description_like**(client: [RMCClient](rmc.md#rmcclient), description: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `37`. This method should be overridden by a subclass. **async def register_local_url**(client: [RMCClient](rmc.md#rmcclient), gid: int, url: [StationURL](common.md#stationurl)) -> None
Handler for method `38`. This method should be overridden by a subclass. **async def register_local_urls**(client: [RMCClient](rmc.md#rmcclient), gid: int, urls: list[[StationURL](common.md#stationurl)]) -> None
Handler for method `39`. This method should be overridden by a subclass. **async def update_session_host_v1**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> None
Handler for method `40`. This method should be overridden by a subclass. **async def get_session_urls**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> list[[StationURL](common.md#stationurl)]
Handler for method `41`. This method should be overridden by a subclass. **async def update_session_host**(client: [RMCClient](rmc.md#rmcclient), gid: int, is_migrate_owner: bool) -> None
Handler for method `42`. This method should be overridden by a subclass. **async def update_gathering_ownership**(client: [RMCClient](rmc.md#rmcclient), gid: int, participants_only: bool) -> bool
Handler for method `43`. This method should be overridden by a subclass. **async def migrate_gathering_ownership**(client: [RMCClient](rmc.md#rmcclient), gid: int, potential_owners: list[int], participants_only: bool) -> None
Handler for method `44`. This method should be overridden by a subclass. ## MatchMakingServerExt **def _\_init__**()
Creates a new [`MatchMakingServerExt`](#matchmakingserverext). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def end_participation**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bool
Handler for method `1`. This method should be overridden by a subclass. **async def get_participants**(client: [RMCClient](rmc.md#rmcclient), gid: int, only_active: bool) -> list[int]
Handler for method `2`. This method should be overridden by a subclass. **async def get_detailed_participants**(client: [RMCClient](rmc.md#rmcclient), gid: int, only_active: bool) -> list[[ParticipantDetails](#participantdetails)]
Handler for method `3`. This method should be overridden by a subclass. **async def get_participants_urls**(client: [RMCClient](rmc.md#rmcclient), gids: list[int]) -> list[[GatheringURLs](#gatheringurls)]
Handler for method `4`. This method should be overridden by a subclass. **async def get_gathering_relations**(client: [RMCClient](rmc.md#rmcclient), id: int, descr: str) -> str
Handler for method `5`. This method should be overridden by a subclass. **async def delete_from_deletions**(client: [RMCClient](rmc.md#rmcclient), deletions: list[int], pid: int) -> None
Handler for method `6`. This method should be overridden by a subclass. ## MatchmakeRefereeServer **def _\_init__**()
Creates a new [`MatchmakeRefereeServer`](#matchmakerefereeserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def start_round**(client: [RMCClient](rmc.md#rmcclient), param: [MatchmakeRefereeStartRoundParam](#matchmakerefereestartroundparam)) -> int
Handler for method `1`. This method should be overridden by a subclass. **async def get_start_round_param**(client: [RMCClient](rmc.md#rmcclient), round_id: int) -> [MatchmakeRefereeStartRoundParam](#matchmakerefereestartroundparam)
Handler for method `2`. This method should be overridden by a subclass. **async def end_round**(client: [RMCClient](rmc.md#rmcclient), param: [MatchmakeRefereeEndRoundParam](#matchmakerefereeendroundparam)) -> None
Handler for method `3`. This method should be overridden by a subclass. **async def end_round_without_report**(client: [RMCClient](rmc.md#rmcclient), round_id: int) -> None
Handler for method `4`. This method should be overridden by a subclass. **async def get_round_participants**(client: [RMCClient](rmc.md#rmcclient), round_id: int) -> list[int]
Handler for method `5`. This method should be overridden by a subclass. **async def get_not_summarized_round**(client: [RMCClient](rmc.md#rmcclient)) -> list[[MatchmakeRefereeRound](#matchmakerefereeround)]
Handler for method `6`. This method should be overridden by a subclass. **async def get_round**(client: [RMCClient](rmc.md#rmcclient), round: int) -> [MatchmakeRefereeRound](#matchmakerefereeround)
Handler for method `7`. This method should be overridden by a subclass. **async def get_stats_primary**(client: [RMCClient](rmc.md#rmcclient), target: [MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Handler for method `8`. This method should be overridden by a subclass. **async def get_stats_primaries**(client: [RMCClient](rmc.md#rmcclient), targets: list[[MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)]) -> [RMCResponse](common.md)
Handler for method `9`. This method should be overridden by a subclass. The RMC response must have the following attributes:
stats: list[[MatchmakeRefereeStats](#matchmakerefereestats)]
results: list[[Result](common.md#result)]
**async def get_stats_all**(client: [RMCClient](rmc.md#rmcclient), target: [MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)) -> list[[MatchmakeRefereeStats](#matchmakerefereestats)]
Handler for method `10`. This method should be overridden by a subclass. **async def create_stats**(client: [RMCClient](rmc.md#rmcclient), param: [MatchmakeRefereeStatsInitParam](#matchmakerefereestatsinitparam)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Handler for method `11`. This method should be overridden by a subclass. **async def get_or_create_stats**(client: [RMCClient](rmc.md#rmcclient), param: [MatchmakeRefereeStatsInitParam](#matchmakerefereestatsinitparam)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Handler for method `12`. This method should be overridden by a subclass. **async def reset_stats**(client: [RMCClient](rmc.md#rmcclient)) -> None
Handler for method `13`. This method should be overridden by a subclass. ## MatchmakeExtensionServerMHXX **def _\_init__**()
Creates a new [`MatchmakeExtensionServerMHXX`](#matchmakeextensionservermhxx). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def close_participation**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> None
Handler for method `1`. This method should be overridden by a subclass. **async def open_participation**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> None
Handler for method `2`. This method should be overridden by a subclass. **async def auto_matchmake_postpone**(client: [RMCClient](rmc.md#rmcclient), gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Handler for method `3`. This method should be overridden by a subclass. **async def browse_matchmake_session**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `4`. This method should be overridden by a subclass. **async def browse_matchmake_session_with_host_urls**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Handler for method `5`. This method should be overridden by a subclass. The RMC response must have the following attributes:
gatherings: list[[Gathering](#gathering)]
urls: list[[GatheringURLs](#gatheringurls)]
**async def create_matchmake_session**(client: [RMCClient](rmc.md#rmcclient), gathering: [Gathering](#gathering), description: str, num_participants: int) -> [RMCResponse](common.md)
Handler for method `6`. This method should be overridden by a subclass. The RMC response must have the following attributes:
gid: int
session_key: bytes
**async def join_matchmake_session**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bytes
Handler for method `7`. This method should be overridden by a subclass. **async def modify_current_game_attribute**(client: [RMCClient](rmc.md#rmcclient), gid: int, attrib: int, value: int) -> None
Handler for method `8`. This method should be overridden by a subclass. **async def update_notification_data**(client: [RMCClient](rmc.md#rmcclient), type: int, param1: int, param2: int, param3: str) -> None
Handler for method `9`. This method should be overridden by a subclass. **async def get_friend_notification_data**(client: [RMCClient](rmc.md#rmcclient), type: int) -> list[[NotificationEvent](notification.md#notificationevent)]
Handler for method `10`. This method should be overridden by a subclass. **async def update_application_buffer**(client: [RMCClient](rmc.md#rmcclient), gid: int, buffer: bytes) -> None
Handler for method `11`. This method should be overridden by a subclass. **async def update_matchmake_session_attribute**(client: [RMCClient](rmc.md#rmcclient), gid: int, attribs: list[int]) -> None
Handler for method `12`. This method should be overridden by a subclass. **async def get_friend_notification_data_list**(client: [RMCClient](rmc.md#rmcclient), types: list[int]) -> list[[NotificationEvent](notification.md#notificationevent)]
Handler for method `13`. This method should be overridden by a subclass. **async def update_matchmake_session**(client: [RMCClient](rmc.md#rmcclient), gathering: [Gathering](#gathering)) -> None
Handler for method `14`. This method should be overridden by a subclass. **async def auto_matchmake_with_search_criteria_postpone**(client: [RMCClient](rmc.md#rmcclient), search_criteria: list[[MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)], gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Handler for method `15`. This method should be overridden by a subclass. **async def get_playing_session**(client: [RMCClient](rmc.md#rmcclient), pids: list[int]) -> list[[PlayingSession](#playingsession)]
Handler for method `16`. This method should be overridden by a subclass. **async def create_community**(client: [RMCClient](rmc.md#rmcclient), community: [PersistentGathering](#persistentgathering), message: str) -> int
Handler for method `17`. This method should be overridden by a subclass. **async def update_community**(client: [RMCClient](rmc.md#rmcclient), community: [PersistentGathering](#persistentgathering)) -> None
Handler for method `18`. This method should be overridden by a subclass. **async def join_community**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str, password: str) -> None
Handler for method `19`. This method should be overridden by a subclass. **async def find_community_by_gathering_id**(client: [RMCClient](rmc.md#rmcclient), gids: list[int]) -> list[[PersistentGathering](#persistentgathering)]
Handler for method `20`. This method should be overridden by a subclass. **async def find_official_community**(client: [RMCClient](rmc.md#rmcclient), available_only: bool, range: [ResultRange](common.md#resultrange)) -> list[[PersistentGathering](#persistentgathering)]
Handler for method `21`. This method should be overridden by a subclass. **async def find_community_by_participant**(client: [RMCClient](rmc.md#rmcclient), pid: int, range: [ResultRange](common.md#resultrange)) -> list[[PersistentGathering](#persistentgathering)]
Handler for method `22`. This method should be overridden by a subclass. **async def update_privacy_setting**(client: [RMCClient](rmc.md#rmcclient), online_status: bool, community_participation: bool) -> None
Handler for method `23`. This method should be overridden by a subclass. **async def get_my_block_list**(client: [RMCClient](rmc.md#rmcclient)) -> list[int]
Handler for method `24`. This method should be overridden by a subclass. **async def add_to_block_list**(client: [RMCClient](rmc.md#rmcclient), pids: list[int]) -> None
Handler for method `25`. This method should be overridden by a subclass. **async def remove_from_block_list**(client: [RMCClient](rmc.md#rmcclient), pids: list[int]) -> None
Handler for method `26`. This method should be overridden by a subclass. **async def clear_my_block_list**(client: [RMCClient](rmc.md#rmcclient)) -> None
Handler for method `27`. This method should be overridden by a subclass. **async def report_violation**(client: [RMCClient](rmc.md#rmcclient), pid: int, username: str, violation_code: int) -> None
Handler for method `28`. This method should be overridden by a subclass. **async def is_violation_user**(client: [RMCClient](rmc.md#rmcclient)) -> [RMCResponse](common.md)
Handler for method `29`. This method should be overridden by a subclass. The RMC response must have the following attributes:
flag: bool
score: int
**async def join_matchmake_session_ex**(client: [RMCClient](rmc.md#rmcclient), gid: int, gmessage: str, ignore_block_list: bool, num_participants: int) -> bytes
Handler for method `30`. This method should be overridden by a subclass. **async def get_simple_playing_session**(client: [RMCClient](rmc.md#rmcclient), pids: list[int], include_login_user: bool) -> list[[SimplePlayingSession](#simpleplayingsession)]
Handler for method `31`. This method should be overridden by a subclass. **async def get_simple_community**(client: [RMCClient](rmc.md#rmcclient), gids: list[int]) -> list[[SimpleCommunity](#simplecommunity)]
Handler for method `32`. This method should be overridden by a subclass. **async def auto_matchmake_with_gathering_id_postpone**(client: [RMCClient](rmc.md#rmcclient), gids: list[int], gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Handler for method `33`. This method should be overridden by a subclass. **async def update_progress_score**(client: [RMCClient](rmc.md#rmcclient), gid: int, score: int) -> None
Handler for method `34`. This method should be overridden by a subclass. **async def debug_notify_event**(client: [RMCClient](rmc.md#rmcclient), pid: int, main_type: int, sub_type: int, param1: int, param2: int, param3: str) -> None
Handler for method `35`. This method should be overridden by a subclass. **async def generate_matchmake_session_system_password**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> str
Handler for method `36`. This method should be overridden by a subclass. **async def clear_matchmake_session_system_password**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> None
Handler for method `37`. This method should be overridden by a subclass. **async def create_matchmake_session_with_param**(client: [RMCClient](rmc.md#rmcclient), param: [CreateMatchmakeSessionParam](#creatematchmakesessionparam)) -> [MatchmakeSession](#matchmakesession)
Handler for method `38`. This method should be overridden by a subclass. **async def join_matchmake_session_with_param**(client: [RMCClient](rmc.md#rmcclient), param: [JoinMatchmakeSessionParam](#joinmatchmakesessionparam)) -> [MatchmakeSession](#matchmakesession)
Handler for method `39`. This method should be overridden by a subclass. **async def auto_matchmake_with_param_postpone**(client: [RMCClient](rmc.md#rmcclient), param: [AutoMatchmakeParam](#automatchmakeparam)) -> [MatchmakeSession](#matchmakesession)
Handler for method `40`. This method should be overridden by a subclass. **async def find_matchmake_session_by_gathering_id_detail**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> [MatchmakeSession](#matchmakesession)
Handler for method `41`. This method should be overridden by a subclass. **async def browse_matchmake_session_no_holder**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> list[[MatchmakeSession](#matchmakesession)]
Handler for method `42`. This method should be overridden by a subclass. **async def browse_matchmake_session_with_host_urls_no_holder**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Handler for method `43`. This method should be overridden by a subclass. The RMC response must have the following attributes:
sessions: list[[MatchmakeSession](#matchmakesession)]
urls: list[[GatheringURLs](#gatheringurls)]
**async def update_matchmake_session_part**(client: [RMCClient](rmc.md#rmcclient), param: [UpdateMatchmakeSessionParam](#updatematchmakesessionparam)) -> None
Handler for method `44`. This method should be overridden by a subclass. **async def request_matchmaking**(client: [RMCClient](rmc.md#rmcclient), param: [AutoMatchmakeParam](#automatchmakeparam)) -> int
Handler for method `45`. This method should be overridden by a subclass. **async def withdraw_matchmaking**(client: [RMCClient](rmc.md#rmcclient), request_id: int) -> None
Handler for method `46`. This method should be overridden by a subclass. **async def withdraw_matchmaking_all**(client: [RMCClient](rmc.md#rmcclient)) -> None
Handler for method `47`. This method should be overridden by a subclass. **async def find_matchmake_session_by_gathering_id**(client: [RMCClient](rmc.md#rmcclient), gids: list[int]) -> list[[MatchmakeSession](#matchmakesession)]
Handler for method `48`. This method should be overridden by a subclass. **async def find_matchmake_session_by_single_gathering_id**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> [MatchmakeSession](#matchmakesession)
Handler for method `49`. This method should be overridden by a subclass. **async def find_matchmake_session_by_owner**(client: [RMCClient](rmc.md#rmcclient), pid: int, range: [ResultRange](common.md#resultrange)) -> list[[MatchmakeSession](#matchmakesession)]
Handler for method `50`. This method should be overridden by a subclass. **async def find_matchmake_session_by_participant**(client: [RMCClient](rmc.md#rmcclient), param: [FindMatchmakeSessionByParticipantParam](#findmatchmakesessionbyparticipantparam)) -> list[[FindMatchmakeSessionByParticipantResult](#findmatchmakesessionbyparticipantresult)]
Handler for method `51`. This method should be overridden by a subclass. **async def browse_matchmake_session_no_holder_no_result_range**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)) -> list[[MatchmakeSession](#matchmakesession)]
Handler for method `52`. This method should be overridden by a subclass. **async def browse_matchmake_session_with_host_urls_no_holder_no_result_range**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)) -> [RMCResponse](common.md)
Handler for method `53`. This method should be overridden by a subclass. The RMC response must have the following attributes:
sessions: list[[MatchmakeSession](#matchmakesession)]
urls: list[[GatheringURLs](#gatheringurls)]
**async def update_friend_user_profile**(client: [RMCClient](rmc.md#rmcclient), param: [FriendUserParam](#frienduserparam)) -> None
Handler for method `54`. This method should be overridden by a subclass. **async def get_friend_user_profiles**(client: [RMCClient](rmc.md#rmcclient), pids: list[int]) -> list[[FriendUserInfo](#frienduserinfo)]
Handler for method `55`. This method should be overridden by a subclass. **async def get_friends**(client: [RMCClient](rmc.md#rmcclient)) -> list[[FriendUserInfo](#frienduserinfo)]
Handler for method `56`. This method should be overridden by a subclass. **async def add_friends**(client: [RMCClient](rmc.md#rmcclient), pids: list[int]) -> None
Handler for method `57`. This method should be overridden by a subclass. **async def remove_friend**(client: [RMCClient](rmc.md#rmcclient), pid: int) -> None
Handler for method `58`. This method should be overridden by a subclass. **async def find_community_by_owner**(client: [RMCClient](rmc.md#rmcclient), id: int, range: [ResultRange](common.md#resultrange)) -> list[[PersistentGathering](#persistentgathering)]
Handler for method `59`. This method should be overridden by a subclass. ## MatchmakeSystem This class defines the following constants:
`GLOBAL = 1`
`FRIENDS = 2`
## AutoMatchmakeParam **def _\_init__**()
Creates a new `AutoMatchmakeParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
session: [MatchmakeSession](#matchmakesession) = [MatchmakeSession](#matchmakesession)()
participants: list[int]
gid_for_participation_check: int
options: int
join_message: str
num_participants: int
search_criteria: list[[MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)]
target_gids: list[int]
block_list: [MatchmakeBlockListParam](#matchmakeblocklistparam) = [MatchmakeBlockListParam](#matchmakeblocklistparam)()

## CreateMatchmakeSessionParam **def _\_init__**()
Creates a new `CreateMatchmakeSessionParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
session: [MatchmakeSession](#matchmakesession) = [MatchmakeSession](#matchmakesession)()
additional_participants: list[int]
gid_for_participation_check: int
options: int
join_message: str
num_participants: int

## DeletionEntry **def _\_init__**()
Creates a new `DeletionEntry` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
pid: int
reason: int

## FindMatchmakeSessionByParticipantParam **def _\_init__**()
Creates a new `FindMatchmakeSessionByParticipantParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
pids: list[int]
options: int
block_list: [MatchmakeBlockListParam](#matchmakeblocklistparam) = [MatchmakeBlockListParam](#matchmakeblocklistparam)()

## FindMatchmakeSessionByParticipantResult **def _\_init__**()
Creates a new `FindMatchmakeSessionByParticipantResult` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
session: [MatchmakeSession](#matchmakesession) = [MatchmakeSession](#matchmakesession)()

## FriendUserInfo **def _\_init__**()
Creates a new `FriendUserInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
name: str
presence: int

## FriendUserParam **def _\_init__**()
Creates a new `FriendUserParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
name: str

## Gathering **def _\_init__**()
Creates a new `Gathering` instance. Required fields must be filled in manually. The following fields are defined in this class:
id: int = 0
owner: int = 0
host: int = 0
min_participants: int = 0
max_participants: int = 0
participation_policy: int = 1
policy_argument: int = 0
flags: int = 512
state: int = 0
description: str = ""

## GatheringStats **def _\_init__**()
Creates a new `GatheringStats` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
flags: int
values: list[float]

## GatheringURLs **def _\_init__**()
Creates a new `GatheringURLs` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
urls: list[[StationURL](common.md#stationurl)]

## Invitation **def _\_init__**()
Creates a new `Invitation` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
guest: int
message: str

## JoinMatchmakeSessionParam **def _\_init__**()
Creates a new `JoinMatchmakeSessionParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
participants: list[int]
gid_for_participation_check: int
options: int
behavior: int
user_password: str
system_password: str
join_message: str
num_participants: int
extra_participants: int
block_list: [MatchmakeBlockListParam](#matchmakeblocklistparam) = [MatchmakeBlockListParam](#matchmakeblocklistparam)()

## MatchmakeBlockListParam **def _\_init__**()
Creates a new `MatchmakeBlockListParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
options: int = 0

## MatchmakeParam **def _\_init__**()
Creates a new `MatchmakeParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
param: dict[str, object] = {}

## MatchmakeRefereeEndRoundParam **def _\_init__**()
Creates a new `MatchmakeRefereeEndRoundParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
round_id: int
results: list[[MatchmakeRefereePersonalRoundResult](#matchmakerefereepersonalroundresult)]

## MatchmakeRefereePersonalRoundResult **def _\_init__**()
Creates a new `MatchmakeRefereePersonalRoundResult` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
personal_round_result_flag: int
round_win_loss: int
rating_change: int
buffer: bytes

## MatchmakeRefereeRound **def _\_init__**()
Creates a new `MatchmakeRefereeRound` instance. Required fields must be filled in manually. The following fields are defined in this class:
id: int
gid: int
state: int
personal_data_category: int
results: list[[MatchmakeRefereePersonalRoundResult](#matchmakerefereepersonalroundresult)]

## MatchmakeRefereeStartRoundParam **def _\_init__**()
Creates a new `MatchmakeRefereeStartRoundParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
personal_data_category: int
gid: int
pids: list[int]

## MatchmakeRefereeStats **def _\_init__**()
Creates a new `MatchmakeRefereeStats` instance. Required fields must be filled in manually. The following fields are defined in this class:
unique_id: int
category: int
pid: int
recent_disconnection: int
recent_violation: int
recent_mismatch: int
recent_win: int
recent_loss: int
recent_draw: int
total_disconnect: int
total_violation: int
total_mismatch: int
total_win: int
total_loss: int
total_draw: int
rating_value: int

## MatchmakeRefereeStatsInitParam **def _\_init__**()
Creates a new `MatchmakeRefereeStatsInitParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
category: int
initial_rating: int

## MatchmakeRefereeStatsTarget **def _\_init__**()
Creates a new `MatchmakeRefereeStatsTarget` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
category: int

## MatchmakeSession **def _\_init__**()
Creates a new `MatchmakeSession` instance. Required fields must be filled in manually. The following fields are defined in this class:
game_mode: int = 0
attribs: list[int] = [0, 0, 0, 0, 0, 0]
open_participation: bool = True
matchmake_system: int = 0
application_data: bytes = b""
num_participants: int = 0
If 30000 <= `nex.version` < 40000:
If `nex.version` >= 30500:
progress_score: int = 100

If `nex.version` >= 30000:
session_key: bytes = b""

If `nex.version` >= 30500:
option: int = 0

If `nex.version` >= 30600:
If `revision` >= 1:
param: [MatchmakeParam](#matchmakeparam) = [MatchmakeParam](#matchmakeparam)()
started_time: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).never()


If `nex.version` >= 30700:
If `revision` >= 2:
user_password: str = ""


If `nex.version` >= 30800:
If `revision` >= 3:
refer_gid: int = 0
user_password_enabled: bool = False
system_password_enabled: bool = False



If `nex.version` >= 40000:
progress_score: int = 100
session_key: bytes = b""
option: int = 0
param: [MatchmakeParam](#matchmakeparam) = [MatchmakeParam](#matchmakeparam)()
started_time: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).never()
user_password: str = ""
refer_gid: int = 0
user_password_enabled: bool = False
system_password_enabled: bool = False
codeword: str = ""


## MatchmakeSessionSearchCriteria **def _\_init__**()
Creates a new `MatchmakeSessionSearchCriteria` instance. Required fields must be filled in manually. The following fields are defined in this class:
attribs: list[str] = ["", "", "", "", "", ""]
game_mode: str = ""
min_participants: str = ""
max_participants: str = ""
matchmake_system: str = ""
vacant_only: bool = True
exclude_locked: bool = True
exclude_non_host_pid: bool = False
selection_method: int = 0
If `nex.version` >= 30500:
vacant_participants: int = 1

If `nex.version` >= 40000:
param: [MatchmakeParam](#matchmakeparam) = [MatchmakeParam](#matchmakeparam)()
exclude_user_password: bool = False
exclude_system_password: bool = False
refer_gid: int = 0
codeword: str = ""
range: [ResultRange](common.md#resultrange) = [ResultRange](common.md#resultrange)()


## ParticipantDetails **def _\_init__**()
Creates a new `ParticipantDetails` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
name: str
message: str
participants: int

## PersistentGathering **def _\_init__**()
Creates a new `PersistentGathering` instance. Required fields must be filled in manually. The following fields are defined in this class:
type: int
password: str
attribs: list[int]
application_buffer: bytes
participation_start: [DateTime](common.md#datetime)
participation_end: [DateTime](common.md#datetime)
matchmake_session_count: int
num_participants: int

## PlayingSession **def _\_init__**()
Creates a new `PlayingSession` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
gathering: [Gathering](#gathering)

## SimpleCommunity **def _\_init__**()
Creates a new `SimpleCommunity` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
matchmake_session_count: int

## SimplePlayingSession **def _\_init__**()
Creates a new `SimplePlayingSession` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
gid: int
game_mode: int
attribute: int

## UpdateMatchmakeSessionParam **def _\_init__**()
Creates a new `UpdateMatchmakeSessionParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
modification_flags: int
attributes: list[int]
open_participation: bool
application_buffer: bytes
progress_score: int
param: [MatchmakeParam](#matchmakeparam) = [MatchmakeParam](#matchmakeparam)()
started_time: [DateTime](common.md#datetime)
user_password: str
game_mode: int
description: str
min_participants: int
max_participants: int
matchmake_system: int
participation_policy: int
policy_argument: int
codeword: str

================================================ FILE: docs/reference/nex/matchmaking_mk8.md ================================================ # Module: nintendo.nex.matchmaking_mk8 Provides a client and server for the `MatchMakingProtocol`, `MatchMakingProtocolExt`, `MatchmakeRefereeProtocol` and `MatchmakeExtensionProtocolMK8`. This page was generated automatically from `matchmaking_mk8.proto`. **class** [MatchMakingClient](#matchmakingclient)
The client for the `MatchMakingProtocol`. **class** [MatchMakingClientExt](#matchmakingclientext)
The client for the `MatchMakingProtocolExt`. **class** [MatchmakeRefereeClient](#matchmakerefereeclient)
The client for the `MatchmakeRefereeProtocol`. **class** [MatchmakeExtensionClientMK8](#matchmakeextensionclientmk8)
The client for the `MatchmakeExtensionProtocolMK8`. **class** [MatchMakingServer](#matchmakingserver)
The server for the `MatchMakingProtocol`. **class** [MatchMakingServerExt](#matchmakingserverext)
The server for the `MatchMakingProtocolExt`. **class** [MatchmakeRefereeServer](#matchmakerefereeserver)
The server for the `MatchmakeRefereeProtocol`. **class** [MatchmakeExtensionServerMK8](#matchmakeextensionservermk8)
The server for the `MatchmakeExtensionProtocolMK8`. **class** [MatchmakeSystem](#matchmakesystem)
**class** [AutoMatchmakeParam](#automatchmakeparam)([Structure](common.md))
**class** [CreateMatchmakeSessionParam](#creatematchmakesessionparam)([Structure](common.md))
**class** [DeletionEntry](#deletionentry)([Structure](common.md))
**class** [FindMatchmakeSessionByParticipantParam](#findmatchmakesessionbyparticipantparam)([Structure](common.md))
**class** [FindMatchmakeSessionByParticipantResult](#findmatchmakesessionbyparticipantresult)([Structure](common.md))
**class** [Gathering](#gathering)([Structure](common.md))
**class** [GatheringStats](#gatheringstats)([Structure](common.md))
**class** [GatheringURLs](#gatheringurls)([Structure](common.md))
**class** [Invitation](#invitation)([Structure](common.md))
**class** [JoinMatchmakeSessionParam](#joinmatchmakesessionparam)([Structure](common.md))
**class** [MatchmakeBlockListParam](#matchmakeblocklistparam)([Structure](common.md))
**class** [MatchmakeParam](#matchmakeparam)([Structure](common.md))
**class** [MatchmakeRefereeEndRoundParam](#matchmakerefereeendroundparam)([Structure](common.md))
**class** [MatchmakeRefereePersonalRoundResult](#matchmakerefereepersonalroundresult)([Structure](common.md))
**class** [MatchmakeRefereeRound](#matchmakerefereeround)([Structure](common.md))
**class** [MatchmakeRefereeStartRoundParam](#matchmakerefereestartroundparam)([Structure](common.md))
**class** [MatchmakeRefereeStats](#matchmakerefereestats)([Structure](common.md))
**class** [MatchmakeRefereeStatsInitParam](#matchmakerefereestatsinitparam)([Structure](common.md))
**class** [MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)([Structure](common.md))
**class** [MatchmakeSession](#matchmakesession)([Gathering](#gathering))
**class** [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)([Structure](common.md))
**class** [ParticipantDetails](#participantdetails)([Structure](common.md))
**class** [PersistentGathering](#persistentgathering)([Gathering](#gathering))
**class** [PlayingSession](#playingsession)([Structure](common.md))
**class** [SimpleCommunity](#simplecommunity)([Structure](common.md))
**class** [SimplePlayingSession](#simpleplayingsession)([Structure](common.md))
**class** [SimpleSearchCondition](#simplesearchcondition)([Structure](common.md))
**class** [SimpleSearchDateTimeAttribute](#simplesearchdatetimeattribute)([Structure](common.md))
**class** [SimpleSearchObject](#simplesearchobject)([Structure](common.md))
**class** [SimpleSearchParam](#simplesearchparam)([Structure](common.md))
**class** [UpdateMatchmakeSessionParam](#updatematchmakesessionparam)([Structure](common.md))
## MatchMakingClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`MatchMakingClient`](#matchmakingclient). **async def register_gathering**(gathering: [Gathering](#gathering)) -> int
Calls method `1` on the server. **async def unregister_gathering**(gid: int) -> bool
Calls method `2` on the server. **async def unregister_gatherings**(gids: list[int]) -> bool
Calls method `3` on the server. **async def update_gathering**(gathering: [Gathering](#gathering)) -> bool
Calls method `4` on the server. **async def invite**(gid: int, pids: list[int], message: str) -> bool
Calls method `5` on the server. **async def accept_invitation**(gid: int, message: str) -> bool
Calls method `6` on the server. **async def decline_invitation**(gid: int, message: str) -> bool
Calls method `7` on the server. **async def cancel_invitation**(gid: int, pids: list[int], message: str) -> bool
Calls method `8` on the server. **async def get_invitations_sent**(gid: int) -> list[[Invitation](#invitation)]
Calls method `9` on the server. **async def get_invitations_received**() -> list[[Invitation](#invitation)]
Calls method `10` on the server. **async def participate**(gid: int, message: str) -> bool
Calls method `11` on the server. **async def cancel_participation**(gid: int, message: str) -> bool
Calls method `12` on the server. **async def get_participants**(gid: int) -> list[int]
Calls method `13` on the server. **async def add_participants**(gid: int, pids: list[int], message: str) -> bool
Calls method `14` on the server. **async def get_detailed_participants**(gid: int) -> list[[ParticipantDetails](#participantdetails)]
Calls method `15` on the server. **async def get_participants_urls**(gid: int) -> list[[StationURL](common.md#stationurl)]
Calls method `16` on the server. **async def find_by_type**(type: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `17` on the server. **async def find_by_description**(description: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `18` on the server. **async def find_by_description_regex**(regex: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `19` on the server. **async def find_by_id**(ids: list[int]) -> list[[Gathering](#gathering)]
Calls method `20` on the server. **async def find_by_single_id**(gid: int) -> [RMCResponse](common.md)
Calls method `21` on the server. The RMC response has the following attributes:
result: bool
gathering: [Gathering](#gathering)
**async def find_by_owner**(owner: int, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `22` on the server. **async def find_by_participants**(pids: list[int]) -> list[[Gathering](#gathering)]
Calls method `23` on the server. **async def find_invitations**(range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `24` on the server. **async def find_by_sql_query**(query: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `25` on the server. **async def launch_session**(gid: int, url: str) -> bool
Calls method `26` on the server. **async def update_session_url**(gid: int, url: str) -> bool
Calls method `27` on the server. **async def get_session_url**(gid: int) -> [RMCResponse](common.md)
Calls method `28` on the server. The RMC response has the following attributes:
result: bool
url: str
**async def get_state**(gid: int) -> [RMCResponse](common.md)
Calls method `29` on the server. The RMC response has the following attributes:
result: bool
state: int
**async def set_state**(gid: int, state: int) -> bool
Calls method `30` on the server. **async def report_stats**(gid: int, stats: list[[GatheringStats](#gatheringstats)]) -> bool
Calls method `31` on the server. **async def get_stats**(gid: int, pids: list[int], columns: list[int]) -> [RMCResponse](common.md)
Calls method `32` on the server. The RMC response has the following attributes:
result: bool
stats: list[[GatheringStats](#gatheringstats)]
**async def delete_gathering**(gid: int) -> bool
Calls method `33` on the server. **async def get_pending_deletions**(reason: int, range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Calls method `34` on the server. The RMC response has the following attributes:
result: bool
deletions: list[[DeletionEntry](#deletionentry)]
**async def delete_from_deletions**(deletions: list[int]) -> bool
Calls method `35` on the server. **async def migrate_gathering_ownership_v1**(gid: int, potential_owners: list[int]) -> bool
Calls method `36` on the server. **async def find_by_description_like**(description: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `37` on the server. **async def register_local_url**(gid: int, url: [StationURL](common.md#stationurl)) -> None
Calls method `38` on the server. **async def register_local_urls**(gid: int, urls: list[[StationURL](common.md#stationurl)]) -> None
Calls method `39` on the server. **async def update_session_host_v1**(gid: int) -> None
Calls method `40` on the server. **async def get_session_urls**(gid: int) -> list[[StationURL](common.md#stationurl)]
Calls method `41` on the server. **async def update_session_host**(gid: int, is_migrate_owner: bool) -> None
Calls method `42` on the server. **async def update_gathering_ownership**(gid: int, participants_only: bool) -> bool
Calls method `43` on the server. **async def migrate_gathering_ownership**(gid: int, potential_owners: list[int], participants_only: bool) -> None
Calls method `44` on the server. ## MatchMakingClientExt **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`MatchMakingClientExt`](#matchmakingclientext). **async def end_participation**(gid: int, message: str) -> bool
Calls method `1` on the server. **async def get_participants**(gid: int, only_active: bool) -> list[int]
Calls method `2` on the server. **async def get_detailed_participants**(gid: int, only_active: bool) -> list[[ParticipantDetails](#participantdetails)]
Calls method `3` on the server. **async def get_participants_urls**(gids: list[int]) -> list[[GatheringURLs](#gatheringurls)]
Calls method `4` on the server. **async def get_gathering_relations**(id: int, descr: str) -> str
Calls method `5` on the server. **async def delete_from_deletions**(deletions: list[int], pid: int) -> None
Calls method `6` on the server. ## MatchmakeRefereeClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`MatchmakeRefereeClient`](#matchmakerefereeclient). **async def start_round**(param: [MatchmakeRefereeStartRoundParam](#matchmakerefereestartroundparam)) -> int
Calls method `1` on the server. **async def get_start_round_param**(round_id: int) -> [MatchmakeRefereeStartRoundParam](#matchmakerefereestartroundparam)
Calls method `2` on the server. **async def end_round**(param: [MatchmakeRefereeEndRoundParam](#matchmakerefereeendroundparam)) -> None
Calls method `3` on the server. **async def end_round_without_report**(round_id: int) -> None
Calls method `4` on the server. **async def get_round_participants**(round_id: int) -> list[int]
Calls method `5` on the server. **async def get_not_summarized_round**() -> list[[MatchmakeRefereeRound](#matchmakerefereeround)]
Calls method `6` on the server. **async def get_round**(round: int) -> [MatchmakeRefereeRound](#matchmakerefereeround)
Calls method `7` on the server. **async def get_stats_primary**(target: [MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Calls method `8` on the server. **async def get_stats_primaries**(targets: list[[MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)]) -> [RMCResponse](common.md)
Calls method `9` on the server. The RMC response has the following attributes:
stats: list[[MatchmakeRefereeStats](#matchmakerefereestats)]
results: list[[Result](common.md#result)]
**async def get_stats_all**(target: [MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)) -> list[[MatchmakeRefereeStats](#matchmakerefereestats)]
Calls method `10` on the server. **async def create_stats**(param: [MatchmakeRefereeStatsInitParam](#matchmakerefereestatsinitparam)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Calls method `11` on the server. **async def get_or_create_stats**(param: [MatchmakeRefereeStatsInitParam](#matchmakerefereestatsinitparam)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Calls method `12` on the server. **async def reset_stats**() -> None
Calls method `13` on the server. ## MatchmakeExtensionClientMK8 **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`MatchmakeExtensionClientMK8`](#matchmakeextensionclientmk8). **async def close_participation**(gid: int) -> None
Calls method `1` on the server. **async def open_participation**(gid: int) -> None
Calls method `2` on the server. **async def auto_matchmake_postpone**(gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Calls method `3` on the server. **async def browse_matchmake_session**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `4` on the server. **async def browse_matchmake_session_with_host_urls**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Calls method `5` on the server. The RMC response has the following attributes:
gatherings: list[[Gathering](#gathering)]
urls: list[[GatheringURLs](#gatheringurls)]
**async def create_matchmake_session**(gathering: [Gathering](#gathering), description: str, num_participants: int) -> [RMCResponse](common.md)
Calls method `6` on the server. The RMC response has the following attributes:
gid: int
session_key: bytes
**async def join_matchmake_session**(gid: int, message: str) -> bytes
Calls method `7` on the server. **async def modify_current_game_attribute**(gid: int, attrib: int, value: int) -> None
Calls method `8` on the server. **async def update_notification_data**(type: int, param1: int, param2: int, param3: str) -> None
Calls method `9` on the server. **async def get_friend_notification_data**(type: int) -> list[[NotificationEvent](notification.md#notificationevent)]
Calls method `10` on the server. **async def update_application_buffer**(gid: int, buffer: bytes) -> None
Calls method `11` on the server. **async def update_matchmake_session_attribute**(gid: int, attribs: list[int]) -> None
Calls method `12` on the server. **async def get_friend_notification_data_list**(types: list[int]) -> list[[NotificationEvent](notification.md#notificationevent)]
Calls method `13` on the server. **async def update_matchmake_session**(gathering: [Gathering](#gathering)) -> None
Calls method `14` on the server. **async def auto_matchmake_with_search_criteria_postpone**(search_criteria: list[[MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)], gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Calls method `15` on the server. **async def get_playing_session**(pids: list[int]) -> list[[PlayingSession](#playingsession)]
Calls method `16` on the server. **async def create_community**(community: [PersistentGathering](#persistentgathering), message: str) -> int
Calls method `17` on the server. **async def update_community**(community: [PersistentGathering](#persistentgathering)) -> None
Calls method `18` on the server. **async def join_community**(gid: int, message: str, password: str) -> None
Calls method `19` on the server. **async def find_community_by_gathering_id**(gids: list[int]) -> list[[PersistentGathering](#persistentgathering)]
Calls method `20` on the server. **async def find_official_community**(available_only: bool, range: [ResultRange](common.md#resultrange)) -> list[[PersistentGathering](#persistentgathering)]
Calls method `21` on the server. **async def find_community_by_participant**(pid: int, range: [ResultRange](common.md#resultrange)) -> list[[PersistentGathering](#persistentgathering)]
Calls method `22` on the server. **async def update_privacy_setting**(online_status: bool, community_participation: bool) -> None
Calls method `23` on the server. **async def get_my_block_list**() -> list[int]
Calls method `24` on the server. **async def add_to_block_list**(pids: list[int]) -> None
Calls method `25` on the server. **async def remove_from_block_list**(pids: list[int]) -> None
Calls method `26` on the server. **async def clear_my_block_list**() -> None
Calls method `27` on the server. **async def report_violation**(pid: int, username: str, violation_code: int) -> None
Calls method `28` on the server. **async def is_violation_user**() -> [RMCResponse](common.md)
Calls method `29` on the server. The RMC response has the following attributes:
flag: bool
score: int
**async def join_matchmake_session_ex**(gid: int, gmessage: str, ignore_block_list: bool, num_participants: int) -> bytes
Calls method `30` on the server. **async def get_simple_playing_session**(pids: list[int], include_login_user: bool) -> list[[SimplePlayingSession](#simpleplayingsession)]
Calls method `31` on the server. **async def get_simple_community**(gids: list[int]) -> list[[SimpleCommunity](#simplecommunity)]
Calls method `32` on the server. **async def auto_matchmake_with_gathering_id_postpone**(gids: list[int], gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Calls method `33` on the server. **async def update_progress_score**(gid: int, score: int) -> None
Calls method `34` on the server. **async def debug_notify_event**(pid: int, main_type: int, sub_type: int, param1: int, param2: int, param3: str) -> None
Calls method `35` on the server. **async def create_simple_search_object**(object: [SimpleSearchObject](#simplesearchobject)) -> int
Calls method `36` on the server. **async def update_simple_search_object**(id: int, object: [SimpleSearchObject](#simplesearchobject)) -> None
Calls method `37` on the server. **async def delete_simple_search_object**(id: int) -> None
Calls method `38` on the server. **async def search_simple_search_object**(param: [SimpleSearchParam](#simplesearchparam)) -> list[[SimpleSearchObject](#simplesearchobject)]
Calls method `39` on the server. **async def join_matchmake_session_with_extra_participants**(gid: int, join_message: str, ignore_blacklist: bool, participation_count: int, extra_participants: int) -> bytes
Calls method `40` on the server. **async def search_simple_search_object_by_object_ids**(ids: list[int]) -> list[[SimpleSearchObject](#simplesearchobject)]
Calls method `41` on the server. **async def browse_matchmake_session_no_holder**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> list[[MatchmakeSession](#matchmakesession)]
Calls method `42` on the server. **async def browse_matchmake_session_with_host_urls_no_holder**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Calls method `43` on the server. The RMC response has the following attributes:
sessions: list[[MatchmakeSession](#matchmakesession)]
urls: list[[GatheringURLs](#gatheringurls)]
**async def update_matchmake_session_part**(param: [UpdateMatchmakeSessionParam](#updatematchmakesessionparam)) -> None
Calls method `44` on the server. **async def request_matchmaking**(param: [AutoMatchmakeParam](#automatchmakeparam)) -> int
Calls method `45` on the server. **async def withdraw_matchmaking**(request_id: int) -> None
Calls method `46` on the server. **async def withdraw_matchmaking_all**() -> None
Calls method `47` on the server. **async def find_matchmake_session_by_gathering_id**(gids: list[int]) -> list[[MatchmakeSession](#matchmakesession)]
Calls method `48` on the server. **async def find_matchmake_session_by_single_gathering_id**(gid: int) -> [MatchmakeSession](#matchmakesession)
Calls method `49` on the server. **async def find_matchmake_session_by_owner**(pid: int, range: [ResultRange](common.md#resultrange)) -> list[[MatchmakeSession](#matchmakesession)]
Calls method `50` on the server. **async def find_matchmake_session_by_participant**(param: [FindMatchmakeSessionByParticipantParam](#findmatchmakesessionbyparticipantparam)) -> list[[FindMatchmakeSessionByParticipantResult](#findmatchmakesessionbyparticipantresult)]
Calls method `51` on the server. **async def browse_matchmake_session_no_holder_no_result_range**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)) -> list[[MatchmakeSession](#matchmakesession)]
Calls method `52` on the server. **async def browse_matchmake_session_with_host_urls_no_holder_no_result_range**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)) -> [RMCResponse](common.md)
Calls method `53` on the server. The RMC response has the following attributes:
sessions: list[[MatchmakeSession](#matchmakesession)]
urls: list[[GatheringURLs](#gatheringurls)]
## MatchMakingServer **def _\_init__**()
Creates a new [`MatchMakingServer`](#matchmakingserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def register_gathering**(client: [RMCClient](rmc.md#rmcclient), gathering: [Gathering](#gathering)) -> int
Handler for method `1`. This method should be overridden by a subclass. **async def unregister_gathering**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> bool
Handler for method `2`. This method should be overridden by a subclass. **async def unregister_gatherings**(client: [RMCClient](rmc.md#rmcclient), gids: list[int]) -> bool
Handler for method `3`. This method should be overridden by a subclass. **async def update_gathering**(client: [RMCClient](rmc.md#rmcclient), gathering: [Gathering](#gathering)) -> bool
Handler for method `4`. This method should be overridden by a subclass. **async def invite**(client: [RMCClient](rmc.md#rmcclient), gid: int, pids: list[int], message: str) -> bool
Handler for method `5`. This method should be overridden by a subclass. **async def accept_invitation**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bool
Handler for method `6`. This method should be overridden by a subclass. **async def decline_invitation**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bool
Handler for method `7`. This method should be overridden by a subclass. **async def cancel_invitation**(client: [RMCClient](rmc.md#rmcclient), gid: int, pids: list[int], message: str) -> bool
Handler for method `8`. This method should be overridden by a subclass. **async def get_invitations_sent**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> list[[Invitation](#invitation)]
Handler for method `9`. This method should be overridden by a subclass. **async def get_invitations_received**(client: [RMCClient](rmc.md#rmcclient)) -> list[[Invitation](#invitation)]
Handler for method `10`. This method should be overridden by a subclass. **async def participate**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bool
Handler for method `11`. This method should be overridden by a subclass. **async def cancel_participation**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bool
Handler for method `12`. This method should be overridden by a subclass. **async def get_participants**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> list[int]
Handler for method `13`. This method should be overridden by a subclass. **async def add_participants**(client: [RMCClient](rmc.md#rmcclient), gid: int, pids: list[int], message: str) -> bool
Handler for method `14`. This method should be overridden by a subclass. **async def get_detailed_participants**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> list[[ParticipantDetails](#participantdetails)]
Handler for method `15`. This method should be overridden by a subclass. **async def get_participants_urls**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> list[[StationURL](common.md#stationurl)]
Handler for method `16`. This method should be overridden by a subclass. **async def find_by_type**(client: [RMCClient](rmc.md#rmcclient), type: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `17`. This method should be overridden by a subclass. **async def find_by_description**(client: [RMCClient](rmc.md#rmcclient), description: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `18`. This method should be overridden by a subclass. **async def find_by_description_regex**(client: [RMCClient](rmc.md#rmcclient), regex: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `19`. This method should be overridden by a subclass. **async def find_by_id**(client: [RMCClient](rmc.md#rmcclient), ids: list[int]) -> list[[Gathering](#gathering)]
Handler for method `20`. This method should be overridden by a subclass. **async def find_by_single_id**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> [RMCResponse](common.md)
Handler for method `21`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
gathering: [Gathering](#gathering)
**async def find_by_owner**(client: [RMCClient](rmc.md#rmcclient), owner: int, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `22`. This method should be overridden by a subclass. **async def find_by_participants**(client: [RMCClient](rmc.md#rmcclient), pids: list[int]) -> list[[Gathering](#gathering)]
Handler for method `23`. This method should be overridden by a subclass. **async def find_invitations**(client: [RMCClient](rmc.md#rmcclient), range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `24`. This method should be overridden by a subclass. **async def find_by_sql_query**(client: [RMCClient](rmc.md#rmcclient), query: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `25`. This method should be overridden by a subclass. **async def launch_session**(client: [RMCClient](rmc.md#rmcclient), gid: int, url: str) -> bool
Handler for method `26`. This method should be overridden by a subclass. **async def update_session_url**(client: [RMCClient](rmc.md#rmcclient), gid: int, url: str) -> bool
Handler for method `27`. This method should be overridden by a subclass. **async def get_session_url**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> [RMCResponse](common.md)
Handler for method `28`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
url: str
**async def get_state**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> [RMCResponse](common.md)
Handler for method `29`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
state: int
**async def set_state**(client: [RMCClient](rmc.md#rmcclient), gid: int, state: int) -> bool
Handler for method `30`. This method should be overridden by a subclass. **async def report_stats**(client: [RMCClient](rmc.md#rmcclient), gid: int, stats: list[[GatheringStats](#gatheringstats)]) -> bool
Handler for method `31`. This method should be overridden by a subclass. **async def get_stats**(client: [RMCClient](rmc.md#rmcclient), gid: int, pids: list[int], columns: list[int]) -> [RMCResponse](common.md)
Handler for method `32`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
stats: list[[GatheringStats](#gatheringstats)]
**async def delete_gathering**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> bool
Handler for method `33`. This method should be overridden by a subclass. **async def get_pending_deletions**(client: [RMCClient](rmc.md#rmcclient), reason: int, range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Handler for method `34`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
deletions: list[[DeletionEntry](#deletionentry)]
**async def delete_from_deletions**(client: [RMCClient](rmc.md#rmcclient), deletions: list[int]) -> bool
Handler for method `35`. This method should be overridden by a subclass. **async def migrate_gathering_ownership_v1**(client: [RMCClient](rmc.md#rmcclient), gid: int, potential_owners: list[int]) -> bool
Handler for method `36`. This method should be overridden by a subclass. **async def find_by_description_like**(client: [RMCClient](rmc.md#rmcclient), description: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `37`. This method should be overridden by a subclass. **async def register_local_url**(client: [RMCClient](rmc.md#rmcclient), gid: int, url: [StationURL](common.md#stationurl)) -> None
Handler for method `38`. This method should be overridden by a subclass. **async def register_local_urls**(client: [RMCClient](rmc.md#rmcclient), gid: int, urls: list[[StationURL](common.md#stationurl)]) -> None
Handler for method `39`. This method should be overridden by a subclass. **async def update_session_host_v1**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> None
Handler for method `40`. This method should be overridden by a subclass. **async def get_session_urls**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> list[[StationURL](common.md#stationurl)]
Handler for method `41`. This method should be overridden by a subclass. **async def update_session_host**(client: [RMCClient](rmc.md#rmcclient), gid: int, is_migrate_owner: bool) -> None
Handler for method `42`. This method should be overridden by a subclass. **async def update_gathering_ownership**(client: [RMCClient](rmc.md#rmcclient), gid: int, participants_only: bool) -> bool
Handler for method `43`. This method should be overridden by a subclass. **async def migrate_gathering_ownership**(client: [RMCClient](rmc.md#rmcclient), gid: int, potential_owners: list[int], participants_only: bool) -> None
Handler for method `44`. This method should be overridden by a subclass. ## MatchMakingServerExt **def _\_init__**()
Creates a new [`MatchMakingServerExt`](#matchmakingserverext). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def end_participation**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bool
Handler for method `1`. This method should be overridden by a subclass. **async def get_participants**(client: [RMCClient](rmc.md#rmcclient), gid: int, only_active: bool) -> list[int]
Handler for method `2`. This method should be overridden by a subclass. **async def get_detailed_participants**(client: [RMCClient](rmc.md#rmcclient), gid: int, only_active: bool) -> list[[ParticipantDetails](#participantdetails)]
Handler for method `3`. This method should be overridden by a subclass. **async def get_participants_urls**(client: [RMCClient](rmc.md#rmcclient), gids: list[int]) -> list[[GatheringURLs](#gatheringurls)]
Handler for method `4`. This method should be overridden by a subclass. **async def get_gathering_relations**(client: [RMCClient](rmc.md#rmcclient), id: int, descr: str) -> str
Handler for method `5`. This method should be overridden by a subclass. **async def delete_from_deletions**(client: [RMCClient](rmc.md#rmcclient), deletions: list[int], pid: int) -> None
Handler for method `6`. This method should be overridden by a subclass. ## MatchmakeRefereeServer **def _\_init__**()
Creates a new [`MatchmakeRefereeServer`](#matchmakerefereeserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def start_round**(client: [RMCClient](rmc.md#rmcclient), param: [MatchmakeRefereeStartRoundParam](#matchmakerefereestartroundparam)) -> int
Handler for method `1`. This method should be overridden by a subclass. **async def get_start_round_param**(client: [RMCClient](rmc.md#rmcclient), round_id: int) -> [MatchmakeRefereeStartRoundParam](#matchmakerefereestartroundparam)
Handler for method `2`. This method should be overridden by a subclass. **async def end_round**(client: [RMCClient](rmc.md#rmcclient), param: [MatchmakeRefereeEndRoundParam](#matchmakerefereeendroundparam)) -> None
Handler for method `3`. This method should be overridden by a subclass. **async def end_round_without_report**(client: [RMCClient](rmc.md#rmcclient), round_id: int) -> None
Handler for method `4`. This method should be overridden by a subclass. **async def get_round_participants**(client: [RMCClient](rmc.md#rmcclient), round_id: int) -> list[int]
Handler for method `5`. This method should be overridden by a subclass. **async def get_not_summarized_round**(client: [RMCClient](rmc.md#rmcclient)) -> list[[MatchmakeRefereeRound](#matchmakerefereeround)]
Handler for method `6`. This method should be overridden by a subclass. **async def get_round**(client: [RMCClient](rmc.md#rmcclient), round: int) -> [MatchmakeRefereeRound](#matchmakerefereeround)
Handler for method `7`. This method should be overridden by a subclass. **async def get_stats_primary**(client: [RMCClient](rmc.md#rmcclient), target: [MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Handler for method `8`. This method should be overridden by a subclass. **async def get_stats_primaries**(client: [RMCClient](rmc.md#rmcclient), targets: list[[MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)]) -> [RMCResponse](common.md)
Handler for method `9`. This method should be overridden by a subclass. The RMC response must have the following attributes:
stats: list[[MatchmakeRefereeStats](#matchmakerefereestats)]
results: list[[Result](common.md#result)]
**async def get_stats_all**(client: [RMCClient](rmc.md#rmcclient), target: [MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)) -> list[[MatchmakeRefereeStats](#matchmakerefereestats)]
Handler for method `10`. This method should be overridden by a subclass. **async def create_stats**(client: [RMCClient](rmc.md#rmcclient), param: [MatchmakeRefereeStatsInitParam](#matchmakerefereestatsinitparam)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Handler for method `11`. This method should be overridden by a subclass. **async def get_or_create_stats**(client: [RMCClient](rmc.md#rmcclient), param: [MatchmakeRefereeStatsInitParam](#matchmakerefereestatsinitparam)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Handler for method `12`. This method should be overridden by a subclass. **async def reset_stats**(client: [RMCClient](rmc.md#rmcclient)) -> None
Handler for method `13`. This method should be overridden by a subclass. ## MatchmakeExtensionServerMK8 **def _\_init__**()
Creates a new [`MatchmakeExtensionServerMK8`](#matchmakeextensionservermk8). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def close_participation**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> None
Handler for method `1`. This method should be overridden by a subclass. **async def open_participation**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> None
Handler for method `2`. This method should be overridden by a subclass. **async def auto_matchmake_postpone**(client: [RMCClient](rmc.md#rmcclient), gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Handler for method `3`. This method should be overridden by a subclass. **async def browse_matchmake_session**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `4`. This method should be overridden by a subclass. **async def browse_matchmake_session_with_host_urls**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Handler for method `5`. This method should be overridden by a subclass. The RMC response must have the following attributes:
gatherings: list[[Gathering](#gathering)]
urls: list[[GatheringURLs](#gatheringurls)]
**async def create_matchmake_session**(client: [RMCClient](rmc.md#rmcclient), gathering: [Gathering](#gathering), description: str, num_participants: int) -> [RMCResponse](common.md)
Handler for method `6`. This method should be overridden by a subclass. The RMC response must have the following attributes:
gid: int
session_key: bytes
**async def join_matchmake_session**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bytes
Handler for method `7`. This method should be overridden by a subclass. **async def modify_current_game_attribute**(client: [RMCClient](rmc.md#rmcclient), gid: int, attrib: int, value: int) -> None
Handler for method `8`. This method should be overridden by a subclass. **async def update_notification_data**(client: [RMCClient](rmc.md#rmcclient), type: int, param1: int, param2: int, param3: str) -> None
Handler for method `9`. This method should be overridden by a subclass. **async def get_friend_notification_data**(client: [RMCClient](rmc.md#rmcclient), type: int) -> list[[NotificationEvent](notification.md#notificationevent)]
Handler for method `10`. This method should be overridden by a subclass. **async def update_application_buffer**(client: [RMCClient](rmc.md#rmcclient), gid: int, buffer: bytes) -> None
Handler for method `11`. This method should be overridden by a subclass. **async def update_matchmake_session_attribute**(client: [RMCClient](rmc.md#rmcclient), gid: int, attribs: list[int]) -> None
Handler for method `12`. This method should be overridden by a subclass. **async def get_friend_notification_data_list**(client: [RMCClient](rmc.md#rmcclient), types: list[int]) -> list[[NotificationEvent](notification.md#notificationevent)]
Handler for method `13`. This method should be overridden by a subclass. **async def update_matchmake_session**(client: [RMCClient](rmc.md#rmcclient), gathering: [Gathering](#gathering)) -> None
Handler for method `14`. This method should be overridden by a subclass. **async def auto_matchmake_with_search_criteria_postpone**(client: [RMCClient](rmc.md#rmcclient), search_criteria: list[[MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)], gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Handler for method `15`. This method should be overridden by a subclass. **async def get_playing_session**(client: [RMCClient](rmc.md#rmcclient), pids: list[int]) -> list[[PlayingSession](#playingsession)]
Handler for method `16`. This method should be overridden by a subclass. **async def create_community**(client: [RMCClient](rmc.md#rmcclient), community: [PersistentGathering](#persistentgathering), message: str) -> int
Handler for method `17`. This method should be overridden by a subclass. **async def update_community**(client: [RMCClient](rmc.md#rmcclient), community: [PersistentGathering](#persistentgathering)) -> None
Handler for method `18`. This method should be overridden by a subclass. **async def join_community**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str, password: str) -> None
Handler for method `19`. This method should be overridden by a subclass. **async def find_community_by_gathering_id**(client: [RMCClient](rmc.md#rmcclient), gids: list[int]) -> list[[PersistentGathering](#persistentgathering)]
Handler for method `20`. This method should be overridden by a subclass. **async def find_official_community**(client: [RMCClient](rmc.md#rmcclient), available_only: bool, range: [ResultRange](common.md#resultrange)) -> list[[PersistentGathering](#persistentgathering)]
Handler for method `21`. This method should be overridden by a subclass. **async def find_community_by_participant**(client: [RMCClient](rmc.md#rmcclient), pid: int, range: [ResultRange](common.md#resultrange)) -> list[[PersistentGathering](#persistentgathering)]
Handler for method `22`. This method should be overridden by a subclass. **async def update_privacy_setting**(client: [RMCClient](rmc.md#rmcclient), online_status: bool, community_participation: bool) -> None
Handler for method `23`. This method should be overridden by a subclass. **async def get_my_block_list**(client: [RMCClient](rmc.md#rmcclient)) -> list[int]
Handler for method `24`. This method should be overridden by a subclass. **async def add_to_block_list**(client: [RMCClient](rmc.md#rmcclient), pids: list[int]) -> None
Handler for method `25`. This method should be overridden by a subclass. **async def remove_from_block_list**(client: [RMCClient](rmc.md#rmcclient), pids: list[int]) -> None
Handler for method `26`. This method should be overridden by a subclass. **async def clear_my_block_list**(client: [RMCClient](rmc.md#rmcclient)) -> None
Handler for method `27`. This method should be overridden by a subclass. **async def report_violation**(client: [RMCClient](rmc.md#rmcclient), pid: int, username: str, violation_code: int) -> None
Handler for method `28`. This method should be overridden by a subclass. **async def is_violation_user**(client: [RMCClient](rmc.md#rmcclient)) -> [RMCResponse](common.md)
Handler for method `29`. This method should be overridden by a subclass. The RMC response must have the following attributes:
flag: bool
score: int
**async def join_matchmake_session_ex**(client: [RMCClient](rmc.md#rmcclient), gid: int, gmessage: str, ignore_block_list: bool, num_participants: int) -> bytes
Handler for method `30`. This method should be overridden by a subclass. **async def get_simple_playing_session**(client: [RMCClient](rmc.md#rmcclient), pids: list[int], include_login_user: bool) -> list[[SimplePlayingSession](#simpleplayingsession)]
Handler for method `31`. This method should be overridden by a subclass. **async def get_simple_community**(client: [RMCClient](rmc.md#rmcclient), gids: list[int]) -> list[[SimpleCommunity](#simplecommunity)]
Handler for method `32`. This method should be overridden by a subclass. **async def auto_matchmake_with_gathering_id_postpone**(client: [RMCClient](rmc.md#rmcclient), gids: list[int], gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Handler for method `33`. This method should be overridden by a subclass. **async def update_progress_score**(client: [RMCClient](rmc.md#rmcclient), gid: int, score: int) -> None
Handler for method `34`. This method should be overridden by a subclass. **async def debug_notify_event**(client: [RMCClient](rmc.md#rmcclient), pid: int, main_type: int, sub_type: int, param1: int, param2: int, param3: str) -> None
Handler for method `35`. This method should be overridden by a subclass. **async def create_simple_search_object**(client: [RMCClient](rmc.md#rmcclient), object: [SimpleSearchObject](#simplesearchobject)) -> int
Handler for method `36`. This method should be overridden by a subclass. **async def update_simple_search_object**(client: [RMCClient](rmc.md#rmcclient), id: int, object: [SimpleSearchObject](#simplesearchobject)) -> None
Handler for method `37`. This method should be overridden by a subclass. **async def delete_simple_search_object**(client: [RMCClient](rmc.md#rmcclient), id: int) -> None
Handler for method `38`. This method should be overridden by a subclass. **async def search_simple_search_object**(client: [RMCClient](rmc.md#rmcclient), param: [SimpleSearchParam](#simplesearchparam)) -> list[[SimpleSearchObject](#simplesearchobject)]
Handler for method `39`. This method should be overridden by a subclass. **async def join_matchmake_session_with_extra_participants**(client: [RMCClient](rmc.md#rmcclient), gid: int, join_message: str, ignore_blacklist: bool, participation_count: int, extra_participants: int) -> bytes
Handler for method `40`. This method should be overridden by a subclass. **async def search_simple_search_object_by_object_ids**(client: [RMCClient](rmc.md#rmcclient), ids: list[int]) -> list[[SimpleSearchObject](#simplesearchobject)]
Handler for method `41`. This method should be overridden by a subclass. **async def browse_matchmake_session_no_holder**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> list[[MatchmakeSession](#matchmakesession)]
Handler for method `42`. This method should be overridden by a subclass. **async def browse_matchmake_session_with_host_urls_no_holder**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Handler for method `43`. This method should be overridden by a subclass. The RMC response must have the following attributes:
sessions: list[[MatchmakeSession](#matchmakesession)]
urls: list[[GatheringURLs](#gatheringurls)]
**async def update_matchmake_session_part**(client: [RMCClient](rmc.md#rmcclient), param: [UpdateMatchmakeSessionParam](#updatematchmakesessionparam)) -> None
Handler for method `44`. This method should be overridden by a subclass. **async def request_matchmaking**(client: [RMCClient](rmc.md#rmcclient), param: [AutoMatchmakeParam](#automatchmakeparam)) -> int
Handler for method `45`. This method should be overridden by a subclass. **async def withdraw_matchmaking**(client: [RMCClient](rmc.md#rmcclient), request_id: int) -> None
Handler for method `46`. This method should be overridden by a subclass. **async def withdraw_matchmaking_all**(client: [RMCClient](rmc.md#rmcclient)) -> None
Handler for method `47`. This method should be overridden by a subclass. **async def find_matchmake_session_by_gathering_id**(client: [RMCClient](rmc.md#rmcclient), gids: list[int]) -> list[[MatchmakeSession](#matchmakesession)]
Handler for method `48`. This method should be overridden by a subclass. **async def find_matchmake_session_by_single_gathering_id**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> [MatchmakeSession](#matchmakesession)
Handler for method `49`. This method should be overridden by a subclass. **async def find_matchmake_session_by_owner**(client: [RMCClient](rmc.md#rmcclient), pid: int, range: [ResultRange](common.md#resultrange)) -> list[[MatchmakeSession](#matchmakesession)]
Handler for method `50`. This method should be overridden by a subclass. **async def find_matchmake_session_by_participant**(client: [RMCClient](rmc.md#rmcclient), param: [FindMatchmakeSessionByParticipantParam](#findmatchmakesessionbyparticipantparam)) -> list[[FindMatchmakeSessionByParticipantResult](#findmatchmakesessionbyparticipantresult)]
Handler for method `51`. This method should be overridden by a subclass. **async def browse_matchmake_session_no_holder_no_result_range**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)) -> list[[MatchmakeSession](#matchmakesession)]
Handler for method `52`. This method should be overridden by a subclass. **async def browse_matchmake_session_with_host_urls_no_holder_no_result_range**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)) -> [RMCResponse](common.md)
Handler for method `53`. This method should be overridden by a subclass. The RMC response must have the following attributes:
sessions: list[[MatchmakeSession](#matchmakesession)]
urls: list[[GatheringURLs](#gatheringurls)]
## MatchmakeSystem This class defines the following constants:
`GLOBAL = 1`
`FRIENDS = 2`
## AutoMatchmakeParam **def _\_init__**()
Creates a new `AutoMatchmakeParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
session: [MatchmakeSession](#matchmakesession) = [MatchmakeSession](#matchmakesession)()
participants: list[int]
gid_for_participation_check: int
options: int
join_message: str
num_participants: int
search_criteria: list[[MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)]
target_gids: list[int]
block_list: [MatchmakeBlockListParam](#matchmakeblocklistparam) = [MatchmakeBlockListParam](#matchmakeblocklistparam)()

## CreateMatchmakeSessionParam **def _\_init__**()
Creates a new `CreateMatchmakeSessionParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
session: [MatchmakeSession](#matchmakesession) = [MatchmakeSession](#matchmakesession)()
additional_participants: list[int]
gid_for_participation_check: int
options: int
join_message: str
num_participants: int

## DeletionEntry **def _\_init__**()
Creates a new `DeletionEntry` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
pid: int
reason: int

## FindMatchmakeSessionByParticipantParam **def _\_init__**()
Creates a new `FindMatchmakeSessionByParticipantParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
pids: list[int]
options: int
block_list: [MatchmakeBlockListParam](#matchmakeblocklistparam) = [MatchmakeBlockListParam](#matchmakeblocklistparam)()

## FindMatchmakeSessionByParticipantResult **def _\_init__**()
Creates a new `FindMatchmakeSessionByParticipantResult` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
session: [MatchmakeSession](#matchmakesession) = [MatchmakeSession](#matchmakesession)()

## Gathering **def _\_init__**()
Creates a new `Gathering` instance. Required fields must be filled in manually. The following fields are defined in this class:
id: int = 0
owner: int = 0
host: int = 0
min_participants: int = 0
max_participants: int = 0
participation_policy: int = 1
policy_argument: int = 0
flags: int = 512
state: int = 0
description: str = ""

## GatheringStats **def _\_init__**()
Creates a new `GatheringStats` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
flags: int
values: list[float]

## GatheringURLs **def _\_init__**()
Creates a new `GatheringURLs` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
urls: list[[StationURL](common.md#stationurl)]

## Invitation **def _\_init__**()
Creates a new `Invitation` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
guest: int
message: str

## JoinMatchmakeSessionParam **def _\_init__**()
Creates a new `JoinMatchmakeSessionParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
participants: list[int]
gid_for_participation_check: int
options: int
behavior: int
user_password: str
system_password: str
join_message: str
num_participants: int
extra_participants: int
block_list: [MatchmakeBlockListParam](#matchmakeblocklistparam) = [MatchmakeBlockListParam](#matchmakeblocklistparam)()

## MatchmakeBlockListParam **def _\_init__**()
Creates a new `MatchmakeBlockListParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
options: int = 0

## MatchmakeParam **def _\_init__**()
Creates a new `MatchmakeParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
param: dict[str, object] = {}

## MatchmakeRefereeEndRoundParam **def _\_init__**()
Creates a new `MatchmakeRefereeEndRoundParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
round_id: int
results: list[[MatchmakeRefereePersonalRoundResult](#matchmakerefereepersonalroundresult)]

## MatchmakeRefereePersonalRoundResult **def _\_init__**()
Creates a new `MatchmakeRefereePersonalRoundResult` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
personal_round_result_flag: int
round_win_loss: int
rating_change: int
buffer: bytes

## MatchmakeRefereeRound **def _\_init__**()
Creates a new `MatchmakeRefereeRound` instance. Required fields must be filled in manually. The following fields are defined in this class:
id: int
gid: int
state: int
personal_data_category: int
results: list[[MatchmakeRefereePersonalRoundResult](#matchmakerefereepersonalroundresult)]

## MatchmakeRefereeStartRoundParam **def _\_init__**()
Creates a new `MatchmakeRefereeStartRoundParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
personal_data_category: int
gid: int
pids: list[int]

## MatchmakeRefereeStats **def _\_init__**()
Creates a new `MatchmakeRefereeStats` instance. Required fields must be filled in manually. The following fields are defined in this class:
unique_id: int
category: int
pid: int
recent_disconnection: int
recent_violation: int
recent_mismatch: int
recent_win: int
recent_loss: int
recent_draw: int
total_disconnect: int
total_violation: int
total_mismatch: int
total_win: int
total_loss: int
total_draw: int
rating_value: int

## MatchmakeRefereeStatsInitParam **def _\_init__**()
Creates a new `MatchmakeRefereeStatsInitParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
category: int
initial_rating: int

## MatchmakeRefereeStatsTarget **def _\_init__**()
Creates a new `MatchmakeRefereeStatsTarget` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
category: int

## MatchmakeSession **def _\_init__**()
Creates a new `MatchmakeSession` instance. Required fields must be filled in manually. The following fields are defined in this class:
game_mode: int = 0
attribs: list[int] = [0, 0, 0, 0, 0, 0]
open_participation: bool = True
matchmake_system: int = 0
application_data: bytes = b""
num_participants: int = 0
If 30000 <= `nex.version` < 40000:
If `nex.version` >= 30500:
progress_score: int = 100

If `nex.version` >= 30000:
session_key: bytes = b""

If `nex.version` >= 30500:
option: int = 0

If `nex.version` >= 30600:
If `revision` >= 1:
param: [MatchmakeParam](#matchmakeparam) = [MatchmakeParam](#matchmakeparam)()
started_time: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).never()


If `nex.version` >= 30700:
If `revision` >= 2:
user_password: str = ""


If `nex.version` >= 30800:
If `revision` >= 3:
refer_gid: int = 0
user_password_enabled: bool = False
system_password_enabled: bool = False



If `nex.version` >= 40000:
progress_score: int = 100
session_key: bytes = b""
option: int = 0
param: [MatchmakeParam](#matchmakeparam) = [MatchmakeParam](#matchmakeparam)()
started_time: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).never()
user_password: str = ""
refer_gid: int = 0
user_password_enabled: bool = False
system_password_enabled: bool = False
codeword: str = ""


## MatchmakeSessionSearchCriteria **def _\_init__**()
Creates a new `MatchmakeSessionSearchCriteria` instance. Required fields must be filled in manually. The following fields are defined in this class:
attribs: list[str] = ["", "", "", "", "", ""]
game_mode: str = ""
min_participants: str = ""
max_participants: str = ""
matchmake_system: str = ""
vacant_only: bool = True
exclude_locked: bool = True
exclude_non_host_pid: bool = False
selection_method: int = 0
If `nex.version` >= 30500:
vacant_participants: int = 1

If `nex.version` >= 40000:
param: [MatchmakeParam](#matchmakeparam) = [MatchmakeParam](#matchmakeparam)()
exclude_user_password: bool = False
exclude_system_password: bool = False
refer_gid: int = 0
codeword: str = ""
range: [ResultRange](common.md#resultrange) = [ResultRange](common.md#resultrange)()


## ParticipantDetails **def _\_init__**()
Creates a new `ParticipantDetails` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
name: str
message: str
participants: int

## PersistentGathering **def _\_init__**()
Creates a new `PersistentGathering` instance. Required fields must be filled in manually. The following fields are defined in this class:
type: int
password: str
attribs: list[int]
application_buffer: bytes
participation_start: [DateTime](common.md#datetime)
participation_end: [DateTime](common.md#datetime)
matchmake_session_count: int
num_participants: int

## PlayingSession **def _\_init__**()
Creates a new `PlayingSession` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
gathering: [Gathering](#gathering)

## SimpleCommunity **def _\_init__**()
Creates a new `SimpleCommunity` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
matchmake_session_count: int

## SimplePlayingSession **def _\_init__**()
Creates a new `SimplePlayingSession` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
gid: int
game_mode: int
attribute: int

## SimpleSearchCondition **def _\_init__**()
Creates a new `SimpleSearchCondition` instance. Required fields must be filled in manually. The following fields are defined in this class:
value: int
operator: int

## SimpleSearchDateTimeAttribute **def _\_init__**()
Creates a new `SimpleSearchDateTimeAttribute` instance. Required fields must be filled in manually. The following fields are defined in this class:
unk1: int
unk2: int
unk3: int
unk4: int
start_time: [DateTime](common.md#datetime)
end_time: [DateTime](common.md#datetime)

## SimpleSearchObject **def _\_init__**()
Creates a new `SimpleSearchObject` instance. Required fields must be filled in manually. The following fields are defined in this class:
id: int
owner: int
attributes: list[int]
metadata: bytes
community_id: int
community_code: str
datetime: [SimpleSearchDateTimeAttribute](#simplesearchdatetimeattribute) = [SimpleSearchDateTimeAttribute](#simplesearchdatetimeattribute)()

## SimpleSearchParam **def _\_init__**()
Creates a new `SimpleSearchParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
unk1: int
unk2: int
conditions: list[[SimpleSearchCondition](#simplesearchcondition)]
unk3: str
range: [ResultRange](common.md#resultrange) = [ResultRange](common.md#resultrange)()
unk4: [DateTime](common.md#datetime)

## UpdateMatchmakeSessionParam **def _\_init__**()
Creates a new `UpdateMatchmakeSessionParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
modification_flags: int
attributes: list[int]
open_participation: bool
application_buffer: bytes
progress_score: int
param: [MatchmakeParam](#matchmakeparam) = [MatchmakeParam](#matchmakeparam)()
started_time: [DateTime](common.md#datetime)
user_password: str
game_mode: int
description: str
min_participants: int
max_participants: int
matchmake_system: int
participation_policy: int
policy_argument: int
codeword: str

================================================ FILE: docs/reference/nex/matchmaking_mk8d.md ================================================ # Module: nintendo.nex.matchmaking_mk8d Provides a client and server for the `MatchMakingProtocol`, `MatchMakingProtocolExt`, `MatchmakeRefereeProtocol` and `MatchmakeExtensionProtocolMK8D`. This page was generated automatically from `matchmaking_mk8d.proto`. **class** [MatchMakingClient](#matchmakingclient)
The client for the `MatchMakingProtocol`. **class** [MatchMakingClientExt](#matchmakingclientext)
The client for the `MatchMakingProtocolExt`. **class** [MatchmakeRefereeClient](#matchmakerefereeclient)
The client for the `MatchmakeRefereeProtocol`. **class** [MatchmakeExtensionClientMK8D](#matchmakeextensionclientmk8d)
The client for the `MatchmakeExtensionProtocolMK8D`. **class** [MatchMakingServer](#matchmakingserver)
The server for the `MatchMakingProtocol`. **class** [MatchMakingServerExt](#matchmakingserverext)
The server for the `MatchMakingProtocolExt`. **class** [MatchmakeRefereeServer](#matchmakerefereeserver)
The server for the `MatchmakeRefereeProtocol`. **class** [MatchmakeExtensionServerMK8D](#matchmakeextensionservermk8d)
The server for the `MatchmakeExtensionProtocolMK8D`. **class** [MatchmakeSystem](#matchmakesystem)
**class** [SimpleSearchConditionOperator](#simplesearchconditionoperator)
**class** [AutoMatchmakeParam](#automatchmakeparam)([Structure](common.md))
**class** [CreateMatchmakeSessionParam](#creatematchmakesessionparam)([Structure](common.md))
**class** [DeletionEntry](#deletionentry)([Structure](common.md))
**class** [FindMatchmakeSessionByParticipantParam](#findmatchmakesessionbyparticipantparam)([Structure](common.md))
**class** [FindMatchmakeSessionByParticipantResult](#findmatchmakesessionbyparticipantresult)([Structure](common.md))
**class** [Gathering](#gathering)([Structure](common.md))
**class** [GatheringStats](#gatheringstats)([Structure](common.md))
**class** [GatheringURLs](#gatheringurls)([Structure](common.md))
**class** [Invitation](#invitation)([Structure](common.md))
**class** [JoinMatchmakeSessionParam](#joinmatchmakesessionparam)([Structure](common.md))
**class** [MatchmakeBlockListParam](#matchmakeblocklistparam)([Structure](common.md))
**class** [MatchmakeParam](#matchmakeparam)([Structure](common.md))
**class** [MatchmakeRefereeEndRoundParam](#matchmakerefereeendroundparam)([Structure](common.md))
**class** [MatchmakeRefereePersonalRoundResult](#matchmakerefereepersonalroundresult)([Structure](common.md))
**class** [MatchmakeRefereeRound](#matchmakerefereeround)([Structure](common.md))
**class** [MatchmakeRefereeStartRoundParam](#matchmakerefereestartroundparam)([Structure](common.md))
**class** [MatchmakeRefereeStats](#matchmakerefereestats)([Structure](common.md))
**class** [MatchmakeRefereeStatsInitParam](#matchmakerefereestatsinitparam)([Structure](common.md))
**class** [MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)([Structure](common.md))
**class** [MatchmakeSession](#matchmakesession)([Gathering](#gathering))
**class** [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)([Structure](common.md))
**class** [ParticipantDetails](#participantdetails)([Structure](common.md))
**class** [PersistentGathering](#persistentgathering)([Gathering](#gathering))
**class** [PlayingSession](#playingsession)([Structure](common.md))
**class** [SimpleCommunity](#simplecommunity)([Structure](common.md))
**class** [SimplePlayingSession](#simpleplayingsession)([Structure](common.md))
**class** [SimpleSearchCondition](#simplesearchcondition)([Structure](common.md))
**class** [SimpleSearchDateTimeAttribute](#simplesearchdatetimeattribute)([Structure](common.md))
**class** [SimpleSearchObject](#simplesearchobject)([Structure](common.md))
**class** [SimpleSearchParam](#simplesearchparam)([Structure](common.md))
**class** [UpdateMatchmakeSessionParam](#updatematchmakesessionparam)([Structure](common.md))
## MatchMakingClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`MatchMakingClient`](#matchmakingclient). **async def register_gathering**(gathering: [Gathering](#gathering)) -> int
Calls method `1` on the server. **async def unregister_gathering**(gid: int) -> bool
Calls method `2` on the server. **async def unregister_gatherings**(gids: list[int]) -> bool
Calls method `3` on the server. **async def update_gathering**(gathering: [Gathering](#gathering)) -> bool
Calls method `4` on the server. **async def invite**(gid: int, pids: list[int], message: str) -> bool
Calls method `5` on the server. **async def accept_invitation**(gid: int, message: str) -> bool
Calls method `6` on the server. **async def decline_invitation**(gid: int, message: str) -> bool
Calls method `7` on the server. **async def cancel_invitation**(gid: int, pids: list[int], message: str) -> bool
Calls method `8` on the server. **async def get_invitations_sent**(gid: int) -> list[[Invitation](#invitation)]
Calls method `9` on the server. **async def get_invitations_received**() -> list[[Invitation](#invitation)]
Calls method `10` on the server. **async def participate**(gid: int, message: str) -> bool
Calls method `11` on the server. **async def cancel_participation**(gid: int, message: str) -> bool
Calls method `12` on the server. **async def get_participants**(gid: int) -> list[int]
Calls method `13` on the server. **async def add_participants**(gid: int, pids: list[int], message: str) -> bool
Calls method `14` on the server. **async def get_detailed_participants**(gid: int) -> list[[ParticipantDetails](#participantdetails)]
Calls method `15` on the server. **async def get_participants_urls**(gid: int) -> list[[StationURL](common.md#stationurl)]
Calls method `16` on the server. **async def find_by_type**(type: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `17` on the server. **async def find_by_description**(description: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `18` on the server. **async def find_by_description_regex**(regex: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `19` on the server. **async def find_by_id**(ids: list[int]) -> list[[Gathering](#gathering)]
Calls method `20` on the server. **async def find_by_single_id**(gid: int) -> [RMCResponse](common.md)
Calls method `21` on the server. The RMC response has the following attributes:
result: bool
gathering: [Gathering](#gathering)
**async def find_by_owner**(owner: int, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `22` on the server. **async def find_by_participants**(pids: list[int]) -> list[[Gathering](#gathering)]
Calls method `23` on the server. **async def find_invitations**(range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `24` on the server. **async def find_by_sql_query**(query: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `25` on the server. **async def launch_session**(gid: int, url: str) -> bool
Calls method `26` on the server. **async def update_session_url**(gid: int, url: str) -> bool
Calls method `27` on the server. **async def get_session_url**(gid: int) -> [RMCResponse](common.md)
Calls method `28` on the server. The RMC response has the following attributes:
result: bool
url: str
**async def get_state**(gid: int) -> [RMCResponse](common.md)
Calls method `29` on the server. The RMC response has the following attributes:
result: bool
state: int
**async def set_state**(gid: int, state: int) -> bool
Calls method `30` on the server. **async def report_stats**(gid: int, stats: list[[GatheringStats](#gatheringstats)]) -> bool
Calls method `31` on the server. **async def get_stats**(gid: int, pids: list[int], columns: list[int]) -> [RMCResponse](common.md)
Calls method `32` on the server. The RMC response has the following attributes:
result: bool
stats: list[[GatheringStats](#gatheringstats)]
**async def delete_gathering**(gid: int) -> bool
Calls method `33` on the server. **async def get_pending_deletions**(reason: int, range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Calls method `34` on the server. The RMC response has the following attributes:
result: bool
deletions: list[[DeletionEntry](#deletionentry)]
**async def delete_from_deletions**(deletions: list[int]) -> bool
Calls method `35` on the server. **async def migrate_gathering_ownership_v1**(gid: int, potential_owners: list[int]) -> bool
Calls method `36` on the server. **async def find_by_description_like**(description: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `37` on the server. **async def register_local_url**(gid: int, url: [StationURL](common.md#stationurl)) -> None
Calls method `38` on the server. **async def register_local_urls**(gid: int, urls: list[[StationURL](common.md#stationurl)]) -> None
Calls method `39` on the server. **async def update_session_host_v1**(gid: int) -> None
Calls method `40` on the server. **async def get_session_urls**(gid: int) -> list[[StationURL](common.md#stationurl)]
Calls method `41` on the server. **async def update_session_host**(gid: int, is_migrate_owner: bool) -> None
Calls method `42` on the server. **async def update_gathering_ownership**(gid: int, participants_only: bool) -> bool
Calls method `43` on the server. **async def migrate_gathering_ownership**(gid: int, potential_owners: list[int], participants_only: bool) -> None
Calls method `44` on the server. ## MatchMakingClientExt **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`MatchMakingClientExt`](#matchmakingclientext). **async def end_participation**(gid: int, message: str) -> bool
Calls method `1` on the server. **async def get_participants**(gid: int, only_active: bool) -> list[int]
Calls method `2` on the server. **async def get_detailed_participants**(gid: int, only_active: bool) -> list[[ParticipantDetails](#participantdetails)]
Calls method `3` on the server. **async def get_participants_urls**(gids: list[int]) -> list[[GatheringURLs](#gatheringurls)]
Calls method `4` on the server. **async def get_gathering_relations**(id: int, descr: str) -> str
Calls method `5` on the server. **async def delete_from_deletions**(deletions: list[int], pid: int) -> None
Calls method `6` on the server. ## MatchmakeRefereeClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`MatchmakeRefereeClient`](#matchmakerefereeclient). **async def start_round**(param: [MatchmakeRefereeStartRoundParam](#matchmakerefereestartroundparam)) -> int
Calls method `1` on the server. **async def get_start_round_param**(round_id: int) -> [MatchmakeRefereeStartRoundParam](#matchmakerefereestartroundparam)
Calls method `2` on the server. **async def end_round**(param: [MatchmakeRefereeEndRoundParam](#matchmakerefereeendroundparam)) -> None
Calls method `3` on the server. **async def end_round_without_report**(round_id: int) -> None
Calls method `4` on the server. **async def get_round_participants**(round_id: int) -> list[int]
Calls method `5` on the server. **async def get_not_summarized_round**() -> list[[MatchmakeRefereeRound](#matchmakerefereeround)]
Calls method `6` on the server. **async def get_round**(round: int) -> [MatchmakeRefereeRound](#matchmakerefereeround)
Calls method `7` on the server. **async def get_stats_primary**(target: [MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Calls method `8` on the server. **async def get_stats_primaries**(targets: list[[MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)]) -> [RMCResponse](common.md)
Calls method `9` on the server. The RMC response has the following attributes:
stats: list[[MatchmakeRefereeStats](#matchmakerefereestats)]
results: list[[Result](common.md#result)]
**async def get_stats_all**(target: [MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)) -> list[[MatchmakeRefereeStats](#matchmakerefereestats)]
Calls method `10` on the server. **async def create_stats**(param: [MatchmakeRefereeStatsInitParam](#matchmakerefereestatsinitparam)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Calls method `11` on the server. **async def get_or_create_stats**(param: [MatchmakeRefereeStatsInitParam](#matchmakerefereestatsinitparam)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Calls method `12` on the server. **async def reset_stats**() -> None
Calls method `13` on the server. ## MatchmakeExtensionClientMK8D **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`MatchmakeExtensionClientMK8D`](#matchmakeextensionclientmk8d). **async def close_participation**(gid: int) -> None
Calls method `1` on the server. **async def open_participation**(gid: int) -> None
Calls method `2` on the server. **async def auto_matchmake_postpone**(gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Calls method `3` on the server. **async def browse_matchmake_session**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Calls method `4` on the server. **async def browse_matchmake_session_with_host_urls**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Calls method `5` on the server. The RMC response has the following attributes:
gatherings: list[[Gathering](#gathering)]
urls: list[[GatheringURLs](#gatheringurls)]
**async def create_matchmake_session**(gathering: [Gathering](#gathering), description: str, num_participants: int) -> [RMCResponse](common.md)
Calls method `6` on the server. The RMC response has the following attributes:
gid: int
session_key: bytes
**async def join_matchmake_session**(gid: int, message: str) -> bytes
Calls method `7` on the server. **async def modify_current_game_attribute**(gid: int, attrib: int, value: int) -> None
Calls method `8` on the server. **async def update_notification_data**(type: int, param1: int, param2: int, param3: str) -> None
Calls method `9` on the server. **async def get_friend_notification_data**(type: int) -> list[[NotificationEvent](notification.md#notificationevent)]
Calls method `10` on the server. **async def update_application_buffer**(gid: int, buffer: bytes) -> None
Calls method `11` on the server. **async def update_matchmake_session_attribute**(gid: int, attribs: list[int]) -> None
Calls method `12` on the server. **async def get_friend_notification_data_list**(types: list[int]) -> list[[NotificationEvent](notification.md#notificationevent)]
Calls method `13` on the server. **async def update_matchmake_session**(gathering: [Gathering](#gathering)) -> None
Calls method `14` on the server. **async def auto_matchmake_with_search_criteria_postpone**(search_criteria: list[[MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)], gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Calls method `15` on the server. **async def get_playing_session**(pids: list[int]) -> list[[PlayingSession](#playingsession)]
Calls method `16` on the server. **async def create_community**(community: [PersistentGathering](#persistentgathering), message: str) -> int
Calls method `17` on the server. **async def update_community**(community: [PersistentGathering](#persistentgathering)) -> None
Calls method `18` on the server. **async def join_community**(gid: int, message: str, password: str) -> None
Calls method `19` on the server. **async def find_community_by_gathering_id**(gids: list[int]) -> list[[PersistentGathering](#persistentgathering)]
Calls method `20` on the server. **async def find_official_community**(available_only: bool, range: [ResultRange](common.md#resultrange)) -> list[[PersistentGathering](#persistentgathering)]
Calls method `21` on the server. **async def find_community_by_participant**(pid: int, range: [ResultRange](common.md#resultrange)) -> list[[PersistentGathering](#persistentgathering)]
Calls method `22` on the server. **async def update_privacy_setting**(online_status: bool, community_participation: bool) -> None
Calls method `23` on the server. **async def get_my_block_list**() -> list[int]
Calls method `24` on the server. **async def add_to_block_list**(pids: list[int]) -> None
Calls method `25` on the server. **async def remove_from_block_list**(pids: list[int]) -> None
Calls method `26` on the server. **async def clear_my_block_list**() -> None
Calls method `27` on the server. **async def report_violation**(pid: int, username: str, violation_code: int) -> None
Calls method `28` on the server. **async def is_violation_user**() -> [RMCResponse](common.md)
Calls method `29` on the server. The RMC response has the following attributes:
flag: bool
score: int
**async def join_matchmake_session_ex**(gid: int, gmessage: str, ignore_block_list: bool, num_participants: int) -> bytes
Calls method `30` on the server. **async def get_simple_playing_session**(pids: list[int], include_login_user: bool) -> list[[SimplePlayingSession](#simpleplayingsession)]
Calls method `31` on the server. **async def get_simple_community**(gids: list[int]) -> list[[SimpleCommunity](#simplecommunity)]
Calls method `32` on the server. **async def auto_matchmake_with_gathering_id_postpone**(gids: list[int], gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Calls method `33` on the server. **async def update_progress_score**(gid: int, score: int) -> None
Calls method `34` on the server. **async def debug_notify_event**(pid: int, main_type: int, sub_type: int, param1: int, param2: int, param3: str) -> None
Calls method `35` on the server. **async def generate_matchmake_session_system_password**(gid: int) -> str
Calls method `36` on the server. **async def clear_matchmake_session_system_password**(gid: int) -> None
Calls method `37` on the server. **async def create_matchmake_session_with_param**(param: [CreateMatchmakeSessionParam](#creatematchmakesessionparam)) -> [MatchmakeSession](#matchmakesession)
Calls method `38` on the server. **async def join_matchmake_session_with_param**(param: [JoinMatchmakeSessionParam](#joinmatchmakesessionparam)) -> [MatchmakeSession](#matchmakesession)
Calls method `39` on the server. **async def auto_matchmake_with_param_postpone**(param: [AutoMatchmakeParam](#automatchmakeparam)) -> [MatchmakeSession](#matchmakesession)
Calls method `40` on the server. **async def find_matchmake_session_by_gathering_id_detail**(gid: int) -> [MatchmakeSession](#matchmakesession)
Calls method `41` on the server. **async def browse_matchmake_session_no_holder**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> list[[MatchmakeSession](#matchmakesession)]
Calls method `42` on the server. **async def browse_matchmake_session_with_host_urls_no_holder**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Calls method `43` on the server. The RMC response has the following attributes:
sessions: list[[MatchmakeSession](#matchmakesession)]
urls: list[[GatheringURLs](#gatheringurls)]
**async def update_matchmake_session_part**(param: [UpdateMatchmakeSessionParam](#updatematchmakesessionparam)) -> None
Calls method `44` on the server. **async def request_matchmaking**(param: [AutoMatchmakeParam](#automatchmakeparam)) -> int
Calls method `45` on the server. **async def withdraw_matchmaking**(request_id: int) -> None
Calls method `46` on the server. **async def withdraw_matchmaking_all**() -> None
Calls method `47` on the server. **async def find_matchmake_session_by_gathering_id**(gids: list[int]) -> list[[MatchmakeSession](#matchmakesession)]
Calls method `48` on the server. **async def find_matchmake_session_by_single_gathering_id**(gid: int) -> [MatchmakeSession](#matchmakesession)
Calls method `49` on the server. **async def find_matchmake_session_by_owner**(pid: int, range: [ResultRange](common.md#resultrange)) -> list[[MatchmakeSession](#matchmakesession)]
Calls method `50` on the server. **async def find_matchmake_session_by_participant**(param: [FindMatchmakeSessionByParticipantParam](#findmatchmakesessionbyparticipantparam)) -> list[[FindMatchmakeSessionByParticipantResult](#findmatchmakesessionbyparticipantresult)]
Calls method `51` on the server. **async def browse_matchmake_session_no_holder_no_result_range**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)) -> list[[MatchmakeSession](#matchmakesession)]
Calls method `52` on the server. **async def browse_matchmake_session_with_host_urls_no_holder_no_result_range**(search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)) -> [RMCResponse](common.md)
Calls method `53` on the server. The RMC response has the following attributes:
sessions: list[[MatchmakeSession](#matchmakesession)]
urls: list[[GatheringURLs](#gatheringurls)]
**async def create_simple_search_object**(object: [SimpleSearchObject](#simplesearchobject)) -> int
Calls method `54` on the server. **async def update_simple_search_object**(id: int, object: [SimpleSearchObject](#simplesearchobject)) -> None
Calls method `55` on the server. **async def delete_simple_search_object**(id: int) -> None
Calls method `56` on the server. **async def search_simple_search_object**(param: [SimpleSearchParam](#simplesearchparam)) -> list[[SimpleSearchObject](#simplesearchobject)]
Calls method `57` on the server. **async def search_simple_search_object_by_object_ids**(ids: list[int]) -> list[[SimpleSearchObject](#simplesearchobject)]
Calls method `58` on the server. **async def join_matchmake_session_with_extra_participants**(gid: int, join_message: str, ignore_blacklist: bool, participation_count: int, extra_participants: int) -> bytes
Calls method `59` on the server. **async def create_competition**(competition: [SimpleSearchObject](#simplesearchobject)) -> [SimpleSearchObject](#simplesearchobject)
Calls method `61` on the server. **async def delete_competition**(id: int) -> None
Calls method `62` on the server. **async def register_favorite_competition**(id: int) -> None
Calls method `63` on the server. **async def unregister_favorite_competition**(id: int) -> None
Calls method `64` on the server. **async def get_favorite_competition**() -> list[[SimpleSearchObject](#simplesearchobject)]
Calls method `65` on the server. ## MatchMakingServer **def _\_init__**()
Creates a new [`MatchMakingServer`](#matchmakingserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def register_gathering**(client: [RMCClient](rmc.md#rmcclient), gathering: [Gathering](#gathering)) -> int
Handler for method `1`. This method should be overridden by a subclass. **async def unregister_gathering**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> bool
Handler for method `2`. This method should be overridden by a subclass. **async def unregister_gatherings**(client: [RMCClient](rmc.md#rmcclient), gids: list[int]) -> bool
Handler for method `3`. This method should be overridden by a subclass. **async def update_gathering**(client: [RMCClient](rmc.md#rmcclient), gathering: [Gathering](#gathering)) -> bool
Handler for method `4`. This method should be overridden by a subclass. **async def invite**(client: [RMCClient](rmc.md#rmcclient), gid: int, pids: list[int], message: str) -> bool
Handler for method `5`. This method should be overridden by a subclass. **async def accept_invitation**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bool
Handler for method `6`. This method should be overridden by a subclass. **async def decline_invitation**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bool
Handler for method `7`. This method should be overridden by a subclass. **async def cancel_invitation**(client: [RMCClient](rmc.md#rmcclient), gid: int, pids: list[int], message: str) -> bool
Handler for method `8`. This method should be overridden by a subclass. **async def get_invitations_sent**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> list[[Invitation](#invitation)]
Handler for method `9`. This method should be overridden by a subclass. **async def get_invitations_received**(client: [RMCClient](rmc.md#rmcclient)) -> list[[Invitation](#invitation)]
Handler for method `10`. This method should be overridden by a subclass. **async def participate**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bool
Handler for method `11`. This method should be overridden by a subclass. **async def cancel_participation**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bool
Handler for method `12`. This method should be overridden by a subclass. **async def get_participants**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> list[int]
Handler for method `13`. This method should be overridden by a subclass. **async def add_participants**(client: [RMCClient](rmc.md#rmcclient), gid: int, pids: list[int], message: str) -> bool
Handler for method `14`. This method should be overridden by a subclass. **async def get_detailed_participants**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> list[[ParticipantDetails](#participantdetails)]
Handler for method `15`. This method should be overridden by a subclass. **async def get_participants_urls**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> list[[StationURL](common.md#stationurl)]
Handler for method `16`. This method should be overridden by a subclass. **async def find_by_type**(client: [RMCClient](rmc.md#rmcclient), type: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `17`. This method should be overridden by a subclass. **async def find_by_description**(client: [RMCClient](rmc.md#rmcclient), description: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `18`. This method should be overridden by a subclass. **async def find_by_description_regex**(client: [RMCClient](rmc.md#rmcclient), regex: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `19`. This method should be overridden by a subclass. **async def find_by_id**(client: [RMCClient](rmc.md#rmcclient), ids: list[int]) -> list[[Gathering](#gathering)]
Handler for method `20`. This method should be overridden by a subclass. **async def find_by_single_id**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> [RMCResponse](common.md)
Handler for method `21`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
gathering: [Gathering](#gathering)
**async def find_by_owner**(client: [RMCClient](rmc.md#rmcclient), owner: int, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `22`. This method should be overridden by a subclass. **async def find_by_participants**(client: [RMCClient](rmc.md#rmcclient), pids: list[int]) -> list[[Gathering](#gathering)]
Handler for method `23`. This method should be overridden by a subclass. **async def find_invitations**(client: [RMCClient](rmc.md#rmcclient), range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `24`. This method should be overridden by a subclass. **async def find_by_sql_query**(client: [RMCClient](rmc.md#rmcclient), query: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `25`. This method should be overridden by a subclass. **async def launch_session**(client: [RMCClient](rmc.md#rmcclient), gid: int, url: str) -> bool
Handler for method `26`. This method should be overridden by a subclass. **async def update_session_url**(client: [RMCClient](rmc.md#rmcclient), gid: int, url: str) -> bool
Handler for method `27`. This method should be overridden by a subclass. **async def get_session_url**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> [RMCResponse](common.md)
Handler for method `28`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
url: str
**async def get_state**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> [RMCResponse](common.md)
Handler for method `29`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
state: int
**async def set_state**(client: [RMCClient](rmc.md#rmcclient), gid: int, state: int) -> bool
Handler for method `30`. This method should be overridden by a subclass. **async def report_stats**(client: [RMCClient](rmc.md#rmcclient), gid: int, stats: list[[GatheringStats](#gatheringstats)]) -> bool
Handler for method `31`. This method should be overridden by a subclass. **async def get_stats**(client: [RMCClient](rmc.md#rmcclient), gid: int, pids: list[int], columns: list[int]) -> [RMCResponse](common.md)
Handler for method `32`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
stats: list[[GatheringStats](#gatheringstats)]
**async def delete_gathering**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> bool
Handler for method `33`. This method should be overridden by a subclass. **async def get_pending_deletions**(client: [RMCClient](rmc.md#rmcclient), reason: int, range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Handler for method `34`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
deletions: list[[DeletionEntry](#deletionentry)]
**async def delete_from_deletions**(client: [RMCClient](rmc.md#rmcclient), deletions: list[int]) -> bool
Handler for method `35`. This method should be overridden by a subclass. **async def migrate_gathering_ownership_v1**(client: [RMCClient](rmc.md#rmcclient), gid: int, potential_owners: list[int]) -> bool
Handler for method `36`. This method should be overridden by a subclass. **async def find_by_description_like**(client: [RMCClient](rmc.md#rmcclient), description: str, range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `37`. This method should be overridden by a subclass. **async def register_local_url**(client: [RMCClient](rmc.md#rmcclient), gid: int, url: [StationURL](common.md#stationurl)) -> None
Handler for method `38`. This method should be overridden by a subclass. **async def register_local_urls**(client: [RMCClient](rmc.md#rmcclient), gid: int, urls: list[[StationURL](common.md#stationurl)]) -> None
Handler for method `39`. This method should be overridden by a subclass. **async def update_session_host_v1**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> None
Handler for method `40`. This method should be overridden by a subclass. **async def get_session_urls**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> list[[StationURL](common.md#stationurl)]
Handler for method `41`. This method should be overridden by a subclass. **async def update_session_host**(client: [RMCClient](rmc.md#rmcclient), gid: int, is_migrate_owner: bool) -> None
Handler for method `42`. This method should be overridden by a subclass. **async def update_gathering_ownership**(client: [RMCClient](rmc.md#rmcclient), gid: int, participants_only: bool) -> bool
Handler for method `43`. This method should be overridden by a subclass. **async def migrate_gathering_ownership**(client: [RMCClient](rmc.md#rmcclient), gid: int, potential_owners: list[int], participants_only: bool) -> None
Handler for method `44`. This method should be overridden by a subclass. ## MatchMakingServerExt **def _\_init__**()
Creates a new [`MatchMakingServerExt`](#matchmakingserverext). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def end_participation**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bool
Handler for method `1`. This method should be overridden by a subclass. **async def get_participants**(client: [RMCClient](rmc.md#rmcclient), gid: int, only_active: bool) -> list[int]
Handler for method `2`. This method should be overridden by a subclass. **async def get_detailed_participants**(client: [RMCClient](rmc.md#rmcclient), gid: int, only_active: bool) -> list[[ParticipantDetails](#participantdetails)]
Handler for method `3`. This method should be overridden by a subclass. **async def get_participants_urls**(client: [RMCClient](rmc.md#rmcclient), gids: list[int]) -> list[[GatheringURLs](#gatheringurls)]
Handler for method `4`. This method should be overridden by a subclass. **async def get_gathering_relations**(client: [RMCClient](rmc.md#rmcclient), id: int, descr: str) -> str
Handler for method `5`. This method should be overridden by a subclass. **async def delete_from_deletions**(client: [RMCClient](rmc.md#rmcclient), deletions: list[int], pid: int) -> None
Handler for method `6`. This method should be overridden by a subclass. ## MatchmakeRefereeServer **def _\_init__**()
Creates a new [`MatchmakeRefereeServer`](#matchmakerefereeserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def start_round**(client: [RMCClient](rmc.md#rmcclient), param: [MatchmakeRefereeStartRoundParam](#matchmakerefereestartroundparam)) -> int
Handler for method `1`. This method should be overridden by a subclass. **async def get_start_round_param**(client: [RMCClient](rmc.md#rmcclient), round_id: int) -> [MatchmakeRefereeStartRoundParam](#matchmakerefereestartroundparam)
Handler for method `2`. This method should be overridden by a subclass. **async def end_round**(client: [RMCClient](rmc.md#rmcclient), param: [MatchmakeRefereeEndRoundParam](#matchmakerefereeendroundparam)) -> None
Handler for method `3`. This method should be overridden by a subclass. **async def end_round_without_report**(client: [RMCClient](rmc.md#rmcclient), round_id: int) -> None
Handler for method `4`. This method should be overridden by a subclass. **async def get_round_participants**(client: [RMCClient](rmc.md#rmcclient), round_id: int) -> list[int]
Handler for method `5`. This method should be overridden by a subclass. **async def get_not_summarized_round**(client: [RMCClient](rmc.md#rmcclient)) -> list[[MatchmakeRefereeRound](#matchmakerefereeround)]
Handler for method `6`. This method should be overridden by a subclass. **async def get_round**(client: [RMCClient](rmc.md#rmcclient), round: int) -> [MatchmakeRefereeRound](#matchmakerefereeround)
Handler for method `7`. This method should be overridden by a subclass. **async def get_stats_primary**(client: [RMCClient](rmc.md#rmcclient), target: [MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Handler for method `8`. This method should be overridden by a subclass. **async def get_stats_primaries**(client: [RMCClient](rmc.md#rmcclient), targets: list[[MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)]) -> [RMCResponse](common.md)
Handler for method `9`. This method should be overridden by a subclass. The RMC response must have the following attributes:
stats: list[[MatchmakeRefereeStats](#matchmakerefereestats)]
results: list[[Result](common.md#result)]
**async def get_stats_all**(client: [RMCClient](rmc.md#rmcclient), target: [MatchmakeRefereeStatsTarget](#matchmakerefereestatstarget)) -> list[[MatchmakeRefereeStats](#matchmakerefereestats)]
Handler for method `10`. This method should be overridden by a subclass. **async def create_stats**(client: [RMCClient](rmc.md#rmcclient), param: [MatchmakeRefereeStatsInitParam](#matchmakerefereestatsinitparam)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Handler for method `11`. This method should be overridden by a subclass. **async def get_or_create_stats**(client: [RMCClient](rmc.md#rmcclient), param: [MatchmakeRefereeStatsInitParam](#matchmakerefereestatsinitparam)) -> [MatchmakeRefereeStats](#matchmakerefereestats)
Handler for method `12`. This method should be overridden by a subclass. **async def reset_stats**(client: [RMCClient](rmc.md#rmcclient)) -> None
Handler for method `13`. This method should be overridden by a subclass. ## MatchmakeExtensionServerMK8D **def _\_init__**()
Creates a new [`MatchmakeExtensionServerMK8D`](#matchmakeextensionservermk8d). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def close_participation**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> None
Handler for method `1`. This method should be overridden by a subclass. **async def open_participation**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> None
Handler for method `2`. This method should be overridden by a subclass. **async def auto_matchmake_postpone**(client: [RMCClient](rmc.md#rmcclient), gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Handler for method `3`. This method should be overridden by a subclass. **async def browse_matchmake_session**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> list[[Gathering](#gathering)]
Handler for method `4`. This method should be overridden by a subclass. **async def browse_matchmake_session_with_host_urls**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Handler for method `5`. This method should be overridden by a subclass. The RMC response must have the following attributes:
gatherings: list[[Gathering](#gathering)]
urls: list[[GatheringURLs](#gatheringurls)]
**async def create_matchmake_session**(client: [RMCClient](rmc.md#rmcclient), gathering: [Gathering](#gathering), description: str, num_participants: int) -> [RMCResponse](common.md)
Handler for method `6`. This method should be overridden by a subclass. The RMC response must have the following attributes:
gid: int
session_key: bytes
**async def join_matchmake_session**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str) -> bytes
Handler for method `7`. This method should be overridden by a subclass. **async def modify_current_game_attribute**(client: [RMCClient](rmc.md#rmcclient), gid: int, attrib: int, value: int) -> None
Handler for method `8`. This method should be overridden by a subclass. **async def update_notification_data**(client: [RMCClient](rmc.md#rmcclient), type: int, param1: int, param2: int, param3: str) -> None
Handler for method `9`. This method should be overridden by a subclass. **async def get_friend_notification_data**(client: [RMCClient](rmc.md#rmcclient), type: int) -> list[[NotificationEvent](notification.md#notificationevent)]
Handler for method `10`. This method should be overridden by a subclass. **async def update_application_buffer**(client: [RMCClient](rmc.md#rmcclient), gid: int, buffer: bytes) -> None
Handler for method `11`. This method should be overridden by a subclass. **async def update_matchmake_session_attribute**(client: [RMCClient](rmc.md#rmcclient), gid: int, attribs: list[int]) -> None
Handler for method `12`. This method should be overridden by a subclass. **async def get_friend_notification_data_list**(client: [RMCClient](rmc.md#rmcclient), types: list[int]) -> list[[NotificationEvent](notification.md#notificationevent)]
Handler for method `13`. This method should be overridden by a subclass. **async def update_matchmake_session**(client: [RMCClient](rmc.md#rmcclient), gathering: [Gathering](#gathering)) -> None
Handler for method `14`. This method should be overridden by a subclass. **async def auto_matchmake_with_search_criteria_postpone**(client: [RMCClient](rmc.md#rmcclient), search_criteria: list[[MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)], gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Handler for method `15`. This method should be overridden by a subclass. **async def get_playing_session**(client: [RMCClient](rmc.md#rmcclient), pids: list[int]) -> list[[PlayingSession](#playingsession)]
Handler for method `16`. This method should be overridden by a subclass. **async def create_community**(client: [RMCClient](rmc.md#rmcclient), community: [PersistentGathering](#persistentgathering), message: str) -> int
Handler for method `17`. This method should be overridden by a subclass. **async def update_community**(client: [RMCClient](rmc.md#rmcclient), community: [PersistentGathering](#persistentgathering)) -> None
Handler for method `18`. This method should be overridden by a subclass. **async def join_community**(client: [RMCClient](rmc.md#rmcclient), gid: int, message: str, password: str) -> None
Handler for method `19`. This method should be overridden by a subclass. **async def find_community_by_gathering_id**(client: [RMCClient](rmc.md#rmcclient), gids: list[int]) -> list[[PersistentGathering](#persistentgathering)]
Handler for method `20`. This method should be overridden by a subclass. **async def find_official_community**(client: [RMCClient](rmc.md#rmcclient), available_only: bool, range: [ResultRange](common.md#resultrange)) -> list[[PersistentGathering](#persistentgathering)]
Handler for method `21`. This method should be overridden by a subclass. **async def find_community_by_participant**(client: [RMCClient](rmc.md#rmcclient), pid: int, range: [ResultRange](common.md#resultrange)) -> list[[PersistentGathering](#persistentgathering)]
Handler for method `22`. This method should be overridden by a subclass. **async def update_privacy_setting**(client: [RMCClient](rmc.md#rmcclient), online_status: bool, community_participation: bool) -> None
Handler for method `23`. This method should be overridden by a subclass. **async def get_my_block_list**(client: [RMCClient](rmc.md#rmcclient)) -> list[int]
Handler for method `24`. This method should be overridden by a subclass. **async def add_to_block_list**(client: [RMCClient](rmc.md#rmcclient), pids: list[int]) -> None
Handler for method `25`. This method should be overridden by a subclass. **async def remove_from_block_list**(client: [RMCClient](rmc.md#rmcclient), pids: list[int]) -> None
Handler for method `26`. This method should be overridden by a subclass. **async def clear_my_block_list**(client: [RMCClient](rmc.md#rmcclient)) -> None
Handler for method `27`. This method should be overridden by a subclass. **async def report_violation**(client: [RMCClient](rmc.md#rmcclient), pid: int, username: str, violation_code: int) -> None
Handler for method `28`. This method should be overridden by a subclass. **async def is_violation_user**(client: [RMCClient](rmc.md#rmcclient)) -> [RMCResponse](common.md)
Handler for method `29`. This method should be overridden by a subclass. The RMC response must have the following attributes:
flag: bool
score: int
**async def join_matchmake_session_ex**(client: [RMCClient](rmc.md#rmcclient), gid: int, gmessage: str, ignore_block_list: bool, num_participants: int) -> bytes
Handler for method `30`. This method should be overridden by a subclass. **async def get_simple_playing_session**(client: [RMCClient](rmc.md#rmcclient), pids: list[int], include_login_user: bool) -> list[[SimplePlayingSession](#simpleplayingsession)]
Handler for method `31`. This method should be overridden by a subclass. **async def get_simple_community**(client: [RMCClient](rmc.md#rmcclient), gids: list[int]) -> list[[SimpleCommunity](#simplecommunity)]
Handler for method `32`. This method should be overridden by a subclass. **async def auto_matchmake_with_gathering_id_postpone**(client: [RMCClient](rmc.md#rmcclient), gids: list[int], gathering: [Gathering](#gathering), message: str) -> [Gathering](#gathering)
Handler for method `33`. This method should be overridden by a subclass. **async def update_progress_score**(client: [RMCClient](rmc.md#rmcclient), gid: int, score: int) -> None
Handler for method `34`. This method should be overridden by a subclass. **async def debug_notify_event**(client: [RMCClient](rmc.md#rmcclient), pid: int, main_type: int, sub_type: int, param1: int, param2: int, param3: str) -> None
Handler for method `35`. This method should be overridden by a subclass. **async def generate_matchmake_session_system_password**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> str
Handler for method `36`. This method should be overridden by a subclass. **async def clear_matchmake_session_system_password**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> None
Handler for method `37`. This method should be overridden by a subclass. **async def create_matchmake_session_with_param**(client: [RMCClient](rmc.md#rmcclient), param: [CreateMatchmakeSessionParam](#creatematchmakesessionparam)) -> [MatchmakeSession](#matchmakesession)
Handler for method `38`. This method should be overridden by a subclass. **async def join_matchmake_session_with_param**(client: [RMCClient](rmc.md#rmcclient), param: [JoinMatchmakeSessionParam](#joinmatchmakesessionparam)) -> [MatchmakeSession](#matchmakesession)
Handler for method `39`. This method should be overridden by a subclass. **async def auto_matchmake_with_param_postpone**(client: [RMCClient](rmc.md#rmcclient), param: [AutoMatchmakeParam](#automatchmakeparam)) -> [MatchmakeSession](#matchmakesession)
Handler for method `40`. This method should be overridden by a subclass. **async def find_matchmake_session_by_gathering_id_detail**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> [MatchmakeSession](#matchmakesession)
Handler for method `41`. This method should be overridden by a subclass. **async def browse_matchmake_session_no_holder**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> list[[MatchmakeSession](#matchmakesession)]
Handler for method `42`. This method should be overridden by a subclass. **async def browse_matchmake_session_with_host_urls_no_holder**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria), range: [ResultRange](common.md#resultrange)) -> [RMCResponse](common.md)
Handler for method `43`. This method should be overridden by a subclass. The RMC response must have the following attributes:
sessions: list[[MatchmakeSession](#matchmakesession)]
urls: list[[GatheringURLs](#gatheringurls)]
**async def update_matchmake_session_part**(client: [RMCClient](rmc.md#rmcclient), param: [UpdateMatchmakeSessionParam](#updatematchmakesessionparam)) -> None
Handler for method `44`. This method should be overridden by a subclass. **async def request_matchmaking**(client: [RMCClient](rmc.md#rmcclient), param: [AutoMatchmakeParam](#automatchmakeparam)) -> int
Handler for method `45`. This method should be overridden by a subclass. **async def withdraw_matchmaking**(client: [RMCClient](rmc.md#rmcclient), request_id: int) -> None
Handler for method `46`. This method should be overridden by a subclass. **async def withdraw_matchmaking_all**(client: [RMCClient](rmc.md#rmcclient)) -> None
Handler for method `47`. This method should be overridden by a subclass. **async def find_matchmake_session_by_gathering_id**(client: [RMCClient](rmc.md#rmcclient), gids: list[int]) -> list[[MatchmakeSession](#matchmakesession)]
Handler for method `48`. This method should be overridden by a subclass. **async def find_matchmake_session_by_single_gathering_id**(client: [RMCClient](rmc.md#rmcclient), gid: int) -> [MatchmakeSession](#matchmakesession)
Handler for method `49`. This method should be overridden by a subclass. **async def find_matchmake_session_by_owner**(client: [RMCClient](rmc.md#rmcclient), pid: int, range: [ResultRange](common.md#resultrange)) -> list[[MatchmakeSession](#matchmakesession)]
Handler for method `50`. This method should be overridden by a subclass. **async def find_matchmake_session_by_participant**(client: [RMCClient](rmc.md#rmcclient), param: [FindMatchmakeSessionByParticipantParam](#findmatchmakesessionbyparticipantparam)) -> list[[FindMatchmakeSessionByParticipantResult](#findmatchmakesessionbyparticipantresult)]
Handler for method `51`. This method should be overridden by a subclass. **async def browse_matchmake_session_no_holder_no_result_range**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)) -> list[[MatchmakeSession](#matchmakesession)]
Handler for method `52`. This method should be overridden by a subclass. **async def browse_matchmake_session_with_host_urls_no_holder_no_result_range**(client: [RMCClient](rmc.md#rmcclient), search_criteria: [MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)) -> [RMCResponse](common.md)
Handler for method `53`. This method should be overridden by a subclass. The RMC response must have the following attributes:
sessions: list[[MatchmakeSession](#matchmakesession)]
urls: list[[GatheringURLs](#gatheringurls)]
**async def create_simple_search_object**(client: [RMCClient](rmc.md#rmcclient), object: [SimpleSearchObject](#simplesearchobject)) -> int
Handler for method `54`. This method should be overridden by a subclass. **async def update_simple_search_object**(client: [RMCClient](rmc.md#rmcclient), id: int, object: [SimpleSearchObject](#simplesearchobject)) -> None
Handler for method `55`. This method should be overridden by a subclass. **async def delete_simple_search_object**(client: [RMCClient](rmc.md#rmcclient), id: int) -> None
Handler for method `56`. This method should be overridden by a subclass. **async def search_simple_search_object**(client: [RMCClient](rmc.md#rmcclient), param: [SimpleSearchParam](#simplesearchparam)) -> list[[SimpleSearchObject](#simplesearchobject)]
Handler for method `57`. This method should be overridden by a subclass. **async def search_simple_search_object_by_object_ids**(client: [RMCClient](rmc.md#rmcclient), ids: list[int]) -> list[[SimpleSearchObject](#simplesearchobject)]
Handler for method `58`. This method should be overridden by a subclass. **async def join_matchmake_session_with_extra_participants**(client: [RMCClient](rmc.md#rmcclient), gid: int, join_message: str, ignore_blacklist: bool, participation_count: int, extra_participants: int) -> bytes
Handler for method `59`. This method should be overridden by a subclass. **async def create_competition**(client: [RMCClient](rmc.md#rmcclient), competition: [SimpleSearchObject](#simplesearchobject)) -> [SimpleSearchObject](#simplesearchobject)
Handler for method `61`. This method should be overridden by a subclass. **async def delete_competition**(client: [RMCClient](rmc.md#rmcclient), id: int) -> None
Handler for method `62`. This method should be overridden by a subclass. **async def register_favorite_competition**(client: [RMCClient](rmc.md#rmcclient), id: int) -> None
Handler for method `63`. This method should be overridden by a subclass. **async def unregister_favorite_competition**(client: [RMCClient](rmc.md#rmcclient), id: int) -> None
Handler for method `64`. This method should be overridden by a subclass. **async def get_favorite_competition**(client: [RMCClient](rmc.md#rmcclient)) -> list[[SimpleSearchObject](#simplesearchobject)]
Handler for method `65`. This method should be overridden by a subclass. ## MatchmakeSystem This class defines the following constants:
`GLOBAL = 1`
`FRIENDS = 2`
## SimpleSearchConditionOperator This class defines the following constants:
`ANY = 0`
`EQUAL = 1`
`GREATER_THAN = 2`
`LESS_THAN = 3`
`GREATER_THAN_OR_EQUAL = 4`
`LESS_THAN_OR_EQUAL = 5`
## AutoMatchmakeParam **def _\_init__**()
Creates a new `AutoMatchmakeParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
session: [MatchmakeSession](#matchmakesession) = [MatchmakeSession](#matchmakesession)()
participants: list[int]
gid_for_participation_check: int
options: int
join_message: str
num_participants: int
search_criteria: list[[MatchmakeSessionSearchCriteria](#matchmakesessionsearchcriteria)]
target_gids: list[int]
block_list: [MatchmakeBlockListParam](#matchmakeblocklistparam) = [MatchmakeBlockListParam](#matchmakeblocklistparam)()

## CreateMatchmakeSessionParam **def _\_init__**()
Creates a new `CreateMatchmakeSessionParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
session: [MatchmakeSession](#matchmakesession) = [MatchmakeSession](#matchmakesession)()
additional_participants: list[int]
gid_for_participation_check: int
options: int
join_message: str
num_participants: int

## DeletionEntry **def _\_init__**()
Creates a new `DeletionEntry` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
pid: int
reason: int

## FindMatchmakeSessionByParticipantParam **def _\_init__**()
Creates a new `FindMatchmakeSessionByParticipantParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
pids: list[int]
options: int
block_list: [MatchmakeBlockListParam](#matchmakeblocklistparam) = [MatchmakeBlockListParam](#matchmakeblocklistparam)()

## FindMatchmakeSessionByParticipantResult **def _\_init__**()
Creates a new `FindMatchmakeSessionByParticipantResult` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
session: [MatchmakeSession](#matchmakesession) = [MatchmakeSession](#matchmakesession)()

## Gathering **def _\_init__**()
Creates a new `Gathering` instance. Required fields must be filled in manually. The following fields are defined in this class:
id: int = 0
owner: int = 0
host: int = 0
min_participants: int = 0
max_participants: int = 0
participation_policy: int = 1
policy_argument: int = 0
flags: int = 512
state: int = 0
description: str = ""

## GatheringStats **def _\_init__**()
Creates a new `GatheringStats` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
flags: int
values: list[float]

## GatheringURLs **def _\_init__**()
Creates a new `GatheringURLs` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
urls: list[[StationURL](common.md#stationurl)]

## Invitation **def _\_init__**()
Creates a new `Invitation` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
guest: int
message: str

## JoinMatchmakeSessionParam **def _\_init__**()
Creates a new `JoinMatchmakeSessionParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
participants: list[int]
gid_for_participation_check: int
options: int
behavior: int
user_password: str
system_password: str
join_message: str
num_participants: int
extra_participants: int
block_list: [MatchmakeBlockListParam](#matchmakeblocklistparam) = [MatchmakeBlockListParam](#matchmakeblocklistparam)()

## MatchmakeBlockListParam **def _\_init__**()
Creates a new `MatchmakeBlockListParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
options: int = 0

## MatchmakeParam **def _\_init__**()
Creates a new `MatchmakeParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
param: dict[str, object] = {}

## MatchmakeRefereeEndRoundParam **def _\_init__**()
Creates a new `MatchmakeRefereeEndRoundParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
round_id: int
results: list[[MatchmakeRefereePersonalRoundResult](#matchmakerefereepersonalroundresult)]

## MatchmakeRefereePersonalRoundResult **def _\_init__**()
Creates a new `MatchmakeRefereePersonalRoundResult` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
personal_round_result_flag: int
round_win_loss: int
rating_change: int
buffer: bytes

## MatchmakeRefereeRound **def _\_init__**()
Creates a new `MatchmakeRefereeRound` instance. Required fields must be filled in manually. The following fields are defined in this class:
id: int
gid: int
state: int
personal_data_category: int
results: list[[MatchmakeRefereePersonalRoundResult](#matchmakerefereepersonalroundresult)]

## MatchmakeRefereeStartRoundParam **def _\_init__**()
Creates a new `MatchmakeRefereeStartRoundParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
personal_data_category: int
gid: int
pids: list[int]

## MatchmakeRefereeStats **def _\_init__**()
Creates a new `MatchmakeRefereeStats` instance. Required fields must be filled in manually. The following fields are defined in this class:
unique_id: int
category: int
pid: int
recent_disconnection: int
recent_violation: int
recent_mismatch: int
recent_win: int
recent_loss: int
recent_draw: int
total_disconnect: int
total_violation: int
total_mismatch: int
total_win: int
total_loss: int
total_draw: int
rating_value: int

## MatchmakeRefereeStatsInitParam **def _\_init__**()
Creates a new `MatchmakeRefereeStatsInitParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
category: int
initial_rating: int

## MatchmakeRefereeStatsTarget **def _\_init__**()
Creates a new `MatchmakeRefereeStatsTarget` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
category: int

## MatchmakeSession **def _\_init__**()
Creates a new `MatchmakeSession` instance. Required fields must be filled in manually. The following fields are defined in this class:
game_mode: int = 0
attribs: list[int] = [0, 0, 0, 0, 0, 0]
open_participation: bool = True
matchmake_system: int = 0
application_data: bytes = b""
num_participants: int = 0
If 30000 <= `nex.version` < 40000:
If `nex.version` >= 30500:
progress_score: int = 100

If `nex.version` >= 30000:
session_key: bytes = b""

If `nex.version` >= 30500:
option: int = 0

If `nex.version` >= 30600:
If `revision` >= 1:
param: [MatchmakeParam](#matchmakeparam) = [MatchmakeParam](#matchmakeparam)()
started_time: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).never()


If `nex.version` >= 30700:
If `revision` >= 2:
user_password: str = ""


If `nex.version` >= 30800:
If `revision` >= 3:
refer_gid: int = 0
user_password_enabled: bool = False
system_password_enabled: bool = False



If `nex.version` >= 40000:
progress_score: int = 100
session_key: bytes = b""
option: int = 0
param: [MatchmakeParam](#matchmakeparam) = [MatchmakeParam](#matchmakeparam)()
started_time: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).never()
user_password: str = ""
refer_gid: int = 0
user_password_enabled: bool = False
system_password_enabled: bool = False
codeword: str = ""


## MatchmakeSessionSearchCriteria **def _\_init__**()
Creates a new `MatchmakeSessionSearchCriteria` instance. Required fields must be filled in manually. The following fields are defined in this class:
attribs: list[str] = ["", "", "", "", "", ""]
game_mode: str = ""
min_participants: str = ""
max_participants: str = ""
matchmake_system: str = ""
vacant_only: bool = True
exclude_locked: bool = True
exclude_non_host_pid: bool = False
selection_method: int = 0
If `nex.version` >= 30500:
vacant_participants: int = 1

If `nex.version` >= 40000:
param: [MatchmakeParam](#matchmakeparam) = [MatchmakeParam](#matchmakeparam)()
exclude_user_password: bool = False
exclude_system_password: bool = False
refer_gid: int = 0
codeword: str = ""
range: [ResultRange](common.md#resultrange) = [ResultRange](common.md#resultrange)()


## ParticipantDetails **def _\_init__**()
Creates a new `ParticipantDetails` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
name: str
message: str
participants: int

## PersistentGathering **def _\_init__**()
Creates a new `PersistentGathering` instance. Required fields must be filled in manually. The following fields are defined in this class:
type: int
password: str
attribs: list[int]
application_buffer: bytes
participation_start: [DateTime](common.md#datetime)
participation_end: [DateTime](common.md#datetime)
matchmake_session_count: int
num_participants: int

## PlayingSession **def _\_init__**()
Creates a new `PlayingSession` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
gathering: [Gathering](#gathering)

## SimpleCommunity **def _\_init__**()
Creates a new `SimpleCommunity` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
matchmake_session_count: int

## SimplePlayingSession **def _\_init__**()
Creates a new `SimplePlayingSession` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
gid: int
game_mode: int
attribute: int

## SimpleSearchCondition **def _\_init__**()
Creates a new `SimpleSearchCondition` instance. Required fields must be filled in manually. The following fields are defined in this class:
value: int
operator: int

## SimpleSearchDateTimeAttribute **def _\_init__**()
Creates a new `SimpleSearchDateTimeAttribute` instance. Required fields must be filled in manually. The following fields are defined in this class:
start_daytime: int
end_daytime: int
start_time: int
end_time: int
start_datetime: [DateTime](common.md#datetime)
end_datetime: [DateTime](common.md#datetime)

## SimpleSearchObject **def _\_init__**()
Creates a new `SimpleSearchObject` instance. Required fields must be filled in manually. The following fields are defined in this class:
id: int
owner: int
attributes: list[int]
metadata: bytes
community_id: int
community_code: str
datetime: [SimpleSearchDateTimeAttribute](#simplesearchdatetimeattribute) = [SimpleSearchDateTimeAttribute](#simplesearchdatetimeattribute)()
If `nex.version` >= 40000:
If `revision` >= 1:
liveliness_rate: int
liveliness_update_time: [DateTime](common.md#datetime)



## SimpleSearchParam **def _\_init__**()
Creates a new `SimpleSearchParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
id: int = 0
owner: int = 0
conditions: list[[SimpleSearchCondition](#simplesearchcondition)] = []
community_code: str = ""
range: [ResultRange](common.md#resultrange) = [ResultRange](common.md#resultrange)()
datetime: [DateTime](common.md#datetime) = [DateTime](common.md#datetime).never()

## UpdateMatchmakeSessionParam **def _\_init__**()
Creates a new `UpdateMatchmakeSessionParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
gid: int
modification_flags: int
attributes: list[int]
open_participation: bool
application_buffer: bytes
progress_score: int
param: [MatchmakeParam](#matchmakeparam) = [MatchmakeParam](#matchmakeparam)()
started_time: [DateTime](common.md#datetime)
user_password: str
game_mode: int
description: str
min_participants: int
max_participants: int
matchmake_system: int
participation_policy: int
policy_argument: int
codeword: str

================================================ FILE: docs/reference/nex/messaging.md ================================================ # Module: nintendo.nex.messaging Provides a client and server for the `MessagingProtocol` and `MessageDeliveryProtocol`. This page was generated automatically from `messaging.proto`. **class** [MessagingClient](#messagingclient)
The client for the `MessagingProtocol`. **class** [MessageDeliveryClient](#messagedeliveryclient)
The client for the `MessageDeliveryProtocol`. **class** [MessagingServer](#messagingserver)
The server for the `MessagingProtocol`. **class** [MessageDeliveryServer](#messagedeliveryserver)
The server for the `MessageDeliveryProtocol`. **class** [RecipientType](#recipienttype)
**class** [BinaryMessage](#binarymessage)([UserMessage](#usermessage))
**class** [MessageRecipient](#messagerecipient)([Structure](common.md))
**class** [TextMessage](#textmessage)([UserMessage](#usermessage))
**class** [UserMessage](#usermessage)([Data](common.md))
## MessagingClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`MessagingClient`](#messagingclient). **async def deliver_message**(message: [Data](common.md)) -> [RMCResponse](common.md)
Calls method `1` on the server. The RMC response has the following attributes:
modified_message: [Data](common.md)
sandbox_node_ids: list[int]
participants: list[int]
**async def get_number_of_messages**(recipient: [MessageRecipient](#messagerecipient)) -> int
Calls method `2` on the server. **async def get_message_headers**(recipient: [MessageRecipient](#messagerecipient), range: [ResultRange](common.md#resultrange)) -> list[[UserMessage](#usermessage)]
Calls method `3` on the server. **async def retrieve_all_messages_within_range**(recipient: [MessageRecipient](#messagerecipient), range: [ResultRange](common.md#resultrange)) -> list[[Data](common.md)]
Calls method `4` on the server. **async def retrieve_messages**(recipient: [MessageRecipient](#messagerecipient), message_ids: list[int], leave_on_server: bool) -> list[[Data](common.md)]
Calls method `5` on the server. **async def delete_messages**(recipient: [MessageRecipient](#messagerecipient), message_ids: list[int]) -> None
Calls method `6` on the server. **async def delete_all_messages**(recipient: [MessageRecipient](#messagerecipient)) -> int
Calls method `7` on the server. ## MessageDeliveryClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`MessageDeliveryClient`](#messagedeliveryclient). **async def deliver_message**(message: [Data](common.md)) -> None
Calls method `1` on the server. ## MessagingServer **def _\_init__**()
Creates a new [`MessagingServer`](#messagingserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def deliver_message**(client: [RMCClient](rmc.md#rmcclient), message: [Data](common.md)) -> [RMCResponse](common.md)
Handler for method `1`. This method should be overridden by a subclass. The RMC response must have the following attributes:
modified_message: [Data](common.md)
sandbox_node_ids: list[int]
participants: list[int]
**async def get_number_of_messages**(client: [RMCClient](rmc.md#rmcclient), recipient: [MessageRecipient](#messagerecipient)) -> int
Handler for method `2`. This method should be overridden by a subclass. **async def get_message_headers**(client: [RMCClient](rmc.md#rmcclient), recipient: [MessageRecipient](#messagerecipient), range: [ResultRange](common.md#resultrange)) -> list[[UserMessage](#usermessage)]
Handler for method `3`. This method should be overridden by a subclass. **async def retrieve_all_messages_within_range**(client: [RMCClient](rmc.md#rmcclient), recipient: [MessageRecipient](#messagerecipient), range: [ResultRange](common.md#resultrange)) -> list[[Data](common.md)]
Handler for method `4`. This method should be overridden by a subclass. **async def retrieve_messages**(client: [RMCClient](rmc.md#rmcclient), recipient: [MessageRecipient](#messagerecipient), message_ids: list[int], leave_on_server: bool) -> list[[Data](common.md)]
Handler for method `5`. This method should be overridden by a subclass. **async def delete_messages**(client: [RMCClient](rmc.md#rmcclient), recipient: [MessageRecipient](#messagerecipient), message_ids: list[int]) -> None
Handler for method `6`. This method should be overridden by a subclass. **async def delete_all_messages**(client: [RMCClient](rmc.md#rmcclient), recipient: [MessageRecipient](#messagerecipient)) -> int
Handler for method `7`. This method should be overridden by a subclass. ## MessageDeliveryServer **def _\_init__**()
Creates a new [`MessageDeliveryServer`](#messagedeliveryserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def deliver_message**(client: [RMCClient](rmc.md#rmcclient), message: [Data](common.md)) -> None
Handler for method `1`. This method should be overridden by a subclass. ## RecipientType This class defines the following constants:
`PRINCIPAL = 1`
`GATHERING = 2`
## BinaryMessage **def _\_init__**()
Creates a new `BinaryMessage` instance. Required fields must be filled in manually. The following fields are defined in this class:
body: bytes

## MessageRecipient **def _\_init__**()
Creates a new `MessageRecipient` instance. Required fields must be filled in manually. The following fields are defined in this class:
type: int
pid: int
gid: int

## TextMessage **def _\_init__**()
Creates a new `TextMessage` instance. Required fields must be filled in manually. The following fields are defined in this class:
body: str

## UserMessage **def _\_init__**()
Creates a new `UserMessage` instance. Required fields must be filled in manually. The following fields are defined in this class:
id: int
parent_id: int
sender: int
reception_time: [DateTime](common.md#datetime)
life_time: int
flags: int
subject: str
sender_name: str
recipient: [MessageRecipient](#messagerecipient) = [MessageRecipient](#messagerecipient)()

================================================ FILE: docs/reference/nex/monitoring.md ================================================ # Module: nintendo.nex.monitoring Provides a client and server for the `MonitoringProtocol`. This page was generated automatically from `monitoring.proto`. **class** [MonitoringClient](#monitoringclient)
The client for the `MonitoringProtocol`. **class** [MonitoringServer](#monitoringserver)
The server for the `MonitoringProtocol`. ## MonitoringClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`MonitoringClient`](#monitoringclient). **async def ping_daemon**() -> bool
Calls method `1` on the server. **async def get_cluster_members**() -> list[str]
Calls method `2` on the server. ## MonitoringServer **def _\_init__**()
Creates a new [`MonitoringServer`](#monitoringserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def ping_daemon**(client: [RMCClient](rmc.md#rmcclient)) -> bool
Handler for method `1`. This method should be overridden by a subclass. **async def get_cluster_members**(client: [RMCClient](rmc.md#rmcclient)) -> list[str]
Handler for method `2`. This method should be overridden by a subclass. ================================================ FILE: docs/reference/nex/natcheck.md ================================================ # Module: nintendo.nex.natcheck Implements a NAT check client. **async def detect_external_address**(socket: [UDPSocket](https://anynet.readthedocs.io/en/latest/reference/udp/#udpsocket)) -> (str, int)
Attempts to figure out the external IP address and port of the given socket. ================================================ FILE: docs/reference/nex/nattraversal.md ================================================ # Module: nintendo.nex.nattraversal Provides a client and server for the `NATTraversalProtocol`. This page was generated automatically from `nattraversal.proto`. **class** [NATTraversalClient](#nattraversalclient)
The client for the `NATTraversalProtocol`. **class** [NATTraversalServer](#nattraversalserver)
The server for the `NATTraversalProtocol`. ## NATTraversalClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`NATTraversalClient`](#nattraversalclient). **async def request_probe_initiation**(target_urls: list[[StationURL](common.md#stationurl)]) -> None
Calls method `1` on the server. **async def initiate_probe**(station_to_probe: [StationURL](common.md#stationurl)) -> None
Calls method `2` on the server. **async def request_probe_initiation_ext**(target_urls: list[[StationURL](common.md#stationurl)], station_to_probe: [StationURL](common.md#stationurl)) -> None
Calls method `3` on the server. **async def report_nat_traversal_result**(cid: int, result: bool) -> None
Calls method `4` on the server. **async def report_nat_properties**(natm: int, natf: int, rtt: int) -> None
Calls method `5` on the server. **async def get_relay_signature_key**() -> [RMCResponse](common.md)
Calls method `6` on the server. The RMC response has the following attributes:
mode: int
time: [DateTime](common.md#datetime)
address: str
port: int
address_type: int
game_server_id: int
**async def report_nat_traversal_result_detail**(cid: int, result: bool, detail: int, rtt: int) -> None
Calls method `7` on the server. ## NATTraversalServer **def _\_init__**()
Creates a new [`NATTraversalServer`](#nattraversalserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def request_probe_initiation**(client: [RMCClient](rmc.md#rmcclient), target_urls: list[[StationURL](common.md#stationurl)]) -> None
Handler for method `1`. This method should be overridden by a subclass. **async def initiate_probe**(client: [RMCClient](rmc.md#rmcclient), station_to_probe: [StationURL](common.md#stationurl)) -> None
Handler for method `2`. This method should be overridden by a subclass. **async def request_probe_initiation_ext**(client: [RMCClient](rmc.md#rmcclient), target_urls: list[[StationURL](common.md#stationurl)], station_to_probe: [StationURL](common.md#stationurl)) -> None
Handler for method `3`. This method should be overridden by a subclass. **async def report_nat_traversal_result**(client: [RMCClient](rmc.md#rmcclient), cid: int, result: bool) -> None
Handler for method `4`. This method should be overridden by a subclass. **async def report_nat_properties**(client: [RMCClient](rmc.md#rmcclient), natm: int, natf: int, rtt: int) -> None
Handler for method `5`. This method should be overridden by a subclass. **async def get_relay_signature_key**(client: [RMCClient](rmc.md#rmcclient)) -> [RMCResponse](common.md)
Handler for method `6`. This method should be overridden by a subclass. The RMC response must have the following attributes:
mode: int
time: [DateTime](common.md#datetime)
address: str
port: int
address_type: int
game_server_id: int
**async def report_nat_traversal_result_detail**(client: [RMCClient](rmc.md#rmcclient), cid: int, result: bool, detail: int, rtt: int) -> None
Handler for method `7`. This method should be overridden by a subclass. ================================================ FILE: docs/reference/nex/nintendonotification.md ================================================ # Module: nintendo.nex.nintendonotification Provides a client and server for the `NintendoNotificationProtocol`. This page was generated automatically from `nintendonotification.proto`. **class** [NintendoNotificationClient](#nintendonotificationclient)
The client for the `NintendoNotificationProtocol`. **class** [NintendoNotificationServer](#nintendonotificationserver)
The server for the `NintendoNotificationProtocol`. **class** [NintendoNotificationType](#nintendonotificationtype)
**class** [NintendoNotificationEvent](#nintendonotificationevent)([Structure](common.md))
**class** [NintendoNotificationEventGeneral](#nintendonotificationeventgeneral)([Data](common.md))
**class** [NintendoNotificationEventKeyValue](#nintendonotificationeventkeyvalue)([Data](common.md))
**class** [NintendoNotificationEventProfile](#nintendonotificationeventprofile)([Data](common.md))
**class** [StringKeyValue](#stringkeyvalue)([Data](common.md))
**class** [u32KeyValue](#u32keyvalue)([Data](common.md))
**class** [u64KeyValue](#u64keyvalue)([Data](common.md))
**class** [u8KeyValue](#u8keyvalue)([Data](common.md))
## NintendoNotificationClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`NintendoNotificationClient`](#nintendonotificationclient). **async def process_nintendo_notification_event**(event: [NintendoNotificationEvent](#nintendonotificationevent)) -> None
Calls method `1` on the server. **async def process_nintendo_notification_event_alt**(event: [NintendoNotificationEvent](#nintendonotificationevent)) -> None
Calls method `2` on the server. ## NintendoNotificationServer **def _\_init__**()
Creates a new [`NintendoNotificationServer`](#nintendonotificationserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def process_nintendo_notification_event**(client: [RMCClient](rmc.md#rmcclient), event: [NintendoNotificationEvent](#nintendonotificationevent)) -> None
Handler for method `1`. This method should be overridden by a subclass. **async def process_nintendo_notification_event_alt**(client: [RMCClient](rmc.md#rmcclient), event: [NintendoNotificationEvent](#nintendonotificationevent)) -> None
Handler for method `2`. This method should be overridden by a subclass. ## NintendoNotificationType This class defines the following constants:
`LOGOUT = 10`
`PRESENCE_CHANGE = 24`
`UNFRIENDED = 26`
`FRIENDED = 30`
`STATUS_CHANGE = 33`
## NintendoNotificationEvent **def _\_init__**()
Creates a new `NintendoNotificationEvent` instance. Required fields must be filled in manually. The following fields are defined in this class:
type: int
pid: int
data: [Data](common.md)

## NintendoNotificationEventGeneral **def _\_init__**()
Creates a new `NintendoNotificationEventGeneral` instance. Required fields must be filled in manually. The following fields are defined in this class:
param1: int
param2: int
param3: int
text: str

## NintendoNotificationEventKeyValue **def _\_init__**()
Creates a new `NintendoNotificationEventKeyValue` instance. Required fields must be filled in manually. The following fields are defined in this class:
u8: list[[u8KeyValue](#u8keyvalue)]
u32: list[[u32KeyValue](#u32keyvalue)]
u64: list[[u64KeyValue](#u64keyvalue)]
string: list[[StringKeyValue](#stringkeyvalue)]

## NintendoNotificationEventProfile **def _\_init__**()
Creates a new `NintendoNotificationEventProfile` instance. Required fields must be filled in manually. The following fields are defined in this class:
region: int
country: int
area: int
language: int
platform: int

## StringKeyValue **def _\_init__**()
Creates a new `StringKeyValue` instance. Required fields must be filled in manually. The following fields are defined in this class:
key: int
value: str

## u32KeyValue **def _\_init__**()
Creates a new `u32KeyValue` instance. Required fields must be filled in manually. The following fields are defined in this class:
key: int
value: int

## u64KeyValue **def _\_init__**()
Creates a new `u64KeyValue` instance. Required fields must be filled in manually. The following fields are defined in this class:
key: int
value: int

## u8KeyValue **def _\_init__**()
Creates a new `u8KeyValue` instance. Required fields must be filled in manually. The following fields are defined in this class:
key: int
value: int

================================================ FILE: docs/reference/nex/notification.md ================================================ # Module: nintendo.nex.notification Provides a client and server for the `NotificationProtocol`. This page was generated automatically from `notification.proto`. **class** [NotificationClient](#notificationclient)
The client for the `NotificationProtocol`. **class** [NotificationServer](#notificationserver)
The server for the `NotificationProtocol`. **class** [NotificationEvent](#notificationevent)([Structure](common.md))
## NotificationClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`NotificationClient`](#notificationclient). **async def process_notification_event**(event: [NotificationEvent](notification.md#notificationevent)) -> None
Calls method `1` on the server. ## NotificationServer **def _\_init__**()
Creates a new [`NotificationServer`](#notificationserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def process_notification_event**(client: [RMCClient](rmc.md#rmcclient), event: [NotificationEvent](notification.md#notificationevent)) -> None
Handler for method `1`. This method should be overridden by a subclass. ## NotificationEvent **def _\_init__**()
Creates a new `NotificationEvent` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
type: int
param1: int = 0
param2: int = 0
text: str = ""
If `nex.version` >= 30500:
param3: int = 0

If `nex.version` >= 40000:
If `revision` >= 1:
map: dict[str, object] = {}



================================================ FILE: docs/reference/nex/prudp.md ================================================ # Module: nintendo.nex.prudp Provides a client and server for PRUDP. Originally, PRUDP implemented reliable and secure transmission on top of UDP, but the Nintendo Switch introduced a 'Lite' mode in which PRUDP is implemented on top of TCP or WebSockets instead. **class** [PRUDPClient](#prudpclient)
A PRUDP client. **async with connect**(settings: [Settings](settings.md#settings), host: str, port: int, vport: int = 1, type: int = 10, context: [TLSContext](https://anynet.readthedocs.io/en/latest/reference/tls/#tlscontext) = None, credentials: [Credentials](kerberos.md#credentials) = None) -> [PRUDPClient](#prudpclient)
Creates a PRUDP client and connects it to the given address. If `context` is provided, and the underlying transport supports this, the connections is secured with TLS. If credentials are provided they are sent to the server in the connection request. Blocks until the connection is ready and handshake has been performed. **async with serve**(handler: Callable, settings: [Settings](settings.md#settings), host: str = "", port: int = 0, vport: int = 1, type: int = 10, context: [TLSContext](https://anynet.readthedocs.io/en/latest/reference/tls/#tlscontext) = None, key: bytes = None) -> None
Creates a PRUDP server and binds it to the given address. If `host` is empty, the local address of the default interface is used. If `port` is 0, it is chosen by the operating system. `handler` must be an `async` function that accepts a [`PRUDPClient`](#prudpclient). The client is closed automatically when `handler` returns. If `context` is provided, and the underlying transport supports this, the server is secured with TLS. If `key` is provided it is used to decrypt the Kerberos tickets in connection requests. If `key` is `None`, the payload of connection requests is ignored an all client connections are accepted. **async with connect_transport**(settings: [Settings](settings.md#settings), host: str, port: int, context: [TLSContext](https://anynet.readthedocs.io/en/latest/reference/tls/#tlscontext) = None) -> [PRUDPClientTransport](#prudpclienttransport)
Creates a transport connection for the PRUDP protocol. This can be used to establish multiple PRUDP connections with a single socket. **async with serve_transport**(settings: [Settings](settings.md#settings), host: str = "", port: int = 0, [TLSContext](https://anynet.readthedocs.io/en/latest/reference/tls/#tlscontext) = None) -> [PRUDPServerTransport](#prudpservertransport)
Creates a transport server for the PRUDP protocol. This can be used to host multiple PRUDP servers at a single port. ## PRUDPClient **async def send**(data: bytes, substream: int = 0) -> None
Sends a reliable data packet to the server through the given substream. Blocks if the send buffer is full. Packets are retransmitted automatically if no acknowledgement is received. **async def send_unreliable**(data: bytes) -> None
Sends an unreliable data packet to the server. Blocks if the send buffer is full.
**async def recv**(substream: int = 0) -> bytes
Receives a single reliable data packet from the server from the given substream. Blocks if no reliable data is available. **async def recv_unreliable**() -> bytes
Receives an unreliable data packet from the server. Blocks if no unreliable data is available. **async def close**() -> None
Closes the connection forcefully by sending an unreliable disconnect packet three times. **async def disconnect**() -> None
Closes the connection gracefully by sending a reliable disconnect packet. **def pid**() -> int
Returns the user id of the connected client. Returns `None` if the client is connected without credentials. **def minor_version**() -> int
Returns the PRUDP minor version that was negotiated during the handshake. **def local_address**() -> tuple[str, int]
Returns the local address of the client. **def remote_address**() -> tuple[str, int]
Returns the address that the client is connected to. **def local_sid**() -> int
Returns the local stream id (PRUDP port). **def remote_sid**() -> int
Returns the remote stream id (PRUDP port). ## PRUDPClientTransport **async with connect**(port: int, type: int = 10, credentials: credentials: [Credentials](kerberos.md#credentials) = None) -> [PRUDPClient](#prudpclient)
Establishes a new PRUDP connection with the given PRUDP port. **def local_address**() -> tuple[str, int]
Returns the local address of the client. **def remote_address**() -> tuple[str, int]
Returns the address that the client is connected to. ## PRUDPServerTransport **async with serve**(handler: Callable, port: int, type: int = 10, key: bytes = None) -> None
Creates a new PRUDP server at the given PRUDP port. ================================================ FILE: docs/reference/nex/ranking.md ================================================ # Module: nintendo.nex.ranking Provides a client and server for the `RankingProtocol`. This page was generated automatically from `ranking.proto`. **class** [RankingClient](#rankingclient)
The client for the `RankingProtocol`. **class** [RankingServer](#rankingserver)
The server for the `RankingProtocol`. **class** [RankingMode](#rankingmode)
**class** [RankingOrderCalc](#rankingordercalc)
**class** [RankingStatFlags](#rankingstatflags)
**class** [RankingCachedResult](#rankingcachedresult)([RankingResult](#rankingresult))
**class** [RankingChangeAttributesParam](#rankingchangeattributesparam)([Structure](common.md))
**class** [RankingOrderParam](#rankingorderparam)([Structure](common.md))
**class** [RankingRankData](#rankingrankdata)([Structure](common.md))
**class** [RankingResult](#rankingresult)([Structure](common.md))
**class** [RankingScoreData](#rankingscoredata)([Structure](common.md))
**class** [RankingStats](#rankingstats)([Structure](common.md))
## RankingClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`RankingClient`](#rankingclient). **async def upload_score**(score_data: [RankingScoreData](#rankingscoredata), unique_id: int) -> None
Calls method `1` on the server. **async def delete_score**(category: int, unique_id: int) -> None
Calls method `2` on the server. **async def delete_all_scores**(unique_id: int) -> None
Calls method `3` on the server. **async def upload_common_data**(common_data: bytes, unique_id: int) -> None
Calls method `4` on the server. **async def delete_common_data**(unique_id: int) -> None
Calls method `5` on the server. **async def get_common_data**(unique_id: int) -> bytes
Calls method `6` on the server. **async def change_attributes**(category: int, param: [RankingChangeAttributesParam](#rankingchangeattributesparam), unique_id: int) -> None
Calls method `7` on the server. **async def change_all_attributes**(param: [RankingChangeAttributesParam](#rankingchangeattributesparam), unique_id: int) -> None
Calls method `8` on the server. **async def get_ranking**(mode: int, category: int, order: [RankingOrderParam](#rankingorderparam), unique_id: int, pid: int) -> [RankingResult](#rankingresult)
Calls method `9` on the server. **async def get_approx_order**(category: int, order: [RankingOrderParam](#rankingorderparam), score: int, unique_id: int, pid: int) -> int
Calls method `10` on the server. **async def get_stats**(category: int, order: [RankingOrderParam](#rankingorderparam), flags: int) -> [RankingStats](#rankingstats)
Calls method `11` on the server. **async def get_ranking_by_pid_list**(pids: list[int], mode: int, category: int, order: [RankingOrderParam](#rankingorderparam), unique_id: int) -> [RankingResult](#rankingresult)
Calls method `12` on the server. **async def get_ranking_by_unique_id_list**(ids: list[int], mode: int, category: int, order: [RankingOrderParam](#rankingorderparam), unique_id: int) -> [RankingResult](#rankingresult)
Calls method `13` on the server. **async def get_cached_topx_ranking**(category: int, order: [RankingOrderParam](#rankingorderparam)) -> [RankingCachedResult](#rankingcachedresult)
Calls method `14` on the server. **async def get_cached_topx_rankings**(categories: list[int], order: list[[RankingOrderParam](#rankingorderparam)]) -> list[[RankingCachedResult](#rankingcachedresult)]
Calls method `15` on the server. ## RankingServer **def _\_init__**()
Creates a new [`RankingServer`](#rankingserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def upload_score**(client: [RMCClient](rmc.md#rmcclient), score_data: [RankingScoreData](#rankingscoredata), unique_id: int) -> None
Handler for method `1`. This method should be overridden by a subclass. **async def delete_score**(client: [RMCClient](rmc.md#rmcclient), category: int, unique_id: int) -> None
Handler for method `2`. This method should be overridden by a subclass. **async def delete_all_scores**(client: [RMCClient](rmc.md#rmcclient), unique_id: int) -> None
Handler for method `3`. This method should be overridden by a subclass. **async def upload_common_data**(client: [RMCClient](rmc.md#rmcclient), common_data: bytes, unique_id: int) -> None
Handler for method `4`. This method should be overridden by a subclass. **async def delete_common_data**(client: [RMCClient](rmc.md#rmcclient), unique_id: int) -> None
Handler for method `5`. This method should be overridden by a subclass. **async def get_common_data**(client: [RMCClient](rmc.md#rmcclient), unique_id: int) -> bytes
Handler for method `6`. This method should be overridden by a subclass. **async def change_attributes**(client: [RMCClient](rmc.md#rmcclient), category: int, param: [RankingChangeAttributesParam](#rankingchangeattributesparam), unique_id: int) -> None
Handler for method `7`. This method should be overridden by a subclass. **async def change_all_attributes**(client: [RMCClient](rmc.md#rmcclient), param: [RankingChangeAttributesParam](#rankingchangeattributesparam), unique_id: int) -> None
Handler for method `8`. This method should be overridden by a subclass. **async def get_ranking**(client: [RMCClient](rmc.md#rmcclient), mode: int, category: int, order: [RankingOrderParam](#rankingorderparam), unique_id: int, pid: int) -> [RankingResult](#rankingresult)
Handler for method `9`. This method should be overridden by a subclass. **async def get_approx_order**(client: [RMCClient](rmc.md#rmcclient), category: int, order: [RankingOrderParam](#rankingorderparam), score: int, unique_id: int, pid: int) -> int
Handler for method `10`. This method should be overridden by a subclass. **async def get_stats**(client: [RMCClient](rmc.md#rmcclient), category: int, order: [RankingOrderParam](#rankingorderparam), flags: int) -> [RankingStats](#rankingstats)
Handler for method `11`. This method should be overridden by a subclass. **async def get_ranking_by_pid_list**(client: [RMCClient](rmc.md#rmcclient), pids: list[int], mode: int, category: int, order: [RankingOrderParam](#rankingorderparam), unique_id: int) -> [RankingResult](#rankingresult)
Handler for method `12`. This method should be overridden by a subclass. **async def get_ranking_by_unique_id_list**(client: [RMCClient](rmc.md#rmcclient), ids: list[int], mode: int, category: int, order: [RankingOrderParam](#rankingorderparam), unique_id: int) -> [RankingResult](#rankingresult)
Handler for method `13`. This method should be overridden by a subclass. **async def get_cached_topx_ranking**(client: [RMCClient](rmc.md#rmcclient), category: int, order: [RankingOrderParam](#rankingorderparam)) -> [RankingCachedResult](#rankingcachedresult)
Handler for method `14`. This method should be overridden by a subclass. **async def get_cached_topx_rankings**(client: [RMCClient](rmc.md#rmcclient), categories: list[int], order: list[[RankingOrderParam](#rankingorderparam)]) -> list[[RankingCachedResult](#rankingcachedresult)]
Handler for method `15`. This method should be overridden by a subclass. ## RankingMode This class defines the following constants:
`GLOBAL = 0`
`GLOBAL_AROUND_SELF = 1`
`SELF = 4`
## RankingOrderCalc This class defines the following constants:
`STANDARD = 0`
`ORDINAL = 1`
## RankingStatFlags This class defines the following constants:
`RANKING_COUNT = 1`
`TOTAL_SCORE = 2`
`LOWEST_SCORE = 4`
`HIGHEST_SCORE = 8`
`AVERAGE_SCORE = 16`
`ALL = 31`
## RankingCachedResult **def _\_init__**()
Creates a new `RankingCachedResult` instance. Required fields must be filled in manually. The following fields are defined in this class:
created_time: [DateTime](common.md#datetime)
expired_time: [DateTime](common.md#datetime)
max_length: int

## RankingChangeAttributesParam **def _\_init__**()
Creates a new `RankingChangeAttributesParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
flags: int
groups: list[int]
param: int

## RankingOrderParam **def _\_init__**()
Creates a new `RankingOrderParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
order_calc: int = 0
group_index: int = 255
group_num: int = 0
time_scope: int = 2
offset: int = 0
count: int = 10

## RankingRankData **def _\_init__**()
Creates a new `RankingRankData` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
unique_id: int
rank: int
category: int
score: int
groups: list[int]
param: int
common_data: bytes
If `nex.version` >= 40000:
update_time: [DateTime](common.md#datetime)


## RankingResult **def _\_init__**()
Creates a new `RankingResult` instance. Required fields must be filled in manually. The following fields are defined in this class:
data: list[[RankingRankData](#rankingrankdata)]
total: int
since_time: [DateTime](common.md#datetime)

## RankingScoreData **def _\_init__**()
Creates a new `RankingScoreData` instance. Required fields must be filled in manually. The following fields are defined in this class:
category: int
score: int
order: int
update_mode: int
groups: list[int]
param: int

## RankingStats **def _\_init__**()
Creates a new `RankingStats` instance. Required fields must be filled in manually. The following fields are defined in this class:
stats: list[float]

================================================ FILE: docs/reference/nex/ranking2.md ================================================ # Module: nintendo.nex.ranking2 Provides a client and server for the `Ranking2Protocol`. This page was generated automatically from `ranking2.proto`. **class** [Ranking2Client](#ranking2client)
The client for the `Ranking2Protocol`. **class** [Ranking2Server](#ranking2server)
The server for the `Ranking2Protocol`. **class** [RankingMode](#rankingmode)
**class** [Ranking2CategorySetting](#ranking2categorysetting)([Structure](common.md))
**class** [Ranking2ChartInfo](#ranking2chartinfo)([Structure](common.md))
**class** [Ranking2ChartInfoInput](#ranking2chartinfoinput)([Structure](common.md))
**class** [Ranking2CommonData](#ranking2commondata)([Structure](common.md))
**class** [Ranking2EstimateScoreRankInput](#ranking2estimatescorerankinput)([Structure](common.md))
**class** [Ranking2EstimateScoreRankOutput](#ranking2estimatescorerankoutput)([Structure](common.md))
**class** [Ranking2GetByListParam](#ranking2getbylistparam)([Structure](common.md))
**class** [Ranking2GetParam](#ranking2getparam)([Structure](common.md))
**class** [Ranking2Info](#ranking2info)([Structure](common.md))
**class** [Ranking2RankData](#ranking2rankdata)([Structure](common.md))
**class** [Ranking2ScoreData](#ranking2scoredata)([Structure](common.md))
## Ranking2Client **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`Ranking2Client`](#ranking2client). **async def put_score**(socres: list[[Ranking2ScoreData](#ranking2scoredata)], unique_id: int) -> None
Calls method `1` on the server. **async def get_common_data**(option_flags: int, pid: int, unique_id: int) -> [Ranking2CommonData](#ranking2commondata)
Calls method `2` on the server. **async def put_common_data**(data: [Ranking2CommonData](#ranking2commondata), unique_id: int) -> None
Calls method `3` on the server. **async def delete_common_data**(unique_id: int) -> None
Calls method `4` on the server. **async def get_ranking**(param: [Ranking2GetParam](#ranking2getparam)) -> [Ranking2Info](#ranking2info)
Calls method `5` on the server. **async def get_ranking_by_principal_id**(param: [Ranking2GetByListParam](#ranking2getbylistparam), pids: list[int]) -> [Ranking2Info](#ranking2info)
Calls method `6` on the server. **async def get_category_setting**(category: int) -> [Ranking2CategorySetting](#ranking2categorysetting)
Calls method `7` on the server. **async def get_ranking_chart**(input: [Ranking2ChartInfoInput](#ranking2chartinfoinput)) -> [Ranking2ChartInfo](#ranking2chartinfo)
Calls method `8` on the server. **async def get_ranking_charts**(inputs: list[[Ranking2ChartInfoInput](#ranking2chartinfoinput)]) -> list[[Ranking2ChartInfo](#ranking2chartinfo)]
Calls method `9` on the server. **async def get_estimate_score_rank**(input: [Ranking2EstimateScoreRankInput](#ranking2estimatescorerankinput)) -> [Ranking2EstimateScoreRankOutput](#ranking2estimatescorerankoutput)
Calls method `10` on the server. ## Ranking2Server **def _\_init__**()
Creates a new [`Ranking2Server`](#ranking2server). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def put_score**(client: [RMCClient](rmc.md#rmcclient), socres: list[[Ranking2ScoreData](#ranking2scoredata)], unique_id: int) -> None
Handler for method `1`. This method should be overridden by a subclass. **async def get_common_data**(client: [RMCClient](rmc.md#rmcclient), option_flags: int, pid: int, unique_id: int) -> [Ranking2CommonData](#ranking2commondata)
Handler for method `2`. This method should be overridden by a subclass. **async def put_common_data**(client: [RMCClient](rmc.md#rmcclient), data: [Ranking2CommonData](#ranking2commondata), unique_id: int) -> None
Handler for method `3`. This method should be overridden by a subclass. **async def delete_common_data**(client: [RMCClient](rmc.md#rmcclient), unique_id: int) -> None
Handler for method `4`. This method should be overridden by a subclass. **async def get_ranking**(client: [RMCClient](rmc.md#rmcclient), param: [Ranking2GetParam](#ranking2getparam)) -> [Ranking2Info](#ranking2info)
Handler for method `5`. This method should be overridden by a subclass. **async def get_ranking_by_principal_id**(client: [RMCClient](rmc.md#rmcclient), param: [Ranking2GetByListParam](#ranking2getbylistparam), pids: list[int]) -> [Ranking2Info](#ranking2info)
Handler for method `6`. This method should be overridden by a subclass. **async def get_category_setting**(client: [RMCClient](rmc.md#rmcclient), category: int) -> [Ranking2CategorySetting](#ranking2categorysetting)
Handler for method `7`. This method should be overridden by a subclass. **async def get_ranking_chart**(client: [RMCClient](rmc.md#rmcclient), input: [Ranking2ChartInfoInput](#ranking2chartinfoinput)) -> [Ranking2ChartInfo](#ranking2chartinfo)
Handler for method `8`. This method should be overridden by a subclass. **async def get_ranking_charts**(client: [RMCClient](rmc.md#rmcclient), inputs: list[[Ranking2ChartInfoInput](#ranking2chartinfoinput)]) -> list[[Ranking2ChartInfo](#ranking2chartinfo)]
Handler for method `9`. This method should be overridden by a subclass. **async def get_estimate_score_rank**(client: [RMCClient](rmc.md#rmcclient), input: [Ranking2EstimateScoreRankInput](#ranking2estimatescorerankinput)) -> [Ranking2EstimateScoreRankOutput](#ranking2estimatescorerankoutput)
Handler for method `10`. This method should be overridden by a subclass. ## RankingMode This class defines the following constants:
`GLOBAL_AROUND_SELF = 1`
`GLOBAL = 2`
`FRIENDS = 3`
## Ranking2CategorySetting **def _\_init__**()
Creates a new `Ranking2CategorySetting` instance. Required fields must be filled in manually. The following fields are defined in this class:
min_score: int
max_score: int
lowest_rank: int
reset_month: int
reset_day: int
reset_hour: int
reset_mode: int
max_seasons_to_go_back: int
score_order: bool

## Ranking2ChartInfo **def _\_init__**()
Creates a new `Ranking2ChartInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
create_time: [DateTime](common.md#datetime)
index: int
category: int
season: int
bins_size: int
sampling_rate: int
score_order: bool
estimate_length: int
estimate_highest_score: int
estimate_lowest_score: int
estimate_median_score: int
estimate_average_score: float
highest_bins_score: int
lowest_bins_score: int
bins_width: int
attribute1: int
attribute2: int
quantities: list[int]

## Ranking2ChartInfoInput **def _\_init__**()
Creates a new `Ranking2ChartInfoInput` instance. Required fields must be filled in manually. The following fields are defined in this class:
chart_index: int
seasons_to_go_back: int

## Ranking2CommonData **def _\_init__**()
Creates a new `Ranking2CommonData` instance. Required fields must be filled in manually. The following fields are defined in this class:
username: str
mii: bytes
binary_data: bytes

## Ranking2EstimateScoreRankInput **def _\_init__**()
Creates a new `Ranking2EstimateScoreRankInput` instance. Required fields must be filled in manually. The following fields are defined in this class:
category: int
seasons_to_go_back: int
score: int

## Ranking2EstimateScoreRankOutput **def _\_init__**()
Creates a new `Ranking2EstimateScoreRankOutput` instance. Required fields must be filled in manually. The following fields are defined in this class:
rank: int
length: int
score: int
category: int
season: int
sampling_rate: int

## Ranking2GetByListParam **def _\_init__**()
Creates a new `Ranking2GetByListParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
category: int
offset: int
length: int
sort_flags: int
option_flags: int
seasons_to_go_back: int

## Ranking2GetParam **def _\_init__**()
Creates a new `Ranking2GetParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
unique_id: int = 0
pid: int = 0
category: int
offset: int = 0
count: int = 10
sort_flags: int = 0
option_flags: int = 0
mode: int = 2
seasons_to_go_back: int = 0

## Ranking2Info **def _\_init__**()
Creates a new `Ranking2Info` instance. Required fields must be filled in manually. The following fields are defined in this class:
data: list[[Ranking2RankData](#ranking2rankdata)]
lowest_rank: int
num_entries: int
season: int

## Ranking2RankData **def _\_init__**()
Creates a new `Ranking2RankData` instance. Required fields must be filled in manually. The following fields are defined in this class:
misc: int
unique_id: int
pid: int
rank: int
score: int
common_data: [Ranking2CommonData](#ranking2commondata) = [Ranking2CommonData](#ranking2commondata)()

## Ranking2ScoreData **def _\_init__**()
Creates a new `Ranking2ScoreData` instance. Required fields must be filled in manually. The following fields are defined in this class:
misc: int
category: int
score: int

================================================ FILE: docs/reference/nex/ranking2_eagle.md ================================================ # Module: nintendo.nex.ranking2_eagle Provides a client and server for the `Ranking2Protocol`. This page was generated automatically from `ranking2_eagle.proto`. **class** [Ranking2Client](#ranking2client)
The client for the `Ranking2Protocol`. **class** [Ranking2Server](#ranking2server)
The server for the `Ranking2Protocol`. **class** [RankingMode](#rankingmode)
**class** [Ranking2CategorySetting](#ranking2categorysetting)([Structure](common.md))
**class** [Ranking2ChartInfo](#ranking2chartinfo)([Structure](common.md))
**class** [Ranking2ChartInfoInput](#ranking2chartinfoinput)([Structure](common.md))
**class** [Ranking2CommonData](#ranking2commondata)([Structure](common.md))
**class** [Ranking2EstimateMyScoreRankInput](#ranking2estimatemyscorerankinput)([Structure](common.md))
**class** [Ranking2EstimateScoreRankInput](#ranking2estimatescorerankinput)([Structure](common.md))
**class** [Ranking2EstimateScoreRankOutput](#ranking2estimatescorerankoutput)([Structure](common.md))
**class** [Ranking2GetByListParam](#ranking2getbylistparam)([Structure](common.md))
**class** [Ranking2GetParam](#ranking2getparam)([Structure](common.md))
**class** [Ranking2Info](#ranking2info)([Structure](common.md))
**class** [Ranking2RankData](#ranking2rankdata)([Structure](common.md))
**class** [Ranking2ScoreData](#ranking2scoredata)([Structure](common.md))
## Ranking2Client **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`Ranking2Client`](#ranking2client). **async def put_score**(socres: list[[Ranking2ScoreData](#ranking2scoredata)], unique_id: int) -> None
Calls method `1` on the server. **async def get_common_data**(option_flags: int, pid: int, unique_id: int) -> [Ranking2CommonData](#ranking2commondata)
Calls method `2` on the server. **async def put_common_data**(data: [Ranking2CommonData](#ranking2commondata), unique_id: int) -> None
Calls method `3` on the server. **async def delete_common_data**(unique_id: int) -> None
Calls method `4` on the server. **async def get_ranking**(param: [Ranking2GetParam](#ranking2getparam)) -> [Ranking2Info](#ranking2info)
Calls method `5` on the server. **async def get_ranking_by_principal_id**(param: [Ranking2GetByListParam](#ranking2getbylistparam), pids: list[int]) -> [Ranking2Info](#ranking2info)
Calls method `6` on the server. **async def get_category_setting**(category: int) -> [Ranking2CategorySetting](#ranking2categorysetting)
Calls method `7` on the server. **async def get_ranking_chart**(input: [Ranking2ChartInfoInput](#ranking2chartinfoinput)) -> [Ranking2ChartInfo](#ranking2chartinfo)
Calls method `8` on the server. **async def get_ranking_charts**(inputs: list[[Ranking2ChartInfoInput](#ranking2chartinfoinput)]) -> list[[Ranking2ChartInfo](#ranking2chartinfo)]
Calls method `9` on the server. **async def get_estimate_score_rank**(input: [Ranking2EstimateScoreRankInput](#ranking2estimatescorerankinput)) -> [Ranking2EstimateScoreRankOutput](#ranking2estimatescorerankoutput)
Calls method `10` on the server. **async def get_estimate_my_score_rank**(input: [Ranking2EstimateMyScoreRankInput](#ranking2estimatemyscorerankinput)) -> [Ranking2EstimateScoreRankOutput](#ranking2estimatescorerankoutput)
Calls method `11` on the server. ## Ranking2Server **def _\_init__**()
Creates a new [`Ranking2Server`](#ranking2server). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def put_score**(client: [RMCClient](rmc.md#rmcclient), socres: list[[Ranking2ScoreData](#ranking2scoredata)], unique_id: int) -> None
Handler for method `1`. This method should be overridden by a subclass. **async def get_common_data**(client: [RMCClient](rmc.md#rmcclient), option_flags: int, pid: int, unique_id: int) -> [Ranking2CommonData](#ranking2commondata)
Handler for method `2`. This method should be overridden by a subclass. **async def put_common_data**(client: [RMCClient](rmc.md#rmcclient), data: [Ranking2CommonData](#ranking2commondata), unique_id: int) -> None
Handler for method `3`. This method should be overridden by a subclass. **async def delete_common_data**(client: [RMCClient](rmc.md#rmcclient), unique_id: int) -> None
Handler for method `4`. This method should be overridden by a subclass. **async def get_ranking**(client: [RMCClient](rmc.md#rmcclient), param: [Ranking2GetParam](#ranking2getparam)) -> [Ranking2Info](#ranking2info)
Handler for method `5`. This method should be overridden by a subclass. **async def get_ranking_by_principal_id**(client: [RMCClient](rmc.md#rmcclient), param: [Ranking2GetByListParam](#ranking2getbylistparam), pids: list[int]) -> [Ranking2Info](#ranking2info)
Handler for method `6`. This method should be overridden by a subclass. **async def get_category_setting**(client: [RMCClient](rmc.md#rmcclient), category: int) -> [Ranking2CategorySetting](#ranking2categorysetting)
Handler for method `7`. This method should be overridden by a subclass. **async def get_ranking_chart**(client: [RMCClient](rmc.md#rmcclient), input: [Ranking2ChartInfoInput](#ranking2chartinfoinput)) -> [Ranking2ChartInfo](#ranking2chartinfo)
Handler for method `8`. This method should be overridden by a subclass. **async def get_ranking_charts**(client: [RMCClient](rmc.md#rmcclient), inputs: list[[Ranking2ChartInfoInput](#ranking2chartinfoinput)]) -> list[[Ranking2ChartInfo](#ranking2chartinfo)]
Handler for method `9`. This method should be overridden by a subclass. **async def get_estimate_score_rank**(client: [RMCClient](rmc.md#rmcclient), input: [Ranking2EstimateScoreRankInput](#ranking2estimatescorerankinput)) -> [Ranking2EstimateScoreRankOutput](#ranking2estimatescorerankoutput)
Handler for method `10`. This method should be overridden by a subclass. **async def get_estimate_my_score_rank**(client: [RMCClient](rmc.md#rmcclient), input: [Ranking2EstimateMyScoreRankInput](#ranking2estimatemyscorerankinput)) -> [Ranking2EstimateScoreRankOutput](#ranking2estimatescorerankoutput)
Handler for method `11`. This method should be overridden by a subclass. ## RankingMode This class defines the following constants:
`GLOBAL_AROUND_SELF = 1`
`GLOBAL = 2`
`FRIENDS = 3`
## Ranking2CategorySetting **def _\_init__**()
Creates a new `Ranking2CategorySetting` instance. Required fields must be filled in manually. The following fields are defined in this class:
min_score: int
max_score: int
lowest_rank: int
reset_month: int
reset_day: int
reset_hour: int
reset_mode: int
max_seasons_to_go_back: int
score_order: bool

## Ranking2ChartInfo **def _\_init__**()
Creates a new `Ranking2ChartInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
create_time: [DateTime](common.md#datetime)
index: int
category: int
season: int
bins_size: int
sampling_rate: int
score_order: bool
estimate_length: int
estimate_highest_score: int
estimate_lowest_score: int
estimate_median_score: int
estimate_average_score: float
highest_bins_score: int
lowest_bins_score: int
bins_width: int
attribute1: int
attribute2: int
quantities: list[int]

## Ranking2ChartInfoInput **def _\_init__**()
Creates a new `Ranking2ChartInfoInput` instance. Required fields must be filled in manually. The following fields are defined in this class:
chart_index: int
seasons_to_go_back: int

## Ranking2CommonData **def _\_init__**()
Creates a new `Ranking2CommonData` instance. Required fields must be filled in manually. The following fields are defined in this class:
username: str
mii: bytes
binary_data: bytes

## Ranking2EstimateMyScoreRankInput **def _\_init__**()
Creates a new `Ranking2EstimateMyScoreRankInput` instance. Required fields must be filled in manually. The following fields are defined in this class:
category: int
seasons_to_go_back: int

## Ranking2EstimateScoreRankInput **def _\_init__**()
Creates a new `Ranking2EstimateScoreRankInput` instance. Required fields must be filled in manually. The following fields are defined in this class:
category: int
seasons_to_go_back: int
score: int

## Ranking2EstimateScoreRankOutput **def _\_init__**()
Creates a new `Ranking2EstimateScoreRankOutput` instance. Required fields must be filled in manually. The following fields are defined in this class:
rank: int
length: int
score: int
category: int
season: int
sampling_rate: int

## Ranking2GetByListParam **def _\_init__**()
Creates a new `Ranking2GetByListParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
category: int
offset: int
length: int
sort_flags: int
option_flags: int
seasons_to_go_back: int

## Ranking2GetParam **def _\_init__**()
Creates a new `Ranking2GetParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
unique_id: int = 0
pid: int = 0
category: int
offset: int = 0
count: int = 10
sort_flags: int = 0
option_flags: int = 0
mode: int = 2
seasons_to_go_back: int = 0

## Ranking2Info **def _\_init__**()
Creates a new `Ranking2Info` instance. Required fields must be filled in manually. The following fields are defined in this class:
data: list[[Ranking2RankData](#ranking2rankdata)]
lowest_rank: int
num_entries: int
season: int

## Ranking2RankData **def _\_init__**()
Creates a new `Ranking2RankData` instance. Required fields must be filled in manually. The following fields are defined in this class:
misc: int
unique_id: int
pid: int
rank: int
score: int
common_data: [Ranking2CommonData](#ranking2commondata) = [Ranking2CommonData](#ranking2commondata)()

## Ranking2ScoreData **def _\_init__**()
Creates a new `Ranking2ScoreData` instance. Required fields must be filled in manually. The following fields are defined in this class:
misc: int
category: int
score: int

================================================ FILE: docs/reference/nex/ranking_mk8.md ================================================ # Module: nintendo.nex.ranking_mk8 Provides a client and server for the `RankingProtocolMK8`. This page was generated automatically from `ranking_mk8.proto`. **class** [RankingClientMK8](#rankingclientmk8)
The client for the `RankingProtocolMK8`. **class** [RankingServerMK8](#rankingservermk8)
The server for the `RankingProtocolMK8`. **class** [RankingMode](#rankingmode)
**class** [RankingOrderCalc](#rankingordercalc)
**class** [RankingStatFlags](#rankingstatflags)
**class** [CompetitionRankingInfo](#competitionrankinginfo)([Structure](common.md))
**class** [CompetitionRankingInfoGetParam](#competitionrankinginfogetparam)([Structure](common.md))
**class** [CompetitionRankingUploadScoreParam](#competitionrankinguploadscoreparam)([Structure](common.md))
**class** [RankingCachedResult](#rankingcachedresult)([RankingResult](#rankingresult))
**class** [RankingChangeAttributesParam](#rankingchangeattributesparam)([Structure](common.md))
**class** [RankingOrderParam](#rankingorderparam)([Structure](common.md))
**class** [RankingRankData](#rankingrankdata)([Structure](common.md))
**class** [RankingResult](#rankingresult)([Structure](common.md))
**class** [RankingScoreData](#rankingscoredata)([Structure](common.md))
**class** [RankingStats](#rankingstats)([Structure](common.md))
## RankingClientMK8 **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`RankingClientMK8`](#rankingclientmk8). **async def upload_score**(score_data: [RankingScoreData](#rankingscoredata), unique_id: int) -> None
Calls method `1` on the server. **async def delete_score**(category: int, unique_id: int) -> None
Calls method `2` on the server. **async def delete_all_scores**(unique_id: int) -> None
Calls method `3` on the server. **async def upload_common_data**(common_data: bytes, unique_id: int) -> None
Calls method `4` on the server. **async def delete_common_data**(unique_id: int) -> None
Calls method `5` on the server. **async def get_common_data**(unique_id: int) -> bytes
Calls method `6` on the server. **async def change_attributes**(category: int, param: [RankingChangeAttributesParam](#rankingchangeattributesparam), unique_id: int) -> None
Calls method `7` on the server. **async def change_all_attributes**(param: [RankingChangeAttributesParam](#rankingchangeattributesparam), unique_id: int) -> None
Calls method `8` on the server. **async def get_ranking**(mode: int, category: int, order: [RankingOrderParam](#rankingorderparam), unique_id: int, pid: int) -> [RankingResult](#rankingresult)
Calls method `9` on the server. **async def get_approx_order**(category: int, order: [RankingOrderParam](#rankingorderparam), score: int, unique_id: int, pid: int) -> int
Calls method `10` on the server. **async def get_stats**(category: int, order: [RankingOrderParam](#rankingorderparam), flags: int) -> [RankingStats](#rankingstats)
Calls method `11` on the server. **async def get_ranking_by_pid_list**(pids: list[int], mode: int, category: int, order: [RankingOrderParam](#rankingorderparam), unique_id: int) -> [RankingResult](#rankingresult)
Calls method `12` on the server. **async def get_ranking_by_unique_id_list**(ids: list[int], mode: int, category: int, order: [RankingOrderParam](#rankingorderparam), unique_id: int) -> [RankingResult](#rankingresult)
Calls method `13` on the server. **async def upload_competition_ranking_score**(param: [CompetitionRankingUploadScoreParam](#competitionrankinguploadscoreparam)) -> bool
Calls method `15` on the server. **async def get_competition_info**(param: [CompetitionRankingInfoGetParam](#competitionrankinginfogetparam)) -> list[[CompetitionRankingInfo](#competitionrankinginfo)]
Calls method `16` on the server. ## RankingServerMK8 **def _\_init__**()
Creates a new [`RankingServerMK8`](#rankingservermk8). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def upload_score**(client: [RMCClient](rmc.md#rmcclient), score_data: [RankingScoreData](#rankingscoredata), unique_id: int) -> None
Handler for method `1`. This method should be overridden by a subclass. **async def delete_score**(client: [RMCClient](rmc.md#rmcclient), category: int, unique_id: int) -> None
Handler for method `2`. This method should be overridden by a subclass. **async def delete_all_scores**(client: [RMCClient](rmc.md#rmcclient), unique_id: int) -> None
Handler for method `3`. This method should be overridden by a subclass. **async def upload_common_data**(client: [RMCClient](rmc.md#rmcclient), common_data: bytes, unique_id: int) -> None
Handler for method `4`. This method should be overridden by a subclass. **async def delete_common_data**(client: [RMCClient](rmc.md#rmcclient), unique_id: int) -> None
Handler for method `5`. This method should be overridden by a subclass. **async def get_common_data**(client: [RMCClient](rmc.md#rmcclient), unique_id: int) -> bytes
Handler for method `6`. This method should be overridden by a subclass. **async def change_attributes**(client: [RMCClient](rmc.md#rmcclient), category: int, param: [RankingChangeAttributesParam](#rankingchangeattributesparam), unique_id: int) -> None
Handler for method `7`. This method should be overridden by a subclass. **async def change_all_attributes**(client: [RMCClient](rmc.md#rmcclient), param: [RankingChangeAttributesParam](#rankingchangeattributesparam), unique_id: int) -> None
Handler for method `8`. This method should be overridden by a subclass. **async def get_ranking**(client: [RMCClient](rmc.md#rmcclient), mode: int, category: int, order: [RankingOrderParam](#rankingorderparam), unique_id: int, pid: int) -> [RankingResult](#rankingresult)
Handler for method `9`. This method should be overridden by a subclass. **async def get_approx_order**(client: [RMCClient](rmc.md#rmcclient), category: int, order: [RankingOrderParam](#rankingorderparam), score: int, unique_id: int, pid: int) -> int
Handler for method `10`. This method should be overridden by a subclass. **async def get_stats**(client: [RMCClient](rmc.md#rmcclient), category: int, order: [RankingOrderParam](#rankingorderparam), flags: int) -> [RankingStats](#rankingstats)
Handler for method `11`. This method should be overridden by a subclass. **async def get_ranking_by_pid_list**(client: [RMCClient](rmc.md#rmcclient), pids: list[int], mode: int, category: int, order: [RankingOrderParam](#rankingorderparam), unique_id: int) -> [RankingResult](#rankingresult)
Handler for method `12`. This method should be overridden by a subclass. **async def get_ranking_by_unique_id_list**(client: [RMCClient](rmc.md#rmcclient), ids: list[int], mode: int, category: int, order: [RankingOrderParam](#rankingorderparam), unique_id: int) -> [RankingResult](#rankingresult)
Handler for method `13`. This method should be overridden by a subclass. **async def upload_competition_ranking_score**(client: [RMCClient](rmc.md#rmcclient), param: [CompetitionRankingUploadScoreParam](#competitionrankinguploadscoreparam)) -> bool
Handler for method `15`. This method should be overridden by a subclass. **async def get_competition_info**(client: [RMCClient](rmc.md#rmcclient), param: [CompetitionRankingInfoGetParam](#competitionrankinginfogetparam)) -> list[[CompetitionRankingInfo](#competitionrankinginfo)]
Handler for method `16`. This method should be overridden by a subclass. ## RankingMode This class defines the following constants:
`GLOBAL = 0`
`GLOBAL_AROUND_SELF = 1`
`SELF = 4`
## RankingOrderCalc This class defines the following constants:
`STANDARD = 0`
`ORDINAL = 1`
## RankingStatFlags This class defines the following constants:
`RANKING_COUNT = 1`
`TOTAL_SCORE = 2`
`LOWEST_SCORE = 4`
`HIGHEST_SCORE = 8`
`AVERAGE_SCORE = 16`
`ALL = 31`
## CompetitionRankingInfo **def _\_init__**()
Creates a new `CompetitionRankingInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
id: int
num_participants: int
team_scores: list[int]

## CompetitionRankingInfoGetParam **def _\_init__**()
Creates a new `CompetitionRankingInfoGetParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
rank_order: int
range: [ResultRange](common.md#resultrange) = [ResultRange](common.md#resultrange)()

## CompetitionRankingUploadScoreParam **def _\_init__**()
Creates a new `CompetitionRankingUploadScoreParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
id: int
season_id: int
unk3: int
score: int
team_id: int
team_score: int
is_first_upload: bool
metadata: bytes

## RankingCachedResult **def _\_init__**()
Creates a new `RankingCachedResult` instance. Required fields must be filled in manually. The following fields are defined in this class:
created_time: [DateTime](common.md#datetime)
expired_time: [DateTime](common.md#datetime)
max_length: int

## RankingChangeAttributesParam **def _\_init__**()
Creates a new `RankingChangeAttributesParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
flags: int
groups: list[int]
param: int

## RankingOrderParam **def _\_init__**()
Creates a new `RankingOrderParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
order_calc: int = 0
group_index: int = 255
group_num: int = 0
time_scope: int = 2
offset: int = 0
count: int = 10

## RankingRankData **def _\_init__**()
Creates a new `RankingRankData` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
unique_id: int
rank: int
category: int
score: int
groups: list[int]
param: int
common_data: bytes
If `nex.version` >= 40000:
update_time: [DateTime](common.md#datetime)


## RankingResult **def _\_init__**()
Creates a new `RankingResult` instance. Required fields must be filled in manually. The following fields are defined in this class:
data: list[[RankingRankData](#rankingrankdata)]
total: int
since_time: [DateTime](common.md#datetime)

## RankingScoreData **def _\_init__**()
Creates a new `RankingScoreData` instance. Required fields must be filled in manually. The following fields are defined in this class:
category: int
score: int
order: int
update_mode: int
groups: list[int]
param: int

## RankingStats **def _\_init__**()
Creates a new `RankingStats` instance. Required fields must be filled in manually. The following fields are defined in this class:
stats: list[float]

================================================ FILE: docs/reference/nex/ranking_mk8d.md ================================================ # Module: nintendo.nex.ranking_mk8d Provides a client and server for the `RankingProtocolMK8D`. This page was generated automatically from `ranking_mk8d.proto`. **class** [RankingClientMK8D](#rankingclientmk8d)
The client for the `RankingProtocolMK8D`. **class** [RankingServerMK8D](#rankingservermk8d)
The server for the `RankingProtocolMK8D`. **class** [RankingMode](#rankingmode)
**class** [RankingOrderCalc](#rankingordercalc)
**class** [RankingStatFlags](#rankingstatflags)
**class** [CommonDataList](#commondatalist)([Structure](common.md))
**class** [CompetitionRankingGetScoreParam](#competitionrankinggetscoreparam)([Structure](common.md))
**class** [CompetitionRankingInfo](#competitionrankinginfo)([Structure](common.md))
**class** [CompetitionRankingInfoGetParam](#competitionrankinginfogetparam)([Structure](common.md))
**class** [CompetitionRankingScoreData](#competitionrankingscoredata)([Structure](common.md))
**class** [CompetitionRankingScoreInfo](#competitionrankingscoreinfo)([Structure](common.md))
**class** [CompetitionRankingUploadScoreParam](#competitionrankinguploadscoreparam)([Structure](common.md))
**class** [RankingCachedResult](#rankingcachedresult)([RankingResult](#rankingresult))
**class** [RankingChangeAttributesParam](#rankingchangeattributesparam)([Structure](common.md))
**class** [RankingOrderParam](#rankingorderparam)([Structure](common.md))
**class** [RankingRankData](#rankingrankdata)([Structure](common.md))
**class** [RankingResult](#rankingresult)([Structure](common.md))
**class** [RankingScoreData](#rankingscoredata)([Structure](common.md))
**class** [RankingStats](#rankingstats)([Structure](common.md))
**class** [ScorePack](#scorepack)([Structure](common.md))
## RankingClientMK8D **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`RankingClientMK8D`](#rankingclientmk8d). **async def upload_score**(score_data: [RankingScoreData](#rankingscoredata), unique_id: int) -> None
Calls method `1` on the server. **async def delete_score**(category: int, unique_id: int) -> None
Calls method `2` on the server. **async def delete_all_scores**(unique_id: int) -> None
Calls method `3` on the server. **async def upload_common_data**(common_data: bytes, unique_id: int) -> None
Calls method `4` on the server. **async def delete_common_data**(unique_id: int) -> None
Calls method `5` on the server. **async def get_common_data**(unique_id: int) -> bytes
Calls method `6` on the server. **async def change_attributes**(category: int, param: [RankingChangeAttributesParam](#rankingchangeattributesparam), unique_id: int) -> None
Calls method `7` on the server. **async def change_all_attributes**(param: [RankingChangeAttributesParam](#rankingchangeattributesparam), unique_id: int) -> None
Calls method `8` on the server. **async def get_ranking**(mode: int, category: int, order: [RankingOrderParam](#rankingorderparam), unique_id: int, pid: int) -> [RankingResult](#rankingresult)
Calls method `9` on the server. **async def get_approx_order**(category: int, order: [RankingOrderParam](#rankingorderparam), score: int, unique_id: int, pid: int) -> int
Calls method `10` on the server. **async def get_stats**(category: int, order: [RankingOrderParam](#rankingorderparam), flags: int) -> [RankingStats](#rankingstats)
Calls method `11` on the server. **async def get_ranking_by_pid_list**(pids: list[int], mode: int, category: int, order: [RankingOrderParam](#rankingorderparam), unique_id: int) -> [RankingResult](#rankingresult)
Calls method `12` on the server. **async def get_ranking_by_unique_id_list**(ids: list[int], mode: int, category: int, order: [RankingOrderParam](#rankingorderparam), unique_id: int) -> [RankingResult](#rankingresult)
Calls method `13` on the server. **async def get_cached_topx_ranking**(category: int, order: [RankingOrderParam](#rankingorderparam)) -> [RankingCachedResult](#rankingcachedresult)
Calls method `14` on the server. **async def get_cached_topx_rankings**(categories: list[int], order: list[[RankingOrderParam](#rankingorderparam)]) -> list[[RankingCachedResult](#rankingcachedresult)]
Calls method `15` on the server. **async def get_competition_ranking_score**(param: [CompetitionRankingGetScoreParam](#competitionrankinggetscoreparam)) -> list[[CompetitionRankingScoreInfo](#competitionrankingscoreinfo)]
Calls method `16` on the server. **async def upload_competition_ranking_score**(param: [CompetitionRankingUploadScoreParam](#competitionrankinguploadscoreparam)) -> bool
Calls method `17` on the server. **async def get_competition_info**(param: [CompetitionRankingInfoGetParam](#competitionrankinginfogetparam)) -> list[[CompetitionRankingInfo](#competitionrankinginfo)]
Calls method `18` on the server. **async def upload_score_pack**(score_data: [RankingScoreData](#rankingscoredata), metadata: bytes) -> None
Calls method `19` on the server. **async def get_score_pack**(pids: list[int], category: int) -> [ScorePack](#scorepack)
Calls method `20` on the server. **async def get_commmon_data_by_pid_list**(pids: list[int]) -> [CommonDataList](#commondatalist)
Calls method `22` on the server. ## RankingServerMK8D **def _\_init__**()
Creates a new [`RankingServerMK8D`](#rankingservermk8d). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def upload_score**(client: [RMCClient](rmc.md#rmcclient), score_data: [RankingScoreData](#rankingscoredata), unique_id: int) -> None
Handler for method `1`. This method should be overridden by a subclass. **async def delete_score**(client: [RMCClient](rmc.md#rmcclient), category: int, unique_id: int) -> None
Handler for method `2`. This method should be overridden by a subclass. **async def delete_all_scores**(client: [RMCClient](rmc.md#rmcclient), unique_id: int) -> None
Handler for method `3`. This method should be overridden by a subclass. **async def upload_common_data**(client: [RMCClient](rmc.md#rmcclient), common_data: bytes, unique_id: int) -> None
Handler for method `4`. This method should be overridden by a subclass. **async def delete_common_data**(client: [RMCClient](rmc.md#rmcclient), unique_id: int) -> None
Handler for method `5`. This method should be overridden by a subclass. **async def get_common_data**(client: [RMCClient](rmc.md#rmcclient), unique_id: int) -> bytes
Handler for method `6`. This method should be overridden by a subclass. **async def change_attributes**(client: [RMCClient](rmc.md#rmcclient), category: int, param: [RankingChangeAttributesParam](#rankingchangeattributesparam), unique_id: int) -> None
Handler for method `7`. This method should be overridden by a subclass. **async def change_all_attributes**(client: [RMCClient](rmc.md#rmcclient), param: [RankingChangeAttributesParam](#rankingchangeattributesparam), unique_id: int) -> None
Handler for method `8`. This method should be overridden by a subclass. **async def get_ranking**(client: [RMCClient](rmc.md#rmcclient), mode: int, category: int, order: [RankingOrderParam](#rankingorderparam), unique_id: int, pid: int) -> [RankingResult](#rankingresult)
Handler for method `9`. This method should be overridden by a subclass. **async def get_approx_order**(client: [RMCClient](rmc.md#rmcclient), category: int, order: [RankingOrderParam](#rankingorderparam), score: int, unique_id: int, pid: int) -> int
Handler for method `10`. This method should be overridden by a subclass. **async def get_stats**(client: [RMCClient](rmc.md#rmcclient), category: int, order: [RankingOrderParam](#rankingorderparam), flags: int) -> [RankingStats](#rankingstats)
Handler for method `11`. This method should be overridden by a subclass. **async def get_ranking_by_pid_list**(client: [RMCClient](rmc.md#rmcclient), pids: list[int], mode: int, category: int, order: [RankingOrderParam](#rankingorderparam), unique_id: int) -> [RankingResult](#rankingresult)
Handler for method `12`. This method should be overridden by a subclass. **async def get_ranking_by_unique_id_list**(client: [RMCClient](rmc.md#rmcclient), ids: list[int], mode: int, category: int, order: [RankingOrderParam](#rankingorderparam), unique_id: int) -> [RankingResult](#rankingresult)
Handler for method `13`. This method should be overridden by a subclass. **async def get_cached_topx_ranking**(client: [RMCClient](rmc.md#rmcclient), category: int, order: [RankingOrderParam](#rankingorderparam)) -> [RankingCachedResult](#rankingcachedresult)
Handler for method `14`. This method should be overridden by a subclass. **async def get_cached_topx_rankings**(client: [RMCClient](rmc.md#rmcclient), categories: list[int], order: list[[RankingOrderParam](#rankingorderparam)]) -> list[[RankingCachedResult](#rankingcachedresult)]
Handler for method `15`. This method should be overridden by a subclass. **async def get_competition_ranking_score**(client: [RMCClient](rmc.md#rmcclient), param: [CompetitionRankingGetScoreParam](#competitionrankinggetscoreparam)) -> list[[CompetitionRankingScoreInfo](#competitionrankingscoreinfo)]
Handler for method `16`. This method should be overridden by a subclass. **async def upload_competition_ranking_score**(client: [RMCClient](rmc.md#rmcclient), param: [CompetitionRankingUploadScoreParam](#competitionrankinguploadscoreparam)) -> bool
Handler for method `17`. This method should be overridden by a subclass. **async def get_competition_info**(client: [RMCClient](rmc.md#rmcclient), param: [CompetitionRankingInfoGetParam](#competitionrankinginfogetparam)) -> list[[CompetitionRankingInfo](#competitionrankinginfo)]
Handler for method `18`. This method should be overridden by a subclass. **async def upload_score_pack**(client: [RMCClient](rmc.md#rmcclient), score_data: [RankingScoreData](#rankingscoredata), metadata: bytes) -> None
Handler for method `19`. This method should be overridden by a subclass. **async def get_score_pack**(client: [RMCClient](rmc.md#rmcclient), pids: list[int], category: int) -> [ScorePack](#scorepack)
Handler for method `20`. This method should be overridden by a subclass. **async def get_commmon_data_by_pid_list**(client: [RMCClient](rmc.md#rmcclient), pids: list[int]) -> [CommonDataList](#commondatalist)
Handler for method `22`. This method should be overridden by a subclass. ## RankingMode This class defines the following constants:
`GLOBAL = 0`
`GLOBAL_AROUND_SELF = 1`
`SELF = 4`
## RankingOrderCalc This class defines the following constants:
`STANDARD = 0`
`ORDINAL = 1`
## RankingStatFlags This class defines the following constants:
`RANKING_COUNT = 1`
`TOTAL_SCORE = 2`
`LOWEST_SCORE = 4`
`HIGHEST_SCORE = 8`
`AVERAGE_SCORE = 16`
`ALL = 31`
## CommonDataList **def _\_init__**()
Creates a new `CommonDataList` instance. Required fields must be filled in manually. The following fields are defined in this class:
data: list[bytes]

## CompetitionRankingGetScoreParam **def _\_init__**()
Creates a new `CompetitionRankingGetScoreParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
id: int
range: [ResultRange](common.md#resultrange) = [ResultRange](common.md#resultrange)()

## CompetitionRankingInfo **def _\_init__**()
Creates a new `CompetitionRankingInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
id: int
num_participants: int
team_scores: list[int]

## CompetitionRankingInfoGetParam **def _\_init__**()
Creates a new `CompetitionRankingInfoGetParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
rank_order: int
range: [ResultRange](common.md#resultrange) = [ResultRange](common.md#resultrange)()

## CompetitionRankingScoreData **def _\_init__**()
Creates a new `CompetitionRankingScoreData` instance. Required fields must be filled in manually. The following fields are defined in this class:
rank: int
pid: int
score: int
last_update: [DateTime](common.md#datetime)
team_id: int = 255
metadata: bytes

## CompetitionRankingScoreInfo **def _\_init__**()
Creates a new `CompetitionRankingScoreInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
season_id: int
scores: list[[CompetitionRankingScoreData](#competitionrankingscoredata)]
num_participants: int
team_scores: list[int]

## CompetitionRankingUploadScoreParam **def _\_init__**()
Creates a new `CompetitionRankingUploadScoreParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
id: int
season_id: int
unk3: int
score: int
team_id: int
team_score: int
is_first_upload: bool
metadata: bytes

## RankingCachedResult **def _\_init__**()
Creates a new `RankingCachedResult` instance. Required fields must be filled in manually. The following fields are defined in this class:
created_time: [DateTime](common.md#datetime)
expired_time: [DateTime](common.md#datetime)
max_length: int

## RankingChangeAttributesParam **def _\_init__**()
Creates a new `RankingChangeAttributesParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
flags: int
groups: list[int]
param: int

## RankingOrderParam **def _\_init__**()
Creates a new `RankingOrderParam` instance. Required fields must be filled in manually. The following fields are defined in this class:
order_calc: int = 0
group_index: int = 255
group_num: int = 0
time_scope: int = 2
offset: int = 0
count: int = 10

## RankingRankData **def _\_init__**()
Creates a new `RankingRankData` instance. Required fields must be filled in manually. The following fields are defined in this class:
pid: int
unique_id: int
rank: int
category: int
score: int
groups: list[int]
param: int
common_data: bytes
If `nex.version` >= 40000:
update_time: [DateTime](common.md#datetime)


## RankingResult **def _\_init__**()
Creates a new `RankingResult` instance. Required fields must be filled in manually. The following fields are defined in this class:
data: list[[RankingRankData](#rankingrankdata)]
total: int
since_time: [DateTime](common.md#datetime)

## RankingScoreData **def _\_init__**()
Creates a new `RankingScoreData` instance. Required fields must be filled in manually. The following fields are defined in this class:
category: int
score: int
order: int
update_mode: int
groups: list[int]
param: int

## RankingStats **def _\_init__**()
Creates a new `RankingStats` instance. Required fields must be filled in manually. The following fields are defined in this class:
stats: list[float]

## ScorePack **def _\_init__**()
Creates a new `ScorePack` instance. Required fields must be filled in manually. The following fields are defined in this class:
data: list[bytes]

================================================ FILE: docs/reference/nex/remotelog.md ================================================ # Module: nintendo.nex.remotelog Provides a client and server for the `RemoteLogDeviceProtocol`. This page was generated automatically from `remotelog.proto`. **class** [RemoteLogDeviceClient](#remotelogdeviceclient)
The client for the `RemoteLogDeviceProtocol`. **class** [RemoteLogDeviceServer](#remotelogdeviceserver)
The server for the `RemoteLogDeviceProtocol`. ## RemoteLogDeviceClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`RemoteLogDeviceClient`](#remotelogdeviceclient). **async def log**(message: str) -> None
Calls method `1` on the server. ## RemoteLogDeviceServer **def _\_init__**()
Creates a new [`RemoteLogDeviceServer`](#remotelogdeviceserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def log**(client: [RMCClient](rmc.md#rmcclient), message: str) -> None
Handler for method `1`. This method should be overridden by a subclass. ================================================ FILE: docs/reference/nex/rmc.md ================================================ # Module: nintendo.nex.rmc Provides a client and server for the RMC protocol. An alternative client that calls remote methods through HTTP can be found in the [`nintendo.nex.hpp`](hpp.md) module. **class** RMCResponse
Generic response object that is returned when a remote method returns multiple values. The attributes depend on the method. **class** [RMCClient](#rmcclient)
RMC client that uses a PRUDP connection. **async with connect**(settings: [Settings](settings.md#settings), host: str, port: int, vport: int = 1, context: [TLSContext](https://anynet.readthedocs.io/en/latest/reference/tls/#tlscontext) = None, credentials: [Credentials](kerberos.md#credentials) = None, servers: list[object] = []) -> [RMCClient](#rmcclient)
Creates an RMC client based on PRUDP and connects it to the given address. If `context` is provided, and the underlying transport supports this, the connections is secured with TLS. If credentials are provided they are sent to the server in the connection request. Blocks until the connection is ready and handshake has been performed. `servers` must be a list of service implementations. **async with serve**(settings: [Settings](settings.md#settings), servers: list[object], host: str = "", port: int = 0, vport: int = 1, context: [TLSContext](https://anynet.readthedocs.io/en/latest/reference/tls/#tlscontext) = None, key: bytes = None) -> None
Creates an RMC server based on PRUDP and binds it to the given address. If `host` is empty, the local address of the default interface is used. If `port` is 0, it is chosen by the operating system. If `context` is provided, and the underlying transport supports this, the server is secured with TLS. If `key` is provided it is used to decrypt the Kerberos tickets in connection requests. If `key` is `None`, the payload of connection requests is ignored and all client connections are accepted. `servers` must be a list of service implementations. **async with serve_on_transport**(settings: [Settings](settings.md#settings), servers: list[object], transport: [PRUDPServerTransport](prudp.md#prudpservertransport), port: int, key: bytes = None) -> None
Creates an RMC server on top of the given transport server. If `key` is provided it is used to decrypt the Kerberos tickets in connection requests. If `key` is `None`, the payload of connection requests is ignored and all client connections are accepted. `servers` must be a list of service implementations. ## RMCClient **async def request**(protocol: int, method: int, body: bytes, noresponse: bool = False) -> bytes
Performs a remote method call. Blocks until the RMC is complete. Returns the body of the RMC response on success. Raises [`RMCError`](common.md#rmcerror) if the server returns an error code.

If `noresponse` is `True`, this method does not wait for a response and returns `None` immediately.
**async def close**() -> None
Closes the connection forcefully by sending an unreliable disconnect packet three times. **async def disconnect**() -> None
Closes the connection gracefully by sending a reliable disconnect packet. **def pid**() -> int
Returns the user id of the connected client. Returns `None` if the client is connected without credentials. **def local_address**() -> tuple[str, int]
Returns the local address of the client. **def remote_address**() -> tuple[str, int]
Returns the address that the client is connected to. **def local_sid**() -> int
Returns the local stream id (PRUDP port). **def remote_sid**() -> int
Returns the remote stream id (PRUDP port). ================================================ FILE: docs/reference/nex/screening.md ================================================ # Module: nintendo.nex.screening Provides a client and server for the `ScreeningProtocol`. This page was generated automatically from `screening.proto`. **class** [ScreeningClient](#screeningclient)
The client for the `ScreeningProtocol`. **class** [ScreeningServer](#screeningserver)
The server for the `ScreeningProtocol`. ## ScreeningClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`ScreeningClient`](#screeningclient). ## ScreeningServer **def _\_init__**()
Creates a new [`ScreeningServer`](#screeningserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. ================================================ FILE: docs/reference/nex/secure.md ================================================ # Module: nintendo.nex.secure Provides a client and server for the `SecureConnectionProtocol`. This page was generated automatically from `secure.proto`. **class** [SecureConnectionClient](#secureconnectionclient)
The client for the `SecureConnectionProtocol`. **class** [SecureConnectionServer](#secureconnectionserver)
The server for the `SecureConnectionProtocol`. **class** [ConnectionData](#connectiondata)([Structure](common.md))
**class** [NintendoLoginData](#nintendologindata)([Structure](common.md))
## SecureConnectionClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`SecureConnectionClient`](#secureconnectionclient). **async def register**(urls: list[[StationURL](common.md#stationurl)]) -> [RMCResponse](common.md)
Calls method `1` on the server. The RMC response has the following attributes:
result: [Result](common.md#result)
connection_id: int
public_station: [StationURL](common.md#stationurl)
**async def request_connection_data**(cid: int, pid: int) -> [RMCResponse](common.md)
Calls method `2` on the server. The RMC response has the following attributes:
result: bool
connection_data: list[[ConnectionData](#connectiondata)]
**async def request_urls**(cid: int, pid: int) -> [RMCResponse](common.md)
Calls method `3` on the server. The RMC response has the following attributes:
result: bool
urls: list[[StationURL](common.md#stationurl)]
**async def register_ex**(urls: list[[StationURL](common.md#stationurl)], login_data: [Data](common.md)) -> [RMCResponse](common.md)
Calls method `4` on the server. The RMC response has the following attributes:
result: [Result](common.md#result)
connection_id: int
public_station: [StationURL](common.md#stationurl)
**async def test_connectivity**() -> None
Calls method `5` on the server. **async def update_urls**(urls: list[[StationURL](common.md#stationurl)]) -> None
Calls method `6` on the server. **async def replace_url**(url: [StationURL](common.md#stationurl), new: [StationURL](common.md#stationurl)) -> None
Calls method `7` on the server. **async def send_report**(report_id: int, data: bytes) -> None
Calls method `8` on the server. ## SecureConnectionServer **def _\_init__**()
Creates a new [`SecureConnectionServer`](#secureconnectionserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def register**(client: [RMCClient](rmc.md#rmcclient), urls: list[[StationURL](common.md#stationurl)]) -> [RMCResponse](common.md)
Handler for method `1`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: [Result](common.md#result)
connection_id: int
public_station: [StationURL](common.md#stationurl)
**async def request_connection_data**(client: [RMCClient](rmc.md#rmcclient), cid: int, pid: int) -> [RMCResponse](common.md)
Handler for method `2`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
connection_data: list[[ConnectionData](#connectiondata)]
**async def request_urls**(client: [RMCClient](rmc.md#rmcclient), cid: int, pid: int) -> [RMCResponse](common.md)
Handler for method `3`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: bool
urls: list[[StationURL](common.md#stationurl)]
**async def register_ex**(client: [RMCClient](rmc.md#rmcclient), urls: list[[StationURL](common.md#stationurl)], login_data: [Data](common.md)) -> [RMCResponse](common.md)
Handler for method `4`. This method should be overridden by a subclass. The RMC response must have the following attributes:
result: [Result](common.md#result)
connection_id: int
public_station: [StationURL](common.md#stationurl)
**async def test_connectivity**(client: [RMCClient](rmc.md#rmcclient)) -> None
Handler for method `5`. This method should be overridden by a subclass. **async def update_urls**(client: [RMCClient](rmc.md#rmcclient), urls: list[[StationURL](common.md#stationurl)]) -> None
Handler for method `6`. This method should be overridden by a subclass. **async def replace_url**(client: [RMCClient](rmc.md#rmcclient), url: [StationURL](common.md#stationurl), new: [StationURL](common.md#stationurl)) -> None
Handler for method `7`. This method should be overridden by a subclass. **async def send_report**(client: [RMCClient](rmc.md#rmcclient), report_id: int, data: bytes) -> None
Handler for method `8`. This method should be overridden by a subclass. ## ConnectionData **def _\_init__**()
Creates a new `ConnectionData` instance. Required fields must be filled in manually. The following fields are defined in this class:
station: [StationURL](common.md#stationurl)
connection_id: int

## NintendoLoginData **def _\_init__**()
Creates a new `NintendoLoginData` instance. Required fields must be filled in manually. The following fields are defined in this class:
token: str

================================================ FILE: docs/reference/nex/settings.md ================================================ # Module: nintendo.nex.settings Defines settings for `nex` classes. **class** [Settings](#settings)
Holds the settings. **def default**() -> [Settings](#settings)
Creates a settings object with default settings. **def load**(name: str) -> [Settings](#settings)
Loads the settings from the given configuration file. The following files are provided:
`- 3ds`: provides reasonable defaults for 3DS applications.
`- default`: provides reasonable defaults for Wii U applications.
`- friends`: provides reasonable defaults for the 3DS / Wii U friend server.
`- switch`: provides reasonable defaults for Switch applications.
## Settings TRANSPORT_UDP (0)
TRANSPORT_TCP (1)
TRANSPORT_WEBSOCKET (2) COMPRESSION_NONE (0)
COMPRESSION_ZLIB (1)
ENCRYPTION_NONE (0)
ENCRYPTION_RC4 (1)
**def _\_getitem__**(name: str) -> object
Returns the value of a specific setting. **def _\_setitem__**(name: str, value: object) -> None
Changes the value of a specific setting. The value is automatically converted to the appropriate type. **def configure**(access_key: str, nex_version: int, client_version: int = None) -> None
Configures the `prudp.access_key`, `nex.version` and `nex.client_version` settings. **def reset**() -> None
Resets all fields back to their defaults. **def copy**() -> [Settings](#settings)
Returns a copy of the settings object. **def load**(name: str) -> None
Loads the settings from the given configuration file and applies them on top of the current settings. Only the settings that are defined in the file are replaced. ## Fields The following fields are currently defined: nex.version: int = 0
The version of the `nex` library.
nex.client_version: int = 0
The client version sent to the server in `ValidateAndRequestTicketWithParam`.
nex.struct_header: int = 0
Enables structure headers.
nex.pid_size: int = 4
The size of a user id in bytes (`4` or `8`).
prudp.access_key: str = ""
The access key of the game server. prudp.version: int = 2
The major version of the `prudp` protocol with UDP transport:
`- 0`: both client and server use only `prudp v0`
`- 1`: both client and server use only `prudp v1`
`- 2`: client uses only `prudp v1`, server supports both `v0` and `v1`.

If the transport is different from UDP, the `lite` encoding is always used.

prudp.minor_version: int = 4
The minor version of the `prudp` protocol. This is only relevant for `prudp v1` and `lite`. prudp.transport: int = TRANSPORT_UDP
The underlying transport protocol for `prudp`.
prudp.compression: int = COMPRESSION_NONE
The compression algorithm used for data packets.
prudp.encryption: int = ENCRYPTION_RC4
The encryption algorithm used for data packets. prudp.resend_timeout: float = 1
Time after which a packet is resent if no acknowledgement is received (in seconds).
prudp.resend_limit: int = 2
Number of retransmissions after which the connection is considered dead.
prudp.ping_timeout: float = 5
Time after which a ping packet is sent to keep the connection alive (in seconds). prudp.fragment_size: int = 1300
The maximum size of a packet payload before it is split up into fragments.
prudp.max_substream_id: int = 0
The maximum substream id in `prudp v1`.
prudp_v0.signature_version: int = 0
The version of the packet signature in the `prudp v0` protocol.
prudp_v0.flags_version: int = 1
The version of the `flags` field in the `prudp v0` protocol.
prudp_v0.checksum_version: int = 1
The version of the checksum algorithm in the `prudp v0` protocol.
kerberos.key_size: int = 32
The size of the session key in bytes.
kerberos.key_derivation: int = 0
The version of the key derivation algorithm for kerberos tickets.
kerberos.ticket_version: int = 1
The version of the internal data in kerberos tickets. ================================================ FILE: docs/reference/nex/streams.md ================================================ # Module: nintendo.nex.streams Extends [generic memory streams](https://anynet.readthedocs.io/en/latest/reference/streams) with useful `nex` related methods. **class** StreamOut([anynet.StreamOut](https://anynet.readthedocs.io/en/latest/reference/streams/#streamout))
An output stream that supports various `nex` structures. **class** StreamIn([anynet.StreamIn](https://anynet.readthedocs.io/en/latest/reference/streams/#streamin))
An input stream that supports various `nex` structures. ## StreamOut **def _\_init__**(settings: [Settings](settings.md#settings))
Creates a new output stream. **def pid**(value: int) -> None
Writes a user id into the stream. **def result**(value: [Result](common.md#result)) -> None
Writes a result into the stream. **def list**(value: list, func: Callable) -> None
Writes a list into the stream. For example: `stream.list([1, 2, 3], stream.u8)`. **def map**(value: dict, keyfunc: Callable, valuefunc: Callable) -> None
Writes a map into the stream. For example: `stream.map({"a": 1, "b": 2}, stream.string, stream.u8)`. **def string**(value: str) -> None
Writes an UTF-8 string into the stream. Automatically adds a null terminator. **def stationurl**(value: [StationURL](common.md#stationurl)) -> None
Writes a [StationURL](common.md#stationurl) into the stream. **def datetime**(value: [DateTime](common.md#datetime)) -> None
Writes a [DateTime](common.md#datetime) object into the stream. **def buffer**(value: bytes) -> None
Writes a buffer into the stream with a 32-bit length field. **def qbuffer**(value: bytes) -> None
Writes a buffer into the stream with a 16-bit length field. **def add**(value: [Structure](common.md)) -> None
Writes a `nex` structure into the stream. **def anydata**(value: object) -> None
Wraps a structure in a data holder and writes it into the stream. **def variant**(value: object) -> None
Writes a variant into the stream. `value` must be either `None` or an instance of `int`, `float`, `bool`, `str` or [`DateTime`](common.md#datetime). ## StreamIn **def _\_init__**(data: bytes, settings: [Settings](settings.md#settings))
Creates a new input stream. **def pid**() -> int
Reads a user id from the stream. **def result**() -> [Result](common.md#result)
Reads a result from the stream. **def repeat**(func: Callable, num: int) -> list
Extracts a fixed number of copies of a given type from the stream. For convenience, `func` may also be a subclass of [`Structure`](common.md) instead of a function. For example: `stream.repeat(stream.u8, 5)` or `stream.repeat(ResultRange, 2)`. **def list**(func: Callable) -> list
Reads a list from the stream. For convenience, `func` may also be a subclass of [`Structure`](common.md) instead of a function. For example: `stream.list(stream.u8)` or `stream.list(ResultRange)`. **def map**(keyfunc: Callable, valuefunc: Callable) -> dict
Reads a map from the stream. For convenience, `keyfunc` and `valuefunc` may also be a subclass of [`Structure`](common.md) instead of a function. For example: `stream.map(stream.string, ResultRange)`. **def string**() -> str
Reads a UTF-8 string from the stream. Automatically removes the null terminator. **def stationurl**() -> [StationURL](common.md#stationurl)
Reads a station url from the stream. **def datetime**() -> [DateTime](common.md#datetime)
Reads a [DateTime](common.md#datetime) object from the stream. **def buffer**() -> bytes
Reads a buffer from the stream with a 32-bit length field. **def qbuffer**() -> bytes
Reads a buffer from the stream with a 16-bit length field. **def substream**() -> [StreamIn](#streamin)
Reads a buffer from the stream with a 32-bit length field and returns an input stream. **def extract**(cls: Type[[Structure](common.md)]) -> [Structure](common.md)
Reads a `nex` structure from the stream. **def anydata**() -> object
Reads a data holder from the stream and returns its content, which is usually a subclass of [`Data`](common.md). **def variant**() -> object
Reads a variant from the stream. ================================================ FILE: docs/reference/nex/subscriber.md ================================================ # Module: nintendo.nex.subscriber Provides a client and server for the `SubscriberProtocol`. This page was generated automatically from `subscriber.proto`. **class** [SubscriberClient](#subscriberclient)
The client for the `SubscriberProtocol`. **class** [SubscriberServer](#subscriberserver)
The server for the `SubscriberProtocol`. ## SubscriberClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`SubscriberClient`](#subscriberclient). ## SubscriberServer **def _\_init__**()
Creates a new [`SubscriberServer`](#subscriberserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. ================================================ FILE: docs/reference/nex/utility.md ================================================ # Module: nintendo.nex.utility Provides a client and server for the `UtilityProtocol`. This page was generated automatically from `utility.proto`. **class** [UtilityClient](#utilityclient)
The client for the `UtilityProtocol`. **class** [UtilityServer](#utilityserver)
The server for the `UtilityProtocol`. **class** [UniqueIdInfo](#uniqueidinfo)([Structure](common.md))
## UtilityClient **def _\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
Creates a new [`UtilityClient`](#utilityclient). **async def acquire_nex_unique_id**() -> int
Calls method `1` on the server. **async def acquire_nex_unique_id_with_password**() -> [UniqueIdInfo](#uniqueidinfo)
Calls method `2` on the server. **async def associate_nex_unique_id_with_my_principal_id**(info: [UniqueIdInfo](#uniqueidinfo)) -> None
Calls method `3` on the server. **async def associate_nex_unique_ids_with_my_principal_id**(infos: list[[UniqueIdInfo](#uniqueidinfo)]) -> None
Calls method `4` on the server. **async def get_associated_nex_unique_id_with_my_principal_id**() -> [UniqueIdInfo](#uniqueidinfo)
Calls method `5` on the server. **async def get_associated_nex_unique_ids_with_my_principal_id**() -> list[[UniqueIdInfo](#uniqueidinfo)]
Calls method `6` on the server. **async def get_integer_settings**(index: int) -> dict[int, int]
Calls method `7` on the server. **async def get_string_settings**(index: int) -> dict[int, str]
Calls method `8` on the server. ## UtilityServer **def _\_init__**()
Creates a new [`UtilityServer`](#utilityserver). **async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
Called whenever a client is disconnected. May be overridden by a subclass. **async def acquire_nex_unique_id**(client: [RMCClient](rmc.md#rmcclient)) -> int
Handler for method `1`. This method should be overridden by a subclass. **async def acquire_nex_unique_id_with_password**(client: [RMCClient](rmc.md#rmcclient)) -> [UniqueIdInfo](#uniqueidinfo)
Handler for method `2`. This method should be overridden by a subclass. **async def associate_nex_unique_id_with_my_principal_id**(client: [RMCClient](rmc.md#rmcclient), info: [UniqueIdInfo](#uniqueidinfo)) -> None
Handler for method `3`. This method should be overridden by a subclass. **async def associate_nex_unique_ids_with_my_principal_id**(client: [RMCClient](rmc.md#rmcclient), infos: list[[UniqueIdInfo](#uniqueidinfo)]) -> None
Handler for method `4`. This method should be overridden by a subclass. **async def get_associated_nex_unique_id_with_my_principal_id**(client: [RMCClient](rmc.md#rmcclient)) -> [UniqueIdInfo](#uniqueidinfo)
Handler for method `5`. This method should be overridden by a subclass. **async def get_associated_nex_unique_ids_with_my_principal_id**(client: [RMCClient](rmc.md#rmcclient)) -> list[[UniqueIdInfo](#uniqueidinfo)]
Handler for method `6`. This method should be overridden by a subclass. **async def get_integer_settings**(client: [RMCClient](rmc.md#rmcclient), index: int) -> dict[int, int]
Handler for method `7`. This method should be overridden by a subclass. **async def get_string_settings**(client: [RMCClient](rmc.md#rmcclient), index: int) -> dict[int, str]
Handler for method `8`. This method should be overridden by a subclass. ## UniqueIdInfo **def _\_init__**()
Creates a new `UniqueIdInfo` instance. Required fields must be filled in manually. The following fields are defined in this class:
unique_id: int = 0
password: int = 0

================================================ FILE: docs/reference/nnas.md ================================================ # Module: nintendo.nnas Provides a client for the 3DS/Wii U [account server](https://github.com/kinnay/nintendo/wiki/Account-Server). **class** NNASError(Exception)
Raised when the server returns an error code. **class** [NNASClient](#nnasclient)
The account server client. **def calc_password_hash**(pid: int, password: str) -> str Calculates the password hash for hash-based authentication and returns the hexdigest. ## NNASClient **def _\_init__**()
Creates a new account server client. **def set_context**(context: [TLSContext](https://anynet.readthedocs.io/en/latest/reference/tls/#tlscontext)) -> None
Changes the TLS context. By default, the server certificate is verified with `Nintendo CA - G3`, and `Wii U Common Prod 1` is used as the client certificate. **def set_url**(url: str) -> None
Changes the server to which requests are sent. The default is `account.nintendo.net`. **def set_client_id**(client_id: str) -> None
Changes the content of the `X-Nintendo-Client-ID` header. The default is `"a2efa818a34fa16b8afbc8a74eba3eda"`. **def set_client_secret**(client_secret: str) -> None
Changes the content of the `X-Nintendo-Client-Secret` header. The default is `"c91cdb5658bd4954ade78533a339cf9a"`. **def set_platform_id**(platform_id: int) -> None
Changes the content of the `X-Nintendo-Platform-ID` header. The default is `1` (Wii U). **def set_device_type**(device_type: int) -> None
Changes the content of the `X-Nintendo-Device-Type` header. The default is `2` (retail). **def set_fpd_version**(version: int) -> None
Changes the content of the `X-Nintendo-FPD-Version` header. The default is `0`. **def set_environment**(environment: str) -> None
Changes the content of the `X-Nintendo-Environment` header. The default is `"L1"` (production). **def set_device**(device_id: int, serial_number: str, system_version: int, cert: str = None) -> None
Changes the `X-Nintendo-Device-ID`, `X-Nintendo-Serial-Number`, `X-Nintendo-System-Version` and `X-Nintendo-Device-Cert` headers. By default, the system version is set to `0x260` and the other headers are omitted. **def set_locale**(region: int, country: str, language: str) -> None
Changes the `X-Nintendo-Region`, `X-Nintendo-Country` and `Accept-Language` headers. By default, the region is `4` (Europe), the country is `"NL"` (Netherlands) and the language is `"en"` (English). **def set_title**(title_id: int, title_version: int) -> None
Changes the `X-Nintendo-Title-ID` and `X-Nintendo-Application-Version` headers. The `X-Nintendo-Unique-ID` header is also derived from the title id. By default, these headers are omitted. **async def login**(username: str, password: str, password_type: str = None) -> [OAuth20](#oauth20)
Logs in on the account server. This method must be called prior to any method that accesses your account data. **async def get_nex_token**(access_token: str, game_server_id: int) -> [NexToken](#nextoken)
Requests a `nex` token for the given game server. **async def get_service_token**(access_token: str, client_id: str) -> str
Requests an independent service token for the given client id. **async def get_profile**(access_token: str) -> [Profile](#profile)
Requests your profile. **async def get_miis**(pids: list[int]) -> list[[Mii](#mii)]
Requests the miis for the given user ids. **async def get_pids**(nnids: list[str]) -> dict[str, int]
Requests the user ids for the given Nintendo Network IDs. **async def get_nnids**(pids: list[int]) -> dict[int, str]
Requests the Nintendo Network IDs for the given user ids. **async def get_pid**(nnid: str) -> int
Requests the user id for the given Nintendo Network ID. **async def get_nnid**(pid: int) -> str
Requests the Nintendo Network ID for the given user id. ## Account `domain: str`
`type: str`
`username: str` ## DeviceAttribute `created_date: datetime.datetime`
`name: str`
`value: str`
## Email `id: int`
`address: str`
`primary: bool`
`parent: bool`
`reachable: bool`
`type: str`
`validated: bool`
`validated_date: datetime.datetime`
## Mii `data: bytes`
`id: int`
`name: str`
`images: list[MiiImage]`
`primary: bool`
`pid: int`
`nnid: str` ## MiiImage `id: int`
`type: str`
`url: str`
`cached_url: str`
## NexToken `host: str`
`port: int`
`pid: int`
`password: str`
`token: str` ## OAuth20 `token: str`
`refresh_token: str`
`expires_in: int` ## Profile accounts: list[[Account](#account)]
`active_flag: bool`
`birth_date: datetime.datetime`
`country: str`
`create_date: datetime.datetime`
device_attributes: list[[DeviceAttribute](#deviceattribute)]
`forgot_pw_email_sent: datetime.datetime`
`gender: str`
`language: str`
`updated: datetime.datetime`
`marketing_flag: bool`
`off_device_flag: bool`
`pid: int`
email: [Email](#email)
mii: [ProfileMii](#profilemii)
`region: int`
`temporary_password_expiration: datetime.datetime`
`tz_name: str`
`nnid: str`
`utc_offset: int`
## ProfileMii `id: int`
`name: str`
`data: bytes`
`primary: bool`
`status: str`
`hash: str`
images: list[[MiiImage](#miiimage)]
================================================ FILE: docs/reference/switch/aauth.md ================================================ # Module: nintendo.switch.aauth Provides a client for the [application authentication server](https://github.com/kinnay/nintendo/wiki/AAuth-Server). **class** [AAuthError](#aautherror)(Exception)
Raised when the `aauth` server returns an error code. **class** [AAuthClient](#aauthclient)
The `aauth` client. ## AAuthError This exception is raised when the `aauth` server returns an error code. The following constants are defined in this class: `DEVICE_TOKEN_EXPIRED: int = 103`
`ROMID_BANNED: int = 105`
`UNAUTHORIZED_APPLICATION: int = 106`
`SERVICE_CLOSED: int = 109`
`APPLICATION_UPDATE_REQUIRED: int = 111`
`INTERNAL_SERVER_ERROR: int = 112`
`GENERIC: int = 118`
`REGION_MISMATCH: int = 121` The error can be inspected using the following attributes: response: [HTTPResponse](https://anynet.readthedocs.io/en/latest/reference/http/#httpresponse)
`code: int`
`message: str` ## AAuthClient **def _\_init__**()
Creates a new `aauth` client. **def set_request_callback**(callback: Callable) -> None
By default, requests are performed with [`http.request`](https://anynet.readthedocs.io/en/latest/reference/http). This method lets you provide a custom callback instead. **def set_context**(context: [TLSContext](https://anynet.readthedocs.io/en/latest/reference/tls/#tlscontext)) -> None
Changes the TLS context. By default, the server certificate is verified with `Nintendo CA - G3` or `Nintendo Root CA - G4`, depending on the specified system version. **def set_certificate**(cert: [TLSCertificate](https://anynet.readthedocs.io/en/latest/reference/tls/#tlscertificate), key: [TLSPrivateKey](https://anynet.readthedocs.io/en/latest/reference/tls/#tlsprivatekey)) -> None Changes the client certificate of the current TLS context. When `aauth.hac.lp1.ndas.srv.nintendo.net` is used, which is the case on system version 20.0.0 and later, the server rejects all requests without a valid client certificate. **def set_host**(url: str) -> None
Changes the server to which the HTTP requests are sent. The default is `aauth-lp1.ndas.srv.nintendo.net` or `aauth.hac.lp1.ndas.srv.nintendo.net`, depending on the specified system version. **def set_power_state**(state: str) -> None
Changes the content of the `X-Nintendo-PowerState` header. The default is `"FA"`. **def set_system_version**(version: int) -> None
Changes the system version that is emulated by the client. The system version should be given as a decimal integer. For example, `1002` indicates system version `10.0.2`. All system versions from `9.0.0` up to `22.1.0` are supported. **async def get_time**() -> tuple[int, str]
Requests the current server time with `/v1/time`. Returns a tuple that contains the current server time and your public IP address. **async def challenge**(device_token: str) -> dict
Requests a challenge from the `aauth` server. The device token can be obtained from the [`dauth server`](dauth.md). The challenge is used for gamecard authentication. **async def auth_system**(title_id: int, title_version: int, device_token: str) -> dict
Requests an application token from the `aauth` server for a system title. The device token can be obtained from the [`dauth server`](dauth.md). **async def auth_digital**(title_id: int, title_version: int, device_token: str, cert: bytes | str) -> dict
Requests an application token from the `aauth` server for a digital title. The device token can be obtained from the [`dauth server`](dauth.md). Prior to system version `15.0.0`, the `cert` parameter must contain the raw ticket (which can be dumped with nxdumptool). In system version `15.0.0` and later, it must contain a contents authorization token instead (which can be obtained from the [`dragons server`](dragons.md)). **async def auth_gamecard**(title_id: int, title_version: int, device_token: str, cert: bytes, gvt: bytes, challenge: str = None, challenge_src: str = None) -> dict
Requests an application token from the `aauth` server for a gamecard. The device token can be obtained from the [`dauth server`](dauth.md). The certificate can be obtained with nxdumptool. The `gvt` parameter must contain the challenge response. Unless you have the [Lotus](https://switchbrew.org/wiki/Lotus3) encryption keys, the challenge cannot be solved offline, but EpicUsername12 made [a tool](https://github.com/EpicUsername12/nx-netauth-link) that solves the challenge on a real Switch.

The `challenge` and `challenge_src` parameters are required on system version 19.0.1 and later.
**async def auth_nocert**(title_id: int, title_version: int, device_token): str -> dict
Requests an application token from the `aauth` server for a title for which no ticket was found on the Switch.

WARNING: Do not use `auth_nocert` on a production server, because it will immediately ban your Switch.
================================================ FILE: docs/reference/switch/atumn.md ================================================ # Module: nintendo.switch.atumn Provides a client for the [system update content server](https://github.com/kinnay/nintendo/wiki/Atumn-Server). **class** [AtumnClient](#atumnclient)
The `atumn` client. ## AtumnClient **def _\_init__**(device_id: int)
Creates a new atumn client. The device id can be obtained from [PRODINFO](../switch.md). **def set_request_callback**(callback: Callable) -> None
By default, requests are performed with [`http.request`](https://anynet.readthedocs.io/en/latest/reference/http). This method lets you provide a custom callback instead. **def set_context**(context: [TLSContext](https://anynet.readthedocs.io/en/latest/reference/tls/#tlscontext)) -> None
Changes the TLS context. By default, the server certificate is verified with `Nintendo Class 2 CA - G3` and no client certificate is used. **def set_certificate**(cert: [TLSCertificate](https://anynet.readthedocs.io/en/latest/reference/tls/#tlscertificate), key: [TLSPrivateKey](https://anynet.readthedocs.io/en/latest/reference/tls/#tlsprivatekey)) -> None Changes the client certificate of the current TLS context. The server rejects all requests without a valid client certificate. **def set_host**(host: str) -> None
Changes the server to which the HTTP requests are sent. The default is: `atumn.hac.lp1.d4c.nintendo.net`. **def set_system_version**(version: int) -> None
Changes the system version that is emulated by the client. The system version should be given as a decimal integer. For example, `1002` indicates system version `10.0.2`. All system versions from `9.0.0` up to `22.1.0` are supported. **async def download_content_metadata**(title_id: int, title_version: int, *, system_update: bool = False) -> bytes
Downloads the metadata NCA for the given title id and version. The `system_update` parameter should only be set to `True` for the system update title (`0100000000000816`). **async def download_content**(content_id: str) -> bytes
Downloads the NCA for the given content id. ================================================ FILE: docs/reference/switch/baas.md ================================================ # Module: nintendo.switch.baas Provides a client for the [BaaS server](https://github.com/kinnay/nintendo/wiki/BAAS-Server). **class** [PresenceState](#presencestate)
Provides predefined constants for the presence state. **class** [BAASError](#baaserror)(Exception)
Raised when the `BaaS` server returns an error code. **class** [BAASClient](#baasclient)
The `BaaS` client. ## PresenceState `INACTIVE: str = "INACTIVE"`
`ONLINE: str = "ONLINE"`
`PLAYING: str = "PLAYING"` ## BAASError response: [HTTPResponse](https://anynet.readthedocs.io/en/latest/reference/http/#httpresponse)
`type: str`
`name: str`
`title: str`
`detail: str`
`status: int`
`instance: str` ## BAASClient **def _\_init__**()
Creates a new `BaaS` client. **def set_request_callback**(callback: Callable) -> None
By default, requests are performed with [`http.request`](https://anynet.readthedocs.io/en/latest/reference/http). This method lets you provide a custom callback instead. **def set_context**(context: [TLSContext](https://anynet.readthedocs.io/en/latest/reference/tls/#tlscontext)) -> None
Changes the TLS context. By default, the server certificate is verified with default authorities. **def set_certificate**(cert: [TLSCertificate](https://anynet.readthedocs.io/en/latest/reference/tls/#tlscertificate), key: [TLSPrivateKey](https://anynet.readthedocs.io/en/latest/reference/tls/#tlsprivatekey)) -> None Changes the client certificate of the current TLS context. This is required on system version 21.0.0 and later, when `m-lp1.baas.nintendo.com` is contacted. **def set_host**(host: str) -> None
Changes the server to which the HTTP requests are sent. By default, requests are sent to `e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com` or `m-lp1.baas.nintendo.com`, depending on the system version. **def set_power_state**(state: str) -> None
Changes the content of the `X-Nintendo-PowerState` header. The default is `"FA"`. **def set_system_version**(version: int) -> None
Changes the system version that is emulated by the client. The system version should be given as a decimal integer. For example, `1002` indicates system version `10.0.2`. All system versions from `9.0.0` up to `22.1.0` are supported. **async def authenticate**(device_token: str, penne_id: str = None) -> dict
Requests an authorization token with `/1.0.0/application/token`. This method must be called before any other requests can be made. The device token can be obtained from the [`dauth server`](dauth.md).

The `penneId` parameter was added in system version 19.0.0.
**async def login**(id: int, password: str, access_token: str, app_token: str = None, na_country: str = None, skip_verification: bool = False, is_persistent: bool = True) -> dict
Logs in with the given user id and password, using `/1.0.0/login`. If an app token is provided, the server returns an id token that can be used to log in on a game server. App tokens can be obtained from the [`aauth server`](aauth.md). If `skip_verification` is `True` the client asks the server to skip NSO verification.

The `na_country` parameter is required in system version 18.0.0 and later. The `is_persistent` parameter was added in system version 20.0.0.
**async def register**(access_token: str) -> dict
Registers a new device account on the `BaaS` server. **async def update_presence**(user_id: int, device_account_id: int, access_token: str, state: str, title_id: int, presence_group_id: int, app_fields: dict[str, str] = {}, acd_index: int = 0) -> dict
Updates your presence state by patching `/1.0.0/users//device_accounts/`. **async def get_friends**(user_id: int, access_token: str, count: int = 300)
Requests your friend list with `/2.0.0/users//friends`. ================================================ FILE: docs/reference/switch/dauth.md ================================================ # Module: nintendo.switch.dauth Provides a client for the [device authentication server](https://github.com/kinnay/nintendo/wiki/DAuth-Server). **class** [DAuthError](#dautherror)(Exception)
Raised when the `dauth` server returns an error code. **class** [DAuthClient](#dauthclient)
The `dauth` client. **class** [DAuthCache](#dauthcache)
A cache for the dauth client that remembers preloaded tokens. ## Global Constants `CLIENT_ID_SCSI: int = 0x146C8AC7B8A0DB52`
`CLIENT_ID_ER: int = 0x16E96F76850156D1`
`CLIENT_ID_ATUM: int = 0x3117B250CAB38F45`
`CLIENT_ID_ESHOP: int = 0x41F4A6491028E3C4`
`CLIENT_ID_BCAT: int = 0x67BF9945B45248C6`
`CLIENT_ID_SATA: int = 0x6AC5A6873FE5F68C`
`CLIENT_ID_ACCOUNT_APPLET: int = 0x75FE236362FF5F8B`
`CLIENT_ID_ACCOUNT: int = 0x81333C548B2E876D`
`CLIENT_ID_NPNS: int = 0x83B72B05DC3278D7`
`CLIENT_ID_BAAS: int = 0x8F849B5D34778D8E`
`CLIENT_ID_BEACH: int = 0x93AF0ACB26258DE9`
`CLIENT_ID_SPROFILE: int = 0xBAD8156F44AC935A`
`CLIENT_ID_DRAGONS: int = 0xD5B6CAC2C1514C56`
`CLIENT_ID_SCSI_POLICY: int = 0xD98185ACB55994B4`
`CLIENT_ID_PCTL: int = 0xDC656EA03B63CF68`
`CLIENT_ID_PREPO: int = 0xDF51C436BC01C437`
`CLIENT_ID_PENNE: int = 0xE58171FE439390CE` ## DAuthError This exception is raised when the `dauth` server returns an error code. The following constants are defined in this class: `UNAUTHORIZED_DEVICE: int = 4`
`SYSTEM_UPDATE_REQUIRED: int = 7`
`BANNED_DEVICE: int = 8`
`INTERNAL_SERVER_ERROR: int = 9`
`GENERIC: int = 14`
`CHALLENGE_EXPIRED: int = 15`
`WRONG_MAC: int = 16`
`BROKEN_DEVICE: int = 17` The error can be inspected using the following attributes: response: [HTTPResponse](https://anynet.readthedocs.io/en/latest/reference/http/#httpresponse)
`code: int`
`message: str` ## DAuthClient NOTE: On system version 20.0.0 and later, it is recommended to request tokens through a [`DAuthCache`](#dauthcache) instead of using the `DAuthClient` directly. This is because the Switch requests multiple tokens at once on those system versions, and the `DAuthCache` makes it easier to mimic that behavior.
**def _\_init__**(keys: dict[str, bytes])
Creates a new `dauth` client with the given keys. The `dauth` client requires the `aes_kek_generation_source` and `master_key_XX` keys. **def set_request_callback**(callback: Callable) -> None
By default, requests are performed with [`http.request`](https://anynet.readthedocs.io/en/latest/reference/http). This method lets you provide a custom callback instead. **def set_context**(context: [TLSContext](https://anynet.readthedocs.io/en/latest/reference/tls/#tlscontext)) -> None
Changes the TLS context. By default, the server certificate is verified with `Nintendo CA - G3` and no client certificate is used. **def set_certificate**(cert: [TLSCertificate](https://anynet.readthedocs.io/en/latest/reference/tls/#tlscertificate), key: [TLSPrivateKey](https://anynet.readthedocs.io/en/latest/reference/tls/#tlsprivatekey)) -> None Changes the client certificate of the current TLS context. The server rejects all requests without a valid client certificate. **def set_power_state**(state: str) -> None
Changes the content of the `X-Nintendo-PowerState` header. The default is `"FA"`. **def set_platform_region**(region: int) -> None
Changes the platform region. This affects the `ist` parameter in the device authentication request. The default is `1`. **def set_host**(host: str) -> None
Changes the server to which the HTTP requests are sent. The default is `dauth-lp1.ndas.srv.nintendo.net`. **def set_system_version**(version: int) -> None
Changes the system version that is emulated by the client. The system version should be given as a decimal integer. For example, `1002` is system version `10.0.2`. All system versions from `9.0.0` up to `22.1.0` are supported. **async def challenge**() -> dict
Requests a challenge from the `dauth` server. **async def device_token**(client_id: int) -> dict
Requests a device token from the `dauth` server. The challenge is done automatically. This method is available up to system version 19.0.1.

**async def edge_token**(client_id: int, vendor_id: str = "akamai") -> dict
Requests an edge token from the `dauth` server. The challenge is done automatically. This method is available up to system version 19.0.1.

**async def device_tokens**(client_ids: list[int]) -> dict
Requests a multiple device tokens from the `dauth` server. This method is available on system version 20.0.0 and later. **async def edge_tokens**(token_requests: list[tuple[int, str]]) -> dict
Requests a multiple edge tokens from the `dauth` server. The `token_requests` parameter should contain a list of `(client_id, vendor_id)` tuples. This method is available on system version 20.0.0 and later. **async def preload_device_tokens**() -> dict
Requests all device tokens that are preloaded by the Switch at once. This method is available on system version 20.0.0 and later. **async def preload_edge_tokens**() -> dict
Requests all edge tokens that are preloaded by the Switch at once. This method is available on system version 20.0.0 and later. ## DAuthCache **def _\_init__**(client: [DAuthClient](#dauthclient), expiration=None)
Creates a new dauth cache for the given client. If `expiration` is provided, tokens are discarded after the given number of seconds. Otherwise, the `expires_in` field that is returned by the server is used. **async def device_token**(client_id: int) -> dict
Returns a device token from the cache or requests it from the dauth server if it is not present in the cache. **async def edge_token**(client_id: int, vendor_id: str = "akamai") -> dict
Returns an edge token from the cache or requests it from the dauth server if it is not present in the cache. ================================================ FILE: docs/reference/switch/dragons.md ================================================ # Module: nintendo.switch.dragons Provides a client for the [dragons servers](https://github.com/kinnay/nintendo/wiki/Dragons-Servers). **class** [DragonsError](#dragonserror)(Exception)
Raised when the dragons server returns an error code. **class** [DragonsClient](#dragonsclient)
The dragons client. ## DragonsError response: [HTTPResponse](https://anynet.readthedocs.io/en/latest/reference/http/#httpresponse)
`type: str`
`name: str`
`title: str`
`detail: str`
`status: int`
`invalid_params: list | None` If present, the `invalid_params` field contains a list of dictionaries, each of which provides two keys: `name` and `reason`. ## DragonsClient **def _\_init__**(device_id: int = None)
Creates a new dragons client. The device id is required for all methods except for `contents_authorization_token_for_aauth`. **def set_request_callback**(callback: Callable) -> None
By default, requests are performed with [`http.request`](https://anynet.readthedocs.io/en/latest/reference/http). This method lets you provide a custom callback instead. **def set_context**(context: [TLSContext](https://anynet.readthedocs.io/en/latest/reference/tls/#tlscontext)) -> None
Changes the TLS context. By default, the server certificate is verified with `Nintendo Class 2 CA - G3` and no client certificate is used. **def set_certificate**(cert: [TLSCertificate](https://anynet.readthedocs.io/en/latest/reference/tls/#tlscertificate), key: [TLSPrivateKey](https://anynet.readthedocs.io/en/latest/reference/tls/#tlsprivatekey)) -> None Changes the client certificate of the current TLS context. The server rejects all requests without a valid client certificate. **def set_hosts**(dragons: str, dragonst: str, tigers: str) -> None
Changes the servers to which the HTTP requests are sent. The defaults are:
* `dragons.hac.lp1.dragons.nintendo.net`
* `dragonst.hac.lp1.dragons.nintendo.net`
* `tigers.hac.lp1.dragons.nintendo.net`
**def set_system_version**(version: int) -> None
Changes the system version that is emulated by the client. The system version should be given as a decimal integer. For example, `1002` indicates system version `10.0.2`. All system versions from `9.0.0` up to `22.1.0` are supported. **async def publish_device_linked_elicenses**(device_token: str) -> dict
Requests all elicenses that are linked to the given device. The device token can be obtained from the [`dauth server`](dauth.md). **async def exercise_elicense**(device_token: str, elicense_ids: list[str], account_ids: list[int], current_account_id: int) -> None
Calls `/v1/elicenses/exercise` with the given parameters. **async def contents_authorization_token_for_aauth**(device_token: str, elicense_id: str, na_id: int, title_id: int) -> dict
Requests a contents authorization token for [aauth](aauth.md). The device token can be obtained from the [`dauth server`](dauth.md). ================================================ FILE: docs/reference/switch/five.md ================================================ # Module: nintendo.switch.five Provides a client for the [online play invitation server](https://github.com/kinnay/nintendo/wiki/Online-Play-Invitation-Server). **class** [FiveError](#fiveerror)(Exception)
Raised when the server returns an error code. **class** [FiveClient](#fiveclient)
The client. ## FiveError This exception is raised when the server returns an error code. The following constants are defined in this class: `INVALID_PARAMETER: int = 2`
`INVALID_REQUEST_URI: int = 3`
`UNAUTHORIZED: int = 6`
`RESOURCE_NOT_FOUND: int = 10`
`APPLICATION_DATA_TOO_LARGE: int = 11` The error can be inspected using the following attributes: response: [HTTPResponse](https://anynet.readthedocs.io/en/latest/reference/http/#httpresponse)
`code: int`
`message: str` ## FiveClient **def _\_init__**()
Creates a new online play invitation client. **def set_request_callback**(callback: Callable) -> None
By default, requests are performed with [`http.request`](https://anynet.readthedocs.io/en/latest/reference/http). This method lets you provide a custom callback instead. **def set_context**(context: [TLSContext](https://anynet.readthedocs.io/en/latest/reference/tls/#tlscontext)) -> None
Changes the TLS context. By default, the server certificate is verified with `Nintendo CA - G3`. **def set_host**(url: str) -> None
Changes the server to which the HTTP requests are sent. The default is `app.lp1.five.nintendo.net`. **def set_system_version**(version: int) -> None
Changes the system version that is emulated by the client. The system version should be given as a decimal integer. For example, `1002` indicates system version `10.0.2`. All system versions from `9.0.0` up to `22.1.0` are supported. **async def get_unread_invitation_count**(access_token: str, user_id: int) -> int
Requests the number of unread invitations with `/v1/users//invitations/inbox?fields=count&read=false`. **async def get_inbox**(access_token: str, user_id: int) -> dict
Requests the list of received online play invitations. **async def get_invitation_group**(access_token: str, invitation_group_id: int) -> dict
Requests details about a specific invitation group. **async def mark_as_read**(access_token: str, ids: list[int]) -> None
Marks the given list of invitations as read. **async def mark_all_as_read**(access_token: str, user_id: int) -> None
Marks all received invitations as read. **async def send_invitation**(access_token: str, receivers: list[int], application_id: int, application_group_id: int, application_data: bytes, messages: dict[str, str], application_id_match: bool = False, acd_index: int = 0) -> dict
Sends an online play invitation to at most 16 users. The application group id is usually the same as the application id (title id). The application data is game-specific and may contain at most 1024 bytes. ================================================ FILE: docs/reference/switch/sun.md ================================================ # Module: nintendo.switch.sun Provides a client for the [system update meta server](https://github.com/kinnay/nintendo/wiki/Sun-Server). **class** [SunError](#sunerror)(Exception)
Raised when the `sun` server returns an error code. **class** [SunClient](#sunclient)
The `sun` client. ## SunError response: [HTTPResponse](https://anynet.readthedocs.io/en/latest/reference/http/#httpresponse)
`code: str`
`message: str` ## SunClient **def _\_init__**(device_id: int)
Creates a new sun client. The device id can be obtained from [PRODINFO](../switch.md). **def set_request_callback**(callback: Callable) -> None
By default, requests are performed with [`http.request`](https://anynet.readthedocs.io/en/latest/reference/http). This method lets you provide a custom callback instead. **def set_context**(context: [TLSContext](https://anynet.readthedocs.io/en/latest/reference/tls/#tlscontext)) -> None
Changes the TLS context. By default, the server certificate is verified with `Nintendo Class 2 CA - G3` and no client certificate is used. **def set_certificate**(cert: [TLSCertificate](https://anynet.readthedocs.io/en/latest/reference/tls/#tlscertificate), key: [TLSPrivateKey](https://anynet.readthedocs.io/en/latest/reference/tls/#tlsprivatekey)) -> None Changes the client certificate of the current TLS context. The server rejects all requests without a valid client certificate. **def set_host**(host: str) -> None
Changes the server to which the HTTP requests are sent. The default is: `sun.hac.lp1.d4c.nintendo.net`. **def set_system_version**(version: int) -> None
Changes the system version that is emulated by the client. The system version should be given as a decimal integer. For example, `1002` indicates system version `10.0.2`. All system versions from `9.0.0` up to `22.1.0` are supported. **async def system_update_meta**() -> dict
Requests the latest system update metadata. ================================================ FILE: docs/reference/switch.md ================================================ # Module: nintendo.switch Provides useful functions and classes related to Nintendo Switch. **def load_keys**(filename: str) -> dict[str, bytes]
Loads encryption keys from a file such as `prod.keys`. **class** [ProdInfo](#prodinfo)
Reads a decrypted `PRODINFO` file. ## ProdInfo **def _\_init__**(keys: dict[str, bytes], filename: str)
Creates a new [ProdInfo](#prodinfo) object from the given file. The key set should contain at least `ssl_rsa_kek`. **def get_device_id**() -> int
Extracts the device id. **def get_tls_cert**() -> [TLSCertificate](https://anynet.readthedocs.io/en/latest/reference/tls#tlscertificate)
Extracts the device certificate. **def get_tls_key**() -> [TLSPrivateKey](https://anynet.readthedocs.io/en/latest/reference/tls#tlsprivatekey)
Extract the private key that belongs to the device certificate. ================================================ FILE: docs/style.css ================================================ .docs { margin-left: 25px; display: inline-block; } code, .rst-content code { background: transparent; font-size: 100%; border: none; padding: 0px; } .docs code { color: #c60; } td, th { padding: 5px; } table { margin-bottom: 20px; } ================================================ FILE: examples/3ds/friends.py ================================================ from nintendo import nasc from nintendo.nex import backend, friends, settings import anyio import logging logging.basicConfig(level=logging.INFO) SERIAL_NUMBER = "..." # Serial number on console minus the last digit MAC_ADDRESS = "aabbccddeeff" # Console MAC address (see WiFi settings), all lowercase with no colons DEVICE_CERT = bytes.fromhex("...") # Unique console certificate. Get from sniffing traffic DEVICE_NAME = "..." # Doesn't matter # 3DS does NOT send NEX credentials over NASC # They are generated once when the account is created and stored on the device # Homebrew like https://github.com/Stary2001/nex-dissector/tree/master/get_3ds_pid_password # can be used to dump the PID and password PID = 0 PID_HMAC = "..." # Sniff console traffic or dump from friends title save (bytes 66-84) NEX_PASSWORD = "..." REGION = 3 # EUR LANGUAGE = 2 async def main(): client = nasc.NASCClient() client.set_title(0x0004013000003202, 20000) client.set_device(SERIAL_NUMBER, MAC_ADDRESS, DEVICE_CERT, DEVICE_NAME) client.set_locale(REGION, LANGUAGE) client.set_user(PID, PID_HMAC) response = await client.login(0x3200) s = settings.load("friends") s.configure("ridfebb9", 20000) async with backend.connect(s, response.host, response.port) as be: async with be.login(str(PID), NEX_PASSWORD) as client: friends_client = friends.FriendsClientV1(client) await friends_client.update_comment("Hello World") anyio.run(main) ================================================ FILE: examples/custom/server.py ================================================ from nintendo.nex import rmc, kerberos, friends, \ authentication, common, settings import collections import secrets import aioconsole import asyncio import logging logging.basicConfig(level=logging.INFO) User = collections.namedtuple("User", "pid name password") users = [ User(2, "Quazal Rendez-Vous", "password"), User(100, "guest", "MMQea3n!fsik") #More accounts here ] def get_user_by_name(name): for user in users: if user.name == name: return user def get_user_by_pid(pid): for user in users: if user.pid == pid: return user def derive_key(user): deriv = kerberos.KeyDerivationOld(65000, 1024) return deriv.derive_key(user.password.encode("ascii"), user.pid) SECURE_SERVER = "Quazal Rendez-Vous" class AuthenticationServer(authentication.AuthenticationServer): def __init__(self, settings): super().__init__() self.settings = settings async def login(self, client, username): print("User trying to log in:", username) user = get_user_by_name(username) if not user: raise common.RMCError("RendezVous::InvalidUsername") server = get_user_by_name(SECURE_SERVER) url = common.StationURL( scheme="prudps", address="127.0.0.1", port=1224, PID = server.pid, CID = 1, type = 2, sid = 1, stream = 10 ) conn_data = authentication.RVConnectionData() conn_data.main_station = url conn_data.special_protocols = [] conn_data.special_station = common.StationURL() response = rmc.RMCResponse() response.result = common.Result.success() response.pid = user.pid response.ticket = self.generate_ticket(user, server) response.connection_data = conn_data response.server_name = "Example server" return response def generate_ticket(self, source, target): settings = self.settings user_key = derive_key(source) server_key = derive_key(target) session_key = secrets.token_bytes(settings["kerberos.key_size"]) internal = kerberos.ServerTicket() internal.timestamp = common.DateTime.now() internal.source = source.pid internal.session_key = session_key ticket = kerberos.ClientTicket() ticket.session_key = session_key ticket.target = target.pid ticket.internal = internal.encrypt(server_key, settings) return ticket.encrypt(user_key, settings) class FriendsServer(friends.FriendsServerV1): pass #Implement friend server methods here async def main(): s = settings.load("friends") s.configure("ridfebb9", 20000) auth_servers = [ AuthenticationServer(s) ] secure_servers = [ FriendsServer() ] server_key = derive_key(get_user_by_name(SECURE_SERVER)) async with rmc.serve(s, auth_servers, "127.0.0.1", 1223): async with rmc.serve(s, secure_servers, "127.0.0.1", 1224, key=server_key): await aioconsole.ainput("Press enter to exit...\n") asyncio.run(main()) ================================================ FILE: examples/custom/server_login.py ================================================ from nintendo.nex import backend, settings import anyio import logging logging.basicConfig(level=logging.INFO) async def main(): s = settings.load("friends") s.configure("ridfebb9", 20000) async with backend.connect(s, "127.0.0.1", 1223) as be: async with be.login_guest() as client: pass anyio.run(main) ================================================ FILE: examples/switch/animalcrossing.py ================================================ from nintendo.switch import dauth, aauth, baas, dragons from nintendo.nex import backend, authentication, matchmaking, settings from nintendo import switch import anyio import logging logging.basicConfig(level=logging.INFO) SYSTEM_VERSION = 2210 # 22.1.0 # You can get your user id and password from # su/baas/.dat in save folder 8000000000000010. # Bytes 0x20 - 0x28 contain the user id in reversed # byte order, and bytes 0x28 - 0x50 contain the # password in plain text. # Alternatively, you can set up a mitm on your Switch # and extract them from the request to /1.0.0/login BAAS_USER_ID = 0x0123456789abcdef # 16 hex digits BAAS_PASSWORD = "..." # Should be 40 characters NA_COUNTRY = "JP" # Country of your Nintendo account # You can dump prod.keys with Lockpick_RCM and # PRODINFO from hekate (decrypt it if necessary) PATH_KEYS = "/path/to/prod.keys" PATH_PRODINFO = "/path/to/PRODINFO" # License information is stored encrypted in saved/ # in save folder 80000000000000E4. # Alternatively, they can be obtained from the dragons server # by calling publish_device_linked_elicenses (see docs), or with # a mitm on your Switch. ELICENSE_ID = "..." # 32 hex digits NA_ID = 0x0123456789abcdef # 16 hex digits PENNE_ID = "..." CODE = "ABCDE" # Dodo code TITLE_ID = 0x01006F8002326000 TITLE_VERSION = 0x1C0000 GAME_SERVER_ID = 0x2EE2E300 ACCESS_KEY = "v43a10em" NEX_VERSION = 40604 CLIENT_VERSION = 2 HOST = "g%08x-lp1.s.n.srv.nintendo.net" %GAME_SERVER_ID PORT = 443 async def main(): keys = switch.load_keys(PATH_KEYS) info = switch.ProdInfo(keys, PATH_PRODINFO) cert = info.get_tls_cert() pkey = info.get_tls_key() dauth_client = dauth.DAuthClient(keys) dauth_client.set_certificate(cert, pkey) dauth_client.set_system_version(SYSTEM_VERSION) dauth_cache = dauth.DAuthCache(dauth_client) dragons_client = dragons.DragonsClient() dragons_client.set_certificate(cert, pkey) dragons_client.set_system_version(SYSTEM_VERSION) aauth_client = aauth.AAuthClient() aauth_client.set_certificate(cert, pkey) aauth_client.set_system_version(SYSTEM_VERSION) baas_client = baas.BAASClient() baas_client.set_certificate(cert, pkey) baas_client.set_system_version(SYSTEM_VERSION) # Request a device authentication token for dragons response = await dauth_cache.device_token(dauth.CLIENT_ID_DRAGONS) device_token_dragons = response["device_auth_token"] # Request a device authentication token for aauth and bass response = await dauth_cache.device_token(dauth.CLIENT_ID_BAAS) device_token_baas = response["device_auth_token"] # Request a contents authorization token from dragons response = await dragons_client.contents_authorization_token_for_aauth(device_token_dragons, ELICENSE_ID, NA_ID, TITLE_ID) contents_token = response["contents_authorization_token"] # Request an application authentication token response = await aauth_client.auth_digital(TITLE_ID, TITLE_VERSION, device_token_baas, contents_token) app_token = response["application_auth_token"] # Request an anonymous access token for baas response = await baas_client.authenticate(device_token_baas, PENNE_ID) access_token = response["accessToken"] # Log in on the baas server response = await baas_client.login( BAAS_USER_ID, BAAS_PASSWORD, access_token, app_token, NA_COUNTRY ) user_id = int(response["user"]["id"], 16) id_token = response["idToken"] # Set up authentication info for nex server auth_info = authentication.AuthenticationInfo() auth_info.token = id_token auth_info.ngs_version = 4 #Switch auth_info.token_type = 2 # Establish connection with nex server s = settings.load("switch") s.configure(ACCESS_KEY, NEX_VERSION, CLIENT_VERSION) async with backend.connect(s, HOST, PORT) as be: async with be.login(str(user_id), auth_info=auth_info) as client: mm = matchmaking.MatchmakeExtensionClient(client) param = matchmaking.MatchmakeSessionSearchCriteria() param.attribs = ["", "", "", "", "", ""] param.game_mode = "2" param.min_participants = "1" param.max_participants = "1,8" param.matchmake_system = "1" param.vacant_only = False param.exclude_locked = True param.exclude_non_host_pid = True param.selection_method = 0 param.vacant_participants = 1 param.exclude_user_password = True param.exclude_system_password = True param.refer_gid = 0 param.codeword = CODE sessions = await mm.browse_matchmake_session_no_holder_no_result_range(param) if not sessions: print("\nNo island found for '%s'\n" %CODE) else: session = sessions[0] data = session.application_data print("\nFound island:") print("\tId:", session.id) print("\tActive players:", session.num_participants) print("\tIsland name:", data[12:32].decode("utf16").rstrip("\0")) print("\tHost name:", data[40:60].decode("utf16").rstrip("\0")) print() anyio.run(main) ================================================ FILE: examples/switch/smm2_level.py ================================================ from nintendo.switch import dauth, aauth, baas, dragons from nintendo.nex import backend, authentication, \ settings, datastore_smm2 as datastore from nintendo import switch from anynet import http import anyio import logging logging.basicConfig(level=logging.INFO) SYSTEM_VERSION = 2210 # 22.1.0 # You can get your user id and password from # su/baas/.dat in save folder 8000000000000010. # Bytes 0x20 - 0x28 contain the user id in reversed # byte order, and bytes 0x28 - 0x50 contain the # password in plain text. # Alternatively, you can set up a mitm on your Switch # and extract them from the request to /1.0.0/login BAAS_USER_ID = 0x0123456789abcdef # 16 hex digits BAAS_PASSWORD = "..." # Should be 40 characters NA_COUNTRY = "JP" # Country of your Nintendo account # You can dump prod.keys with Lockpick_RCM and # PRODINFO from hekate (decrypt it if necessary) PATH_KEYS = "/path/to/prod.keys" PATH_PRODINFO = "/path/to/PRODINFO" # License information is stored encrypted in saved/ # in save folder 80000000000000E4. # Alternatively, they can be obtained from the dragons server # by calling publish_device_linked_elicenses (see docs), or with # a mitm on your Switch. ELICENSE_ID = "..." # 32 hex digits NA_ID = 0x0123456789abcdef # 16 hex digits PENNE_ID = "..." COURSE_ID = "2J53K2Y9G" TITLE_ID = 0x01009B90006DC000 TITLE_VERSION = 0x70000 GAME_SERVER_ID = 0x22306D00 ACCESS_KEY = "fdf6617f" NEX_VERSION = 40605 CLIENT_VERSION = 60 HOST = "g%08x-lp1.s.n.srv.nintendo.net" %GAME_SERVER_ID PORT = 443 GameStyles = ["SMB1", "SMB3", "SMW", "NSMBU", "SM3DW"] Difficulties = ["Easy", "Normal", "Expert", "Super expert"] CourseThemes = [ "Overworld", "Underground", "Castle", "Airship", "Underwater", "Ghost house", "Snow", "Desert", "Sky", "Forest" ] TagNames = [ "None", "Standard", "Puzzle solving", "Speedrun", "Autoscroll", "Auto mario", "Short and sweet", "Multiplayer versus", "Themed", "Music", "Art", "Technical", "Shooter", "Boss battle", "Single player", "Link" ] def format_time(milliseconds): seconds = (milliseconds // 1000) % 60 minutes = (milliseconds // 1000) // 60 milliseconds = milliseconds % 1000 return "%02i:%02i.%03i" %(minutes, seconds, milliseconds) async def download_thumbnail(store, info, filename): response = await store.get_req_get_info_headers_info(info.data_type) headers = {h.key: h.value for h in response.headers} response = await http.get(info.url, headers=headers) response.raise_if_error() with open(filename, "wb") as f: f.write(response.body) async def main(): keys = switch.load_keys(PATH_KEYS) info = switch.ProdInfo(keys, PATH_PRODINFO) cert = info.get_tls_cert() pkey = info.get_tls_key() dauth_client = dauth.DAuthClient(keys) dauth_client.set_certificate(cert, pkey) dauth_client.set_system_version(SYSTEM_VERSION) dauth_cache = dauth.DAuthCache(dauth_client) dragons_client = dragons.DragonsClient() dragons_client.set_certificate(cert, pkey) dragons_client.set_system_version(SYSTEM_VERSION) aauth_client = aauth.AAuthClient() aauth_client.set_certificate(cert, pkey) aauth_client.set_system_version(SYSTEM_VERSION) baas_client = baas.BAASClient() baas_client.set_certificate(cert, pkey) baas_client.set_system_version(SYSTEM_VERSION) # Request a device authentication token for dragons response = await dauth_cache.device_token(dauth.CLIENT_ID_DRAGONS) device_token_dragons = response["device_auth_token"] # Request a device authentication token for aauth and bass response = await dauth_cache.device_token(dauth.CLIENT_ID_BAAS) device_token_baas = response["device_auth_token"] # Request a contents authorization token from dragons response = await dragons_client.contents_authorization_token_for_aauth(device_token_dragons, ELICENSE_ID, NA_ID, TITLE_ID) contents_token = response["contents_authorization_token"] # Request an application authentication token response = await aauth_client.auth_digital(TITLE_ID, TITLE_VERSION, device_token_baas, contents_token) app_token = response["application_auth_token"] # Request an anonymous access token for baas response = await baas_client.authenticate(device_token_baas, PENNE_ID) access_token = response["accessToken"] # Log in on the baas server response = await baas_client.login( BAAS_USER_ID, BAAS_PASSWORD, access_token, app_token, NA_COUNTRY ) user_id = int(response["user"]["id"], 16) id_token = response["idToken"] # Set up authentication info for nex server auth_info = authentication.AuthenticationInfo() auth_info.token = id_token auth_info.ngs_version = 4 #Switch auth_info.token_type = 2 s = settings.load("switch") s.configure(ACCESS_KEY, NEX_VERSION, CLIENT_VERSION) async with backend.connect(s, HOST, PORT) as be: async with be.login(str(user_id), auth_info=auth_info) as client: store = datastore.DataStoreClientSMM2(client) param = datastore.GetUserOrCourseParam() param.code = COURSE_ID param.course_option = datastore.CourseOption.ALL response = await store.get_user_or_course(param) course = response.course # Print information about the course print("Level info:") print("\tName:", course.name) print("\tDescription:", course.description) print("\tUploaded at:", course.upload_time) print("\tGame:", GameStyles[course.game_style]) print("\tTheme:", CourseThemes[course.course_theme]) print("\tDifficulty:", Difficulties[course.difficulty]) print("\tFirst tag:", TagNames[course.tag1]) print("\tSecond tag:", TagNames[course.tag2]) print("\tWorld record:", format_time(course.time_stats.world_record)) print("\tNumber of comments:", course.comment_stats[0]) # Request information about its uploader param = datastore.GetUsersParam() param.pids = [course.owner_id] response = await store.get_users(param) user = response.users[0] print("Uploader:") print("\tCode:", user.code) print("\tName:", user.name) print("\tCountry:", user.country) print("\tLast active:", user.last_active) # Download thumbnails await download_thumbnail(store, course.one_screen_thumbnail, "thumbnail_onescreen.jpg") await download_thumbnail(store, course.entire_thumbnail, "thumbnail_entire.jpg") # Download level file param = datastore.DataStorePrepareGetParam() param.data_id = course.data_id req_info = await store.prepare_get_object(param) response = await http.get(req_info.url) response.raise_if_error() with open("level.bin", "wb") as f: f.write(response.body) anyio.run(main) ================================================ FILE: examples/switch/smm2_ninji.py ================================================ from nintendo.switch import dauth, aauth, baas, dragons from nintendo.nex import backend, authentication, \ settings, datastore_smm2 as datastore from nintendo import switch from anynet import http import anyio import zlib import logging logging.basicConfig(level=logging.INFO) SYSTEM_VERSION = 2210 # 22.1.0 # You can get your user id and password from # su/baas/.dat in save folder 8000000000000010. # Bytes 0x20 - 0x28 contain the user id in reversed # byte order, and bytes 0x28 - 0x50 contain the # password in plain text. # Alternatively, you can set up a mitm on your Switch # and extract them from the request to /1.0.0/login BAAS_USER_ID = 0x0123456789abcdef # 16 hex digits BAAS_PASSWORD = "..." # Should be 40 characters NA_COUNTRY = "JP" # Country of your Nintendo account # You can dump prod.keys with Lockpick_RCM and # PRODINFO from hekate (decrypt it if necessary) PATH_KEYS = "/path/to/prod.keys" PATH_PRODINFO = "/path/to/PRODINFO" # License information is stored encrypted in saved/ # in save folder 80000000000000E4. # Alternatively, they can be obtained from the dragons server # by calling publish_device_linked_elicenses (see docs), or with # a mitm on your Switch. ELICENSE_ID = "..." # 32 hex digits NA_ID = 0x0123456789abcdef # 16 hex digits PENNE_ID = "..." TITLE_ID = 0x01009B90006DC000 TITLE_VERSION = 0x70000 GAME_SERVER_ID = 0x22306D00 ACCESS_KEY = "fdf6617f" NEX_VERSION = 40605 CLIENT_VERSION = 60 HOST = "g%08x-lp1.s.n.srv.nintendo.net" %GAME_SERVER_ID PORT = 443 async def main(): keys = switch.load_keys(PATH_KEYS) info = switch.ProdInfo(keys, PATH_PRODINFO) cert = info.get_tls_cert() pkey = info.get_tls_key() dauth_client = dauth.DAuthClient(keys) dauth_client.set_certificate(cert, pkey) dauth_client.set_system_version(SYSTEM_VERSION) dauth_cache = dauth.DAuthCache(dauth_client) dragons_client = dragons.DragonsClient() dragons_client.set_certificate(cert, pkey) dragons_client.set_system_version(SYSTEM_VERSION) aauth_client = aauth.AAuthClient() aauth_client.set_certificate(cert, pkey) aauth_client.set_system_version(SYSTEM_VERSION) baas_client = baas.BAASClient() baas_client.set_certificate(cert, pkey) baas_client.set_system_version(SYSTEM_VERSION) # Request a device authentication token for dragons response = await dauth_cache.device_token(dauth.CLIENT_ID_DRAGONS) device_token_dragons = response["device_auth_token"] # Request a device authentication token for aauth and bass response = await dauth_cache.device_token(dauth.CLIENT_ID_BAAS) device_token_baas = response["device_auth_token"] # Request a contents authorization token from dragons response = await dragons_client.contents_authorization_token_for_aauth(device_token_dragons, ELICENSE_ID, NA_ID, TITLE_ID) contents_token = response["contents_authorization_token"] # Request an application authentication token response = await aauth_client.auth_digital(TITLE_ID, TITLE_VERSION, device_token_baas, contents_token) app_token = response["application_auth_token"] # Request an anonymous access token for baas response = await baas_client.authenticate(device_token_baas, PENNE_ID) access_token = response["accessToken"] # Log in on the baas server response = await baas_client.login( BAAS_USER_ID, BAAS_PASSWORD, access_token, app_token, NA_COUNTRY ) user_id = int(response["user"]["id"], 16) id_token = response["idToken"] # Set up authentication info for nex server auth_info = authentication.AuthenticationInfo() auth_info.token = id_token auth_info.ngs_version = 4 #Switch auth_info.token_type = 2 s = settings.load("switch") s.configure(ACCESS_KEY, NEX_VERSION, CLIENT_VERSION) async with backend.connect(s, HOST, PORT) as be: async with be.login(str(user_id), auth_info=auth_info) as client: # Search for ninji courses store = datastore.DataStoreClientSMM2(client) param = datastore.SearchCoursesEventParam() courses = await store.search_courses_event(param) print("Found %i ninji courses.\n" %len(courses)) # Print information about the oldest ninji course course = courses[-1] print("Name:", course.name) print("Description:", course.description) print("Start time:", course.upload_time) print("End time:", course.end_time) print() # Request ghost info param = datastore.GetEventCourseGhostParam() param.data_id = course.data_id param.time = 30000 # Request ghosts with a time around 30 seconds param.count = 1 # Only request a single ghost ghost = (await store.get_event_course_ghost(param))[0] # Request info about the ghost player param = datastore.GetUsersParam() param.pids = [ghost.pid] user = (await store.get_users(param)).users[0] print("Player:", user.name) print("Time: %i.%03i" %(ghost.time // 1000, ghost.time % 1000)) print() # Download replay file header_info = await store.get_req_get_info_headers_info(ghost.replay_file.data_type) headers = {h.key: h.value for h in header_info.headers} response = await http.get(ghost.replay_file.url, headers=headers) response.raise_if_error() # Decompress and save replay file data = zlib.decompress(response.body) with open("replay.bin", "wb") as f: f.write(data) anyio.run(main) ================================================ FILE: examples/switch/system_update.py ================================================ from nintendo.switch import sun, atumn from nintendo import switch import anyio import os import re import struct import subprocess SYSTEM_VERSION = 2210 # 22.1.0 # You can dump prod.keys with Lockpick_RCM and # PRODINFO from hekate (decrypt it if necessary) PATH_KEYS = "/path/to/prod.keys" PATH_PRODINFO = "/path/to/PRODINFO" # This script uses hactool to parse NCA files PATH_HACTOOL = "/path/to/hactool" # Name of folder where files will be stored OUTPUT_PATH = "/path/to/folder" async def retry(worker, n=3): # If the download / connection fails, retry just in case for i in range(n): try: return await worker except anyio.BrokenResourceError: print("Retrying...") raise Exception("Download failed!") async def download_content_metadata(atumn_client, title_id, title_version, *, system_update=False): # Download NCA print("Downloading metadata NCA for title %016x..." %title_id) data = await retry(atumn_client.download_content_metadata(title_id, title_version, system_update=system_update)) # Save data to file nca_path = OUTPUT_PATH + "/metadata_nca/%016x.nca" %title_id with open(nca_path, "wb") as f: f.write(data) # Extract CNMT from NCA section0dir = OUTPUT_PATH + "/cnmt" output = subprocess.check_output([PATH_HACTOOL, nca_path, "--section0dir", section0dir, "--disablekeywarns"]) return re.search("\nSaving .* to (.*)\\.\\.\\.\n", output.decode())[1] # Return the filename async def download_content(atumn_client, title_id, metadata_path): # Parse the CNMT with open(metadata_path, "rb") as f: data = f.read() content_count = struct.unpack_from(" 1: raise ValueError("We currently assume that each title has no more than one NCA") # Download content NCA content_id = data[0x40:0x50].hex() content_size = struct.unpack_from("> 1) / 60 time = "%i:%02i.%02i" %(seconds / 60, seconds % 60, (seconds * 100) % 100) damage = " Damaged " if rankdata.score & 1 else "No damage" kong = ["No Kong", "Diddy", "Dixie", "Cranky"][rankdata.groups[1]] name = rankdata.common_data.decode("ascii")[:-1] print("\t%2i %20s %s (%s) %s" %(rankdata.rank, name, time, damage, kong)) #Now download the world record replay file if available world_record = rankings.data[0] if world_record.param: #If world record has a replay file store = datastore.DataStoreClient(client) get_param = datastore.DataStorePrepareGetParam() get_param.data_id = world_record.param req_info = await store.prepare_get_object(get_param) headers = {header.key: header.value for header in req_info.headers} response = await http.get(req_info.url, headers=headers) response.raise_if_error() with open("replay.bin", "wb") as f: f.write(response.body) anyio.run(main) ================================================ FILE: examples/wiiu/friends.py ================================================ from nintendo.nex import backend, friends, common, settings from nintendo import nnas import anyio import logging logging.basicConfig(level=logging.INFO) DEVICE_ID = 12345678 #From MCP_GetDeviceId SERIAL_NUMBER = "..." SYSTEM_VERSION = 0x270 REGION = 4 #EUR COUNTRY = "NL" LANGUAGE = "en" USERNAME = "..." #Nintendo network id PASSWORD = "..." #Nintendo network password BIRTHDAY = common.DateTime.make(2000, 12, 31) TITLE_ID = 0x10001C00 TITLE_VERSION = 0 GAME_SERVER_ID = 0x3200 ACCESS_KEY = "ridfebb9" NEX_VERSION = 20000 def print_requests(requests): for request in requests: principal_info = request.principal_info message = request.message print("\tWho: %s (%s)" %(principal_info.nnid, principal_info.mii.name)) print("\tMessage:", message.message) if message.game_key.title_id: print("\tGame: %016X (v%i)" %(message.game_key.title_id, message.game_key.title_version)) print("\tSent:", request.sent) print("\tExpires:", message.expires) print("\t" + "-" * 40) print() async def main(): nas = nnas.NNASClient() nas.set_device(DEVICE_ID, SERIAL_NUMBER, SYSTEM_VERSION) nas.set_title(TITLE_ID, TITLE_VERSION) nas.set_locale(REGION, COUNTRY, LANGUAGE) access_token = await nas.login(USERNAME, PASSWORD) nex_token = await nas.get_nex_token(access_token.token, GAME_SERVER_ID) pid = await nas.get_pid(USERNAME) mii = await nas.get_mii(pid) s = settings.load("friends") s.configure(ACCESS_KEY, NEX_VERSION) async with backend.connect(s, nex_token.host, nex_token.port) as be: async with be.login(str(nex_token.pid), nex_token.password) as client: nna_info = friends.NNAInfo() nna_info.principal_info.pid = pid nna_info.principal_info.nnid = USERNAME nna_info.principal_info.mii.name = mii.name nna_info.principal_info.mii.data = mii.data #NintendoPresenceV2 tells the server about your online status, which #game you're currently playing, etc. This will be shown to your friends #in their friend list (unless you disabled this feature). presence = friends.NintendoPresenceV2() friends_client = friends.FriendsClientV2(client) response = await friends_client.update_and_get_all_information( nna_info, presence, BIRTHDAY ) if response.comment.text: print("Your status message: %s (last changed on %s)" %(response.comment.text, response.comment.changed)) else: print("You don't have a status message") if response.friends: print("Friends:") for friend in response.friends: principal_info = friend.nna_info.principal_info print("\tNNID:", principal_info.nnid) print("\tName:", principal_info.mii.name) presence = friend.presence print("\tOnline:", ["No", "Yes"][presence.is_online]) if presence.game_key.title_id: print("\tPlaying: %016X (v%i)" %(presence.game_key.title_id, presence.game_key.title_version)) if friend.comment.text: print("\tStatus: %s (last changed on %s)" %(friend.comment.text, friend.comment.changed)) print("\tFriend since:", friend.befriended) print("\tLast online:", friend.last_online) print("\t" + "-" * 40) print() else: print("You don't have any friends") if response.sent_requests: print("Friend requests sent:") print_requests(response.sent_requests) else: print("You haven't sent any friend requests") if response.received_requests: print("Friend requests received:") print_requests(response.received_requests) else: print("You haven't received any friend requests") if response.blacklist: print("Blacklist:") for item in response.blacklist: principal_info = item.principal_info print("\tWho: %s (%s)" %(principal_info.nnid, principal_info.mii.name)) if item.game_key.title_id: print("\tGame: %016X (%i)" %(item.game_key.title_id, item.game_key.title_version)) print("\tSince:", item.since) print("\t" + "-" * 40) else: print("You haven't blacklisted any users") anyio.run(main) ================================================ FILE: examples/wiiu/mariokart.py ================================================ from nintendo.nex import backend, ranking, datastore, settings from nintendo import nnas from anynet import http import anyio import logging logging.basicConfig(level=logging.INFO) DEVICE_ID = 12345678 #From MCP_GetDeviceId SERIAL_NUMBER = "..." SYSTEM_VERSION = 0x270 REGION_ID = 4 #EU COUNTRY_ID = 94 #NL REGION_NAME = "EUR" COUNTRY_NAME = "NL" LANGUAGE = "en" USERNAME = "..." #Nintendo network id PASSWORD = "..." #Nintendo network password TRACK_ID = 27 #Mario Kart Stadium TITLE_ID = 0x000500001010ED00 TITLE_VERSION = 64 GAME_SERVER_ID = 0x1010EB00 ACCESS_KEY = "25dbf96a" NEX_VERSION = 30504 def format_time(score): millisec = score % 1000 seconds = score // 1000 % 60 minutes = score // 1000 // 60 return "%i:%02i.%03i" %(minutes, seconds, millisec) async def main(): nas = nnas.NNASClient() nas.set_device(DEVICE_ID, SERIAL_NUMBER, SYSTEM_VERSION) nas.set_title(TITLE_ID, TITLE_VERSION) nas.set_locale(REGION_ID, COUNTRY_NAME, LANGUAGE) access_token = await nas.login(USERNAME, PASSWORD) nex_token = await nas.get_nex_token(access_token.token, GAME_SERVER_ID) s = settings.default() s.configure(ACCESS_KEY, NEX_VERSION) async with backend.connect(s, nex_token.host, nex_token.port) as be: async with be.login(str(nex_token.pid), nex_token.password) as client: ranking_client = ranking.RankingClient(client) order_param = ranking.RankingOrderParam() order_param.order_calc = ranking.RankingOrderCalc.ORDINAL order_param.offset = 499 #Start at 500th place order_param.count = 20 #Download 20 highscores rankings = await ranking_client.get_ranking( ranking.RankingMode.GLOBAL, TRACK_ID, order_param, 0, 0 ) ranking_stats = await ranking_client.get_stats( TRACK_ID, order_param, ranking.RankingStatFlags.ALL ) names = await nas.get_nnids([data.pid for data in rankings.data]) #Print some interesting stats stats = ranking_stats.stats print("Total:", int(stats[0])) print("Total time:", format_time(stats[1])) print("Lowest time:", format_time(stats[2])) print("Highest time:", format_time(stats[3])) print("Average time:", format_time(stats[4])) print("Rankings:") for rankdata in rankings.data: time = format_time(rankdata.score) print("\t%5i %20s %s" %(rankdata.rank, names[rankdata.pid], time)) #Let's download the replay file of whoever is in 500th place store = datastore.DataStoreClient(client) rankdata = rankings.data[0] get_param = datastore.DataStorePrepareGetParam() get_param.persistence_target.owner_id = rankdata.pid get_param.persistence_target.persistence_id = TRACK_ID - 16 get_param.extra_data = ["WUP", str(REGION_ID), REGION_NAME, str(COUNTRY_ID), COUNTRY_NAME, ""] req_info = await store.prepare_get_object(get_param) headers = {header.key: header.value for header in req_info.headers} response = await http.get(req_info.url, headers=headers) response.raise_if_error() with open("replay.bin", "wb") as f: f.write(response.body) anyio.run(main) ================================================ FILE: examples/wiiu/miis.py ================================================ from nintendo import nnas, miis import anyio async def main(): nas = nnas.NNASClient() pid = await nas.get_pid("Kinnay-WiiU") mii = await nas.get_mii(pid) print("NNID:", mii.nnid) print("PID:", mii.pid) print("Name:", mii.name) info = miis.MiiData.parse(mii.data) print("Mii:") print("\tBirthday: %i-%i" %(info.birth_day, info.birth_month)) print("\tCreator name:", info.creator_name) print("\tMii color:", info.color) print("\tMii size: %i%%" %(info.size / 128 * 100)) print("\tMii weight: %i%%" %(info.fatness / 128 * 100)) print("\tGender:", ["Male", "Female"][info.gender]) print("\t----------") print("\tBlush style:", info.blush_type) print("\tFace style:", info.face_style) print("\tFace color:", info.face_color) print("\tFace shape:", info.face_type) print("\t----------") print("\tHair style:", info.hair_type) print("\tHair color:", info.hair_color) print("\tHair mirrored:", ["No", "Yes"][info.hair_mirrored]) print("\t----------") print("\tEye style:", info.eye_type) print("\tEye color:", info.eye_color) print("\tEye size:", info.eye_scale) print("\tEye thickness:", info.eye_thickness) print("\tEye height:", info.eye_height) print("\tEye distance:", info.eye_distance) print("\tEye rotation:", info.eye_rotation) print("\t----------") print("\tEyebrow style:", info.eyebrow_type) print("\tEyebrow color:", info.eyebrow_color) print("\tEyebrow size:", info.eyebrow_scale) print("\tEyebrow thickness:", info.eyebrow_thickness) print("\tEyebrow height:", info.eyebrow_height) print("\tEyebrow distance:", info.eyebrow_distance) print("\tEyebrow rotation:", info.eyebrow_rotation) print("\t----------") print("\tNose style:", info.nose_type) print("\tNose size:", info.nose_scale) print("\tNose height:", info.nose_height) print("\t----------") print("\tMouth style:", info.mouth_type) print("\tMouth color:", info.mouth_color) print("\tMouth size:", info.mouth_scale) print("\tMouth thickness:", info.mouth_thickness) print("\tMouth height:", info.mouth_height) print("\t----------") print("\tMustache style:", info.mustache_type) if info.mustache_type: print("\tMustache height:", info.mustache_height) print("\tMustache size:", info.mustache_scale) print("\tBeard style:", info.beard_type) if info.beard_type: print("\tBeard color:", info.beard_color) print("\t----------") print("\tGlasses style:", info.glass_type) if info.glass_type: print("\tGlasses color:", info.glass_color) print("\tGlasses size:", info.glass_scale) print("\tGlasses height:", info.glass_height) print("\t----------") print("\tMole:", ["No", "Yes"][info.mole_enabled]) if info.mole_enabled: print("\tMole size:", info.mole_scale) print("\tMole X:", info.mole_xpos) print("\tMole Y:", info.mole_ypos) print("Images:") for image in mii.images: print("\t%s" %image.url) anyio.run(main) ================================================ FILE: generate_protocols.py ================================================ import string import os TYPE_NAME = 0 TYPE_RESERVED = 1 TYPE_SYMBOL = 2 TYPE_NUMBER = 3 TYPE_STRING = 4 TYPE_EOF = 5 class Token: def __init__(self, type, value, row, col): self.type = type self.value = value self.row = row self.col = col NAME_HEAD_CHARS = string.ascii_letters + "_" NAME_CHARS = NAME_HEAD_CHARS + string.digits NUMBER_CHARS = string.digits + string.ascii_lowercase SPECIAL_CHARS = "{}()[]<>:;,.-=!#" RESERVED_WORDS = [ "import", "protocol", "method", "struct", "enum", "nex", "revision", "set" ] CHAR_EOF = "EOF" class Tokenizer: def process(self, data): self.tokens = [] self.state = self.state_next self.row = 1 self.col = 1 for char in data: self.state(char) if char == "\n": self.row += 1 self.col = 1 else: self.col += 1 self.state(CHAR_EOF) self.add(TYPE_EOF, None) return self.tokens def error(self, char): raise ValueError("Unexpected character at %i:%i in %s: %s" %(self.row, self.col, self.state.__name__, char)) def add(self, type, value): token = Token(type, value, self.token_row, self.token_col) self.tokens.append(token) def state_next(self, char): self.token_row = self.row self.token_col = self.col if char == '"': self.string = "" self.state = self.state_string elif char == "/": self.state = self.state_comment_start elif char == "0": self.number = "" self.state = self.state_number_prefix elif char in NUMBER_CHARS[:10]: self.base = 10 self.number = char self.state = self.state_number elif char in NAME_HEAD_CHARS: self.name = char self.state = self.state_name elif char in SPECIAL_CHARS: self.add(TYPE_SYMBOL, char) elif char in string.whitespace or char == CHAR_EOF: pass else: self.error(char) def state_comment_start(self, char): if char == "/": self.state = self.state_comment_line elif char == "*": self.state = self.state_comment_block else: self.error(char) def state_comment_line(self, char): if char == "\n" or char == CHAR_EOF: self.state = self.state_next def state_comment_block(self, char): if char == CHAR_EOF: self.error(char) elif char == "*": self.state = self.state_comment_end def state_comment_end(self, char): if char == "/": self.state = self.state_next else: self.state = self.state_comment_block self.state(char) def state_name(self, char): if char in NAME_CHARS: self.name += char else: if self.name in RESERVED_WORDS: self.add(TYPE_RESERVED, self.name) else: self.add(TYPE_NAME, self.name) self.state = self.state_next self.state(char) def state_string(self, char): if char == CHAR_EOF: self.error(char) elif char == '"': self.add(TYPE_STRING, self.string) self.state = self.state_next else: self.string += char def state_number(self, char): if char.lower() in NUMBER_CHARS[:self.base]: self.number += char else: self.add(TYPE_NUMBER, int(self.number, self.base)) self.state = self.state_next self.state(char) def state_number_prefix(self, char): if char == "x": self.base = 16 self.state = self.state_number else: self.base = 10 self.number = "0" self.state = self.state_number self.state(char) class TokenStream: def __init__(self, tokens): self.tokens = tokens self.index = 0 def read(self): token = self.tokens[self.index] self.index += 1 return token def peek(self): return self.tokens[self.index] def rewind(self): self.index -= 1 def error(self, token): if token.type == TYPE_EOF: message = "Unexpected end of file" else: message = "Unexpected token at %i:%i: %s" %(token.row, token.col, token.value) raise ValueError(message) def read_token(self, type): token = self.read() if token.type != type: self.error(token) return token def parse_token(self, type): return self.read_token(type).value def skip_token(self, type, value): token = self.read() if token.type != type or token.value != value: self.error(token) def check_token(self, type, value): token = self.peek() if token.type == type and token.value == value: self.index += 1 return True return False def read_reserved(self): return self.read_token(TYPE_RESERVED) def read_name(self): return self.read_token(TYPE_NAME) def read_symbol(self): return self.read_token(TYPE_SYMBOL) def parse_name(self): return self.parse_token(TYPE_NAME) def parse_number(self): return self.parse_token(TYPE_NUMBER) def parse_string(self): return self.parse_token(TYPE_STRING) def check_reserved(self, value): return self.check_token(TYPE_RESERVED, value) def check_symbol(self, value): return self.check_token(TYPE_SYMBOL, value) def check_eof(self): return self.check_token(TYPE_EOF, None) def skip_name(self, value): self.skip_token(TYPE_NAME, value) def skip_reserved(self, value): self.skip_token(TYPE_RESERVED, value) def skip_symbol(self, value): self.skip_token(TYPE_SYMBOL, value) class Scope: def __init__(self): self.names = [] def __contains__(self, name): return name in self.names def add(self, name): if name in self.names: return True self.names.append(name) return False class File: def __init__(self): self.protocols = {} self.structs = {} self.enums = [] self.scope = Scope() def check_protocols(self): for proto in self.protocols.values(): proto.check() def sort_protocols(self): for proto in self.protocols.values(): proto.sort() def sort_types(self): self.structs = {k: v for k, v in sorted(self.structs.items())} self.enums = sorted(self.enums, key=lambda e: e.name) def add_file(self, file): for proto in file.protocols.values(): self.add_protocol(proto) for struct in file.structs.values(): self.add_struct(struct) for enum in file.enums: self.add_enum(enum) def add_protocol(self, proto): if self.scope.add(proto.name): item = self.protocols.get(proto.name) if not item or item.file == self or proto.file != self: raise ValueError("%s is already defined" %proto.name) self.protocols[proto.name] = proto def add_struct(self, struct): if self.scope.add(struct.name): item = self.structs.get(struct.name) if not item or item.file == self or struct.file != self: raise ValueError("%s is already defined" %struct.name) self.structs[struct.name] = struct def add_enum(self, enum): if self.scope.add(enum.name): raise ValueError("%s is already defined" %enum.name) self.enums.append(enum) class Protocol: id = None name = None overridden = False noresponse = False def __init__(self): self.methods = {} self.scope = Scope() def sort(self): self.methods = {k: v for k, v in sorted(self.methods.items())} def check(self): if self.noresponse and any(method.response.vars for method in self.methods.values()): raise ValueError("%s is marked noresponse but at least one method returns a non-empty response" %self.name) def add_method(self, method): if self.scope.add(method.name): raise ValueError("%s is already defined in %s" %(method.name, self.name)) if method.id in self.methods: raise ValueError("Method id %i is used twice in %s" %(method.id, self.name)) self.methods[method.id] = method def set_parent(self, parent): parent.overridden = True self.id = parent.id for method in parent.methods.values(): if method.id not in self.methods: self.add_method(method) class Method: id = None name = None request = None response = None supported = None class VariableList: def __init__(self): self.vars = [] self.scope = Scope() def add(self, var): if self.scope.add(var.name): raise ValueError("Duplicate variable name: %s" %var.name) self.vars.append(var) class Variable: type = None name = None default = None class Type: name = None template = None class Struct: name = None parent = None body = None class Condition: VERSION = 0 REVISION = 1 type = None minimum = None maximum = None body = None class StructBody: def __init__(self): self.fields = [] def has_revision(self): for field in self.fields: if isinstance(field, Condition): if field.type == Condition.REVISION: return True if field.body.has_revision(): return True return False def add(self, field): self.fields.append(field) class Enum: name = None def __init__(self): self.values = [] self.scope = Scope() def add(self, name, value): if self.scope.add(name): raise ValueError("Name %s used twice in enum %s" %(name, self.name)) self.values.append((name, value)) TEMPLATE_TYPES = { "list": 1, "map": 2 } NUMERIC_TYPES = [ "uint8", "uint16", "uint32", "uint64", "sint8", "sint16", "sint32", "sint64", "pid" ] STRING_TYPES = [ "string", "buffer", "qbuffer", "stationurl" ] class Parser: def process(self, tokens): stream = TokenStream(tokens) return self.parse_file(stream) def parse_file(self, stream): self.file = File() while True: token = stream.peek() if token.type == TYPE_EOF: return self.file elif token.type == TYPE_RESERVED and token.value == "import": self.parse_import(stream) elif token.type == TYPE_RESERVED and token.value == "protocol": self.file.add_protocol(self.parse_protocol(stream)) elif token.type == TYPE_RESERVED and token.value == "struct": self.file.add_struct(self.parse_struct(stream)) elif token.type == TYPE_RESERVED and token.value == "enum": self.file.add_enum(self.parse_enum(stream)) else: stream.error(token) def parse_import(self, stream): stream.skip_reserved("import") name = stream.parse_name() stream.skip_symbol(";") print("Importing %s.proto" %name) path = "nintendo/files/proto/%s.proto" %name with open(path) as f: text = f.read() tokens = Tokenizer().process(text) file = Parser().process(tokens) self.file.add_file(file) def parse_protocol(self, stream): stream.skip_reserved("protocol") protocol = Protocol() protocol.file = self.file protocol.name = stream.parse_name() stream.skip_symbol(":") parent = None token = stream.read() if token.type == TYPE_NUMBER: protocol.id = token.value elif token.type == TYPE_NAME: parent = token.value else: stream.error(token) stream.skip_symbol("{") self.prev_method = 0 while True: token = stream.peek() if token.type == TYPE_SYMBOL and token.value == "}": stream.skip_symbol("}") break elif token.type == TYPE_RESERVED: if token.value == "method": protocol.add_method(self.parse_method(stream)) elif token.value == "set": stream.skip_reserved("set") stream.skip_name("noresponse") stream.skip_symbol(";") protocol.noresponse = True else: stream.error(token) else: stream.error(token) if parent: protocol.set_parent(self.file.protocols[parent]) return protocol def parse_method(self, stream): stream.skip_reserved("method") method = Method() token = stream.peek() if token.type == TYPE_SYMBOL and token.value == "(": stream.skip_symbol("(") method.id = stream.parse_number() stream.skip_symbol(")") else: method.id = self.prev_method + 1 self.prev_method = method.id method.name = stream.parse_name() token = stream.read_symbol() if token.value == "(": method.request = self.parse_parameter_list(stream) stream.skip_symbol("{") method.response = self.parse_variable_list(stream) method.supported = True elif token.value == ";": method.supported = False else: stream.error(token) return method def parse_parameter_list(self, stream): list = VariableList() token = stream.peek() if token.type == TYPE_SYMBOL and token.value == ")": stream.skip_symbol(")") return list while True: list.add(self.parse_variable(stream)) token = stream.read_symbol() if token.value == ")": return list elif token.value != ",": stream.error(token) def parse_variable_list(self, stream): list = VariableList() while True: token = stream.peek() if token.type == TYPE_SYMBOL and token.value == "}": stream.skip_symbol("}") return list list.add(self.parse_variable(stream)) stream.skip_symbol(";") def parse_variable(self, stream): var = Variable() var.type = self.parse_type(stream) var.name = stream.parse_name() token = stream.peek() if token.type == TYPE_SYMBOL and token.value == "=": stream.skip_symbol("=") var.default = self.parse_constant(stream, var.type) return var def parse_type(self, stream): type = Type() type.name = stream.parse_name() if type.name in TEMPLATE_TYPES: type.template = self.parse_template(stream, TEMPLATE_TYPES[type.name]) elif type.name == "anydata": token = stream.peek() if token.type == TYPE_SYMBOL and token.value == "<": type.template = self.parse_template(stream, 1) return type def parse_template(self, stream, num): template = [] stream.skip_symbol("<") for i in range(num): template.append(self.parse_type(stream)) if i < num - 1: stream.skip_symbol(",") stream.skip_symbol(">") return template def parse_constant(self, stream, type): if type.name in NUMERIC_TYPES: return stream.parse_number() elif type.name in STRING_TYPES: return stream.parse_string() elif type.name == "bool": token = stream.read_name() if token.value not in ["false", "true"]: stream.error(token) return token.value == "true" elif type.name == "datetime": token = stream.read() if token.type == TYPE_NUMBER: return token.value elif token.type == TYPE_NAME: if token.value == "never": return 0 if token.value == "future": return 671076024059 stream.error(token) elif type.name == "list": list = [] stream.skip_symbol("[") token = stream.peek() if token.type == TYPE_SYMBOL and token.value == "]": stream.skip_symbol("]") return list subtype = type.template[0] while True: list.append(self.parse_constant(stream, subtype)) token = stream.read_symbol() if token.value == "]": return list elif token.value != ",": stream.error(token) elif type.name == "map": map = {} stream.skip_symbol("{") token = stream.peek() if token.type == TYPE_SYMBOL and token.value == "}": stream.skip_symbol("}") return map keytype = type.template[0] valuetype = type.template[1] while True: key = self.parse_constant(stream, keytype) stream.skip_symbol(":") value = self.parse_constant(stream, valuetype) map[key] = value token = stream.read_symbol() if token.value == "}": return map elif token.value != ",": stream.error(token) else: raise ValueError("Don't know how to parse constant for %s" %type.name) def parse_struct(self, stream): stream.skip_reserved("struct") struct = Struct() struct.file = self.file struct.name = stream.parse_name() token = stream.peek() if token.type == TYPE_SYMBOL and token.value == ":": stream.skip_symbol(":") struct.parent = stream.parse_name() struct.body = self.parse_struct_body(stream) return struct def parse_struct_body(self, stream): body = StructBody() stream.skip_symbol("{") while True: token = stream.peek() if token.type == TYPE_SYMBOL and token.value == "}": stream.skip_symbol("}") return body body.add(self.parse_struct_item(stream)) def parse_struct_item(self, stream): token = stream.peek() if token.type == TYPE_RESERVED: return self.parse_condition(stream) var = self.parse_variable(stream) stream.skip_symbol(";") return var def parse_condition(self, stream): cond = Condition() token = stream.read_reserved() if token.value == "nex": cond.type = Condition.VERSION elif token.value == "revision": cond.type = Condition.REVISION else: stream.error(token) cond.minimum = stream.parse_number() if stream.check_symbol("-"): cond.maximum = stream.parse_number() cond.body = self.parse_struct_body(stream) return cond def parse_enum(self, stream): stream.skip_reserved("enum") enum = Enum() enum.name = stream.parse_name() stream.skip_symbol("{") token = stream.peek() if token.type == TYPE_SYMBOL and token.value == "}": stream.skip_symbol("}") return enum while True: name = stream.parse_name() stream.skip_symbol("=") value = stream.parse_number() enum.add(name, value) token = stream.read_symbol() if token.value == "}": return enum elif token.value != ",": stream.error(token) class CodeStream: def __init__(self): self.code = "" self.tabs = 0 def get(self): return self.code def indent(self): self.tabs += 1 def unindent(self): self.tabs -= 1 def write(self, text): self.code += text def begin_line(self): self.write("\t" * self.tabs) def write_line(self, line=""): self.begin_line() self.write(line + "\n") BASIC_TYPES = [ "float", "double", "bool", "pid", "result", "datetime", "string", "stationurl", "buffer", "qbuffer", "anydata", "variant" ] MAPPED_TYPES = { "uint8": "u8", "uint16": "u16", "uint32": "u32", "uint64": "u64", "sint8": "s8", "sint16": "s16", "sint32": "s32", "sint64": "s64", } EXTERNAL_TYPES = [ "ResultRange", "NotificationEvent" ] def make_class_name(name, type): if "_" in name: name, ext = name.rsplit("_", 1) return "%s%s%s" %(name, type, ext) return "%s%s" %(name, type) class CodeGenerator: def process(self, file): self.file = file self.file.check_protocols() self.file.sort_protocols() stream = CodeStream() self.generate_file(stream) return stream.get() def generate_file(self, stream): self.generate_header(stream) for enum in self.file.enums: self.generate_enum(stream, enum) for struct in self.file.structs.values(): self.generate_struct(stream, struct) for proto in self.file.protocols.values(): if not proto.overridden: self.generate_protocol(stream, proto) for proto in self.file.protocols.values(): if not proto.overridden: self.generate_client(stream, proto) for proto in self.file.protocols.values(): if not proto.overridden: self.generate_server(stream, proto) def generate_header(self, stream): stream.write_line() stream.write_line("# This file was generated automatically by generate_protocols.py") stream.write_line() stream.write_line("from nintendo.nex import notification, rmc, common, streams") stream.write_line() stream.write_line("import logging") stream.write_line("logger = logging.getLogger(__name__)") stream.write_line() def generate_enum(self, stream, enum): stream.write_line() stream.write_line("class %s:" %enum.name) stream.indent() if enum.values: for name, value in enum.values: stream.write_line("%s = %i" %(name, value)) else: stream.write_line("pass") stream.unindent() stream.write_line() def generate_struct(self, stream, struct): stream.write_line() parent = struct.parent if parent is None: parent = "common.Structure" elif parent == "Data": parent = "common.Data" stream.write_line("class %s(%s):" %(struct.name, parent)) stream.indent() self.generate_struct_init(stream, struct) self.generate_struct_version(stream, struct) self.generate_struct_check(stream, struct) self.generate_struct_load(stream, struct) self.generate_struct_save(stream, struct) stream.unindent() if struct.parent: stream.write_line('common.DataHolder.register(%s, "%s")' %(struct.name, struct.name)) stream.write_line() def generate_struct_init(self, stream, struct): stream.write_line("def __init__(self):") stream.indent() stream.write_line("super().__init__()") self.generate_struct_init_body(stream, struct.body, {}) stream.unindent() stream.write_line() def generate_struct_init_body(self, stream, body, defaults): for field in body.fields: if isinstance(field, Variable): if field.name in defaults: if defaults[field.name] != field.default: raise ValueError("Duplicate variable name in struct with incompatible defaults: %s" %field.name) else: defaults[field.name] = field.default stream.write_line("self.%s = %s" %(field.name, self.make_constant(field.type, field.default))) elif isinstance(field, Condition): self.generate_struct_init_body(stream, field.body, defaults) def generate_if_statement(self, stream, cond, prefix=""): field = f'{prefix}settings["nex.version"]' if cond.type == Condition.VERSION else "version" if cond.maximum is None: stream.write_line(f"if {field} >= {cond.minimum}:") else: stream.write_line(f"if {cond.minimum} <= {field} < {cond.maximum}:") def generate_struct_version(self, stream, struct): if struct.body.has_revision(): stream.write_line("def max_version(self, settings):") stream.indent() stream.write_line("version = 0") self.generate_struct_version_body(stream, struct.body) stream.write_line("return version") stream.unindent() stream.write_line() def generate_struct_version_body(self, stream, body): for field in body.fields: if isinstance(field, Condition): if field.type == Condition.REVISION: stream.write_line("version = %i" %field.minimum) elif field.type == Condition.VERSION: if field.body.has_revision(): self.generate_if_statement(stream, field) stream.indent() self.generate_struct_version_body(stream, field.body) stream.unindent() def generate_struct_check(self, stream, struct): stream.write_line("def check_required(self, settings, version):") stream.indent() self.generate_struct_check_body(stream, struct.body) stream.unindent() stream.write_line() def generate_struct_check_body(self, stream, body): required = [] for field in body.fields: if isinstance(field, Variable): if field.type.name not in self.file.structs and \ field.type.name not in EXTERNAL_TYPES and \ field.default is None: required.append(field.name) if required: stream.write_line("for field in %s:" %required) stream.write_line("\tif getattr(self, field) is None:") stream.write_line('\t\traise ValueError("No value assigned to required field: %s" %field)') conditions = [f for f in body.fields if isinstance(f, Condition)] for cond in conditions: self.generate_if_statement(stream, cond) stream.indent() self.generate_struct_check_body(stream, cond.body) stream.unindent() if not required and not conditions: stream.write_line("pass") def generate_struct_load(self, stream, struct): stream.write_line("def load(self, stream, version):") stream.indent() self.generate_struct_load_body(stream, struct.body) stream.unindent() stream.write_line() def generate_struct_load_body(self, stream, body): if not body.fields: stream.write_line("pass") for field in body.fields: if isinstance(field, Variable): stream.write_line("self.%s = %s" %(field.name, self.make_extract(field.type))) elif isinstance(field, Condition): self.generate_if_statement(stream, field, "stream.") stream.indent() self.generate_struct_load_body(stream, field.body) stream.unindent() def generate_struct_save(self, stream, struct): stream.write_line("def save(self, stream, version):") stream.indent() stream.write_line("self.check_required(stream.settings, version)") self.generate_struct_save_body(stream, struct.body) stream.unindent() def generate_struct_save_body(self, stream, body): for field in body.fields: if isinstance(field, Variable): stream.write_line(self.make_encode(field.type, "self.%s" %field.name)) elif isinstance(field, Condition): self.generate_if_statement(stream, field, "stream.") stream.indent() self.generate_struct_save_body(stream, field.body) stream.unindent() def generate_protocol(self, stream, proto): name = make_class_name(proto.name, "Protocol") stream.write_line() stream.write_line("class %s:" %name) stream.indent() if proto.noresponse: stream.write_line("NORESPONSE = True") stream.write_line() for method in proto.methods.values(): stream.write_line("METHOD_%s = %i" %(method.name.upper(), method.id)) stream.write_line() stream.write_line("PROTOCOL_ID = 0x%X" %proto.id) stream.unindent() stream.write_line() def generate_client(self, stream, proto): proto_name = make_class_name(proto.name, "Protocol") client_name = make_class_name(proto.name, "Client") stream.write_line() stream.write_line("class %s(%s):" %(client_name, proto_name)) stream.indent() stream.write_line("def __init__(self, client):") stream.write_line("\tself.settings = client.settings") stream.write_line("\tself.client = client") stream.write_line() first = True for method in proto.methods.values(): if method.supported: if not first: stream.write_line() else: first = False self.generate_client_method(stream, proto, method) stream.unindent() stream.write_line() def generate_client_method(self, stream, proto, method): class_name = make_class_name(proto.name, "Client") param = ", ".join(["self"] + [param.name for param in method.request.vars]) stream.write_line("async def %s(%s):" %(method.name, param)) stream.indent() stream.write_line('logger.info("%s.%s()")' %(class_name, method.name)) stream.write_line("#--- request ---") stream.write_line("stream = streams.StreamOut(self.settings)") for param in method.request.vars: stream.write_line(self.make_encode(param.type, param.name)) if proto.noresponse: stream.write_line("await self.client.request(self.PROTOCOL_ID, self.METHOD_%s, stream.get(), True)" %method.name.upper()) else: stream.write_line("data = await self.client.request(self.PROTOCOL_ID, self.METHOD_%s, stream.get())" %method.name.upper()) stream.write_line() stream.write_line("#--- response ---") stream.write_line("stream = streams.StreamIn(data, self.settings)") if len(method.response.vars) > 1: stream.write_line("obj = rmc.RMCResponse()") for var in method.response.vars: stream.write_line("obj.%s = %s" %(var.name, self.make_extract(var.type))) elif len(method.response.vars) == 1: value = method.response.vars[0] stream.write_line("%s = %s" %(value.name, self.make_extract(value.type))) stream.write_line("if not stream.eof():") stream.write_line('\traise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell()))') stream.write_line('logger.info("%s.%s -> done")' %(class_name, method.name)) if len(method.response.vars) > 1: stream.write_line("return obj") elif len(method.response.vars) == 1: stream.write_line("return %s" %(method.response.vars[0].name)) stream.unindent() def generate_server(self, stream, proto): server_name = make_class_name(proto.name, "Server") proto_name = make_class_name(proto.name, "Protocol") stream.write_line() stream.write_line("class %s(%s):" %(server_name, proto_name)) stream.indent() stream.write_line("def __init__(self):") stream.indent() stream.write_line("self.methods = {") for method in proto.methods.values(): stream.write_line("\tself.METHOD_%s: self.handle_%s," %(method.name.upper(), method.name)) stream.write_line("}") stream.unindent() stream.write_line() stream.write_line("async def logout(self, client):") stream.write_line("\tpass") stream.write_line() stream.write_line("async def handle(self, client, method_id, input, output):") stream.write_line("\tif method_id in self.methods:") stream.write_line("\t\tawait self.methods[method_id](client, input, output)") stream.write_line("\telse:") stream.write_line('\t\tlogger.warning("Unknown method called on %s: %%i", method_id)' %server_name) stream.write_line('\t\traise common.RMCError("Core::NotImplemented")') for method in proto.methods.values(): stream.write_line() self.generate_server_method(stream, proto, method) for method in proto.methods.values(): if method.supported: stream.write_line() self.generate_server_stub(stream, proto, method) stream.unindent() stream.write_line() def generate_server_method(self, stream, proto, method): class_name = make_class_name(proto.name, "Server") stream.write_line("async def handle_%s(self, client, input, output):" %method.name) if not method.supported: stream.write_line('\tlogger.warning("%s.%s is not supported")' %(class_name, method.name)) stream.write_line('\traise common.RMCError("Core::NotImplemented")') return stream.indent() stream.write_line('logger.info("%s.%s()")' %(class_name, method.name)) stream.write_line("#--- request ---") for param in method.request.vars: stream.write_line("%s = %s" %(param.name, self.make_extract(param.type, "input"))) params = ", ".join(["client"] + [p.name for p in method.request.vars]) if len(method.response.vars) > 1: names = [var.name for var in method.response.vars] stream.write_line("response = await self.%s(%s)" %(method.name, params)) stream.write_line() stream.write_line("#--- response ---") stream.write_line("if not isinstance(response, rmc.RMCResponse):") stream.write_line('\traise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__)') stream.write_line("for field in %s:" %names) stream.write_line("\tif not hasattr(response, field):") stream.write_line('\t\traise RuntimeError("Missing field in RMCResponse: %s" %field)') for var in method.response.vars: stream.write_line(self.make_encode(var.type, "response.%s" %var.name, "output")) elif len(method.response.vars) == 1: var = method.response.vars[0] expected = self.make_python_type(var.type) stream.write_line("response = await self.%s(%s)" %(method.name, params)) stream.write_line() stream.write_line("#--- response ---") stream.write_line("if not isinstance(response, %s):" %expected) stream.write_line('\traise RuntimeError("Expected %s, got %%s" %%response.__class__.__name__)' %expected) stream.write_line(self.make_encode(var.type, "response", "output")) else: stream.write_line("await self.%s(%s)" %(method.name, params)) stream.unindent() def generate_server_stub(self, stream, proto, method): class_name = make_class_name(proto.name, "Server") stream.write_line("async def %s(self, *args):" %method.name) stream.write_line('\tlogger.warning("%s.%s not implemented")' %(class_name, method.name)) stream.write_line('\traise common.RMCError("Core::NotImplemented")') def make_python_type(self, type): if type.name == "bool": return "bool" if type.name == "list": return "list" if type.name == "map": return "dict" if type.name == "string": return "str" if type.name == "variant": return "object" if type.name in ["buffer", "qbuffer"]: return "bytes" if type.name == "datetime": return "common.DateTime" if type.name == "stationurl": return "common.StationURL" if type.name == "result": return "common.Result" if type.name == "anydata": if type.template: return self.make_python_type(type.template[0]) return "common.Data" if type.name == "ResultRange": return "common.ResultRange" if type.name == "NotificationEvent": return "notification.NotificationEvent" if type.name in self.file.structs: return type.name if type.name in NUMERIC_TYPES: return "int" raise ValueError("Unknown type: %s" %type.name) def make_constant(self, type, value): if type.name in self.file.structs: return "%s()" %type.name if type.name == "ResultRange": return "common.ResultRange()" if type.name == "NotificationEvent": return "notification.NotificationEvent()" if value is None: return "None" if type.name == "datetime": return "common.DateTime(%i)" %value if type.name == "string": return '"%s"' %value if type.name == "stationurl": return 'common.StationURL.parse("%s")' %value if type.name in ["buffer", "qbuffer"]: return 'b"%s"' %value if type.name in NUMERIC_TYPES + ["bool"]: return str(value) if type.name == "list": entries = [] for entry in value: entries.append(self.make_constant(type.template[0], entry)) return "[%s]" %", ".join(entries) if type.name == "map": items = [] for key, value in value.items(): key = self.make_constant(type.template[0], key) value = self.make_constant(type.template[1], value) items.append("%s: %s" %(key, value)) return "{%s}" %", ".join(items) raise ValueError("Unknown type: %s" %type.name) def make_extract(self, type, stream="stream"): if type.name in BASIC_TYPES: return "%s.%s()" %(stream, type.name) if type.name in MAPPED_TYPES: return "%s.%s()" %(stream, MAPPED_TYPES[type.name]) if type.name in self.file.structs: return "%s.extract(%s)" %(stream, type.name) if type.name == "ResultRange": return "%s.extract(common.ResultRange)" %stream if type.name == "NotificationEvent": return "%s.extract(notification.NotificationEvent)" %stream if type.name == "list": func = self.make_extract_func(type.template[0], stream) return "%s.list(%s)" %(stream, func) if type.name == "map": keyfunc = self.make_extract_func(type.template[0], stream) valuefunc = self.make_extract_func(type.template[1], stream) return "%s.map(%s, %s)" %(stream, keyfunc, valuefunc) raise ValueError("Unknown type: %s" %type.name) def make_extract_func(self, type, stream="stream"): if type.name in BASIC_TYPES: return "%s.%s" %(stream, type.name) if type.name in MAPPED_TYPES: return "%s.%s" %(stream, MAPPED_TYPES[type.name]) if type.name in self.file.structs: return type.name if type.name == "ResultRange": return "common.ResultRange" if type.name == "NotificationEvent": return "notification.NotificationEvent" if type.name == "list": return "lambda: %s.list(%s)" %(stream, self.make_extract_func(type.template[0], stream)) raise ValueError("Unknown type in list: %s" %type.name) def make_encode(self, type, name, stream="stream"): if type.name == "list": func = self.make_encode_func(type.template[0], stream) return "%s.list(%s, %s)" %(stream, name, func) if type.name == "map": keyfunc = self.make_encode_func(type.template[0], stream) valuefunc = self.make_encode_func(type.template[1], stream) return "%s.map(%s, %s, %s)" %(stream, name, keyfunc, valuefunc) return "%s(%s)" %(self.make_encode_func(type, stream), name) def make_encode_func(self, type, stream="stream"): if type.name in BASIC_TYPES: return "%s.%s" %(stream, type.name) if type.name in MAPPED_TYPES: return "%s.%s" %(stream, MAPPED_TYPES[type.name]) if type.name in self.file.structs: return "%s.add" %stream if type.name in EXTERNAL_TYPES: return "%s.add" %stream if type.name == "list": return "lambda x: %s.list(x, %s)" %(stream, self.make_encode_func(type.template[0], stream)) raise ValueError("Unknown type: %s" %type.name) class DocsGenerator: def process(self, file, name): self.file = file self.file.sort_types() self.text = "" self.generate_file(name) return self.text def generate_file(self, name): self.generate_header(name) for proto in self.file.protocols.values(): if not proto.overridden: self.generate_client(proto) for proto in self.file.protocols.values(): if not proto.overridden: self.generate_server(proto) for enum in self.file.enums: self.generate_enum(enum) for struct in self.file.structs.values(): self.generate_struct(struct) def generate_header(self, name): self.text += "\n# Module: nintendo.nex.%s\n\n" %name self.text += "Provides a client and server for the " protocols = [] for proto in self.file.protocols.values(): if not proto.overridden: protocols.append(proto) for i, proto in enumerate(protocols): self.text += "`%s`" %make_class_name(proto.name, "Protocol") if i < len(protocols) - 2: self.text += ", " elif i == len(protocols) - 2: self.text += " and " self.text += ". This page was generated automatically from `%s.proto`.\n\n" %name for proto in self.file.protocols.values(): if not proto.overridden: name = make_class_name(proto.name, "Client") proto = make_class_name(proto.name, "Protocol") self.text += "**class** [%s](#%s)
\n" %(name, name.lower()) self.text += 'The client for the `%s`.\n\n' %proto for proto in self.file.protocols.values(): if not proto.overridden: name = make_class_name(proto.name, "Server") proto = make_class_name(proto.name, "Protocol") self.text += "**class** [%s](#%s)
\n" %(name, name.lower()) self.text += 'The server for the `%s`.\n\n' %proto for enum in self.file.enums: self.text += "**class** [%s](#%s)
\n" %(enum.name, enum.name.lower()) if self.file.enums: self.text += "\n" for struct in self.file.structs.values(): if not struct.parent: parent = "[Structure](common.md)" elif struct.parent == "Data": parent = "[Data](common.md)" elif struct.parent in self.file.structs: parent = "[%s](#%s)" %(struct.parent, struct.parent.lower()) else: raise ValueError("Unknown struct parent: %s" %struct.parent) self.text += "**class** [%s](#%s)(%s)
\n" %(struct.name, struct.name.lower(), parent) if self.file.structs: self.text += "\n" def generate_enum(self, enum): self.text += "## %s\n" %enum.name self.text += "This class defines the following constants:
\n" self.text += '\n' for name, value in enum.values: self.text += "`%s = %i`
\n" %(name, value) self.text += "
\n\n" def generate_struct(self, struct): self.text += "## %s\n" %struct.name self.text += "**def _\\_init__**()
\n" self.text += 'Creates a new `%s` instance.' %struct.name self.text += " Required fields must be filled in manually.\n\n" self.text += "The following fields are defined in this class:
\n" self.generate_struct_body(struct.body) self.text += "\n" def generate_struct_body(self, body): self.text += '\n' for field in body.fields: if isinstance(field, Variable): variable = self.format_variable(field, True) self.text += "%s
\n" %variable elif isinstance(field, Condition): type = { Condition.VERSION: "nex.version", Condition.REVISION: "revision" }[field.type] if field.maximum is None: self.text += f"If `{type}` >= {field.minimum}:
\n" else: self.text += f"If {field.minimum} <= `{type}` < {field.maximum}:
\n" self.generate_struct_body(field.body) self.text += "

\n" def generate_client(self, proto): name = make_class_name(proto.name, "Client") self.text += "## %s\n" %name self.text += "**def _\\_init__**(client: [RMCClient](rmc.md#rmcclient) / [HppClient](hpp.md#hppclient))
\n" self.text += 'Creates a new [`%s`](#%s).\n\n' %(name, name.lower()) for method in proto.methods.values(): if method.supported: self.generate_client_method(method) def generate_client_method(self, method): param = ", ".join([self.format_variable(param, False) for param in method.request.vars]) rval = self.format_return_value(method) self.text += "**async def %s**(%s) -> %s
\n" %(method.name, param, rval) self.text += 'Calls method `%i` on the server.' %method.id if len(method.response.vars) > 1: self.text += " The RMC response has the following attributes:
\n" self.text += '\n' for var in method.response.vars: self.text += "%s
\n" %self.format_variable(var, False) self.text += "
\n" self.text += "
\n\n" def generate_server(self, proto): name = make_class_name(proto.name, "Server") self.text += "## %s\n" %name self.text += "**def _\\_init__**()
\n" self.text += 'Creates a new [`%s`](#%s).\n\n' %(name, name.lower()) self.text += "**async def logout**(client: [RMCClient](rmc.md#rmcclient)) -> None
\n" self.text += 'Called whenever a client is disconnected. May be overridden by a subclass.\n\n' for method in proto.methods.values(): if method.supported: self.generate_server_method(method) def generate_server_method(self, method): param = ["client: [RMCClient](rmc.md#rmcclient)"] param += [self.format_variable(param, False) for param in method.request.vars] param = ", ".join(param) rval = self.format_return_value(method) self.text += "**async def %s**(%s) -> %s
\n" %(method.name, param, rval) self.text += 'Handler for method `%i`.' %method.id self.text += " This method should be overridden by a subclass." if len(method.response.vars) > 1: self.text += " The RMC response must have the following attributes:
\n" self.text += '\n' for var in method.response.vars: self.text += "%s
\n" %self.format_variable(var, False) self.text += "
\n" self.text += "
\n\n" def format_variable(self, var, defaults): text = "%s: %s" %(var.name, self.format_type(var.type)) if defaults: if var.default is not None or var.type.name in ["ResultRange", "NotificationEvent"] or var.type.name in self.file.structs: text += " = %s" %self.format_constant(var.type, var.default) return text def format_type(self, type): if type.name == "bool": return "bool" if type.name == "string": return "str" if type.name in ["float", "double"]: return "float" if type.name in ["buffer", "qbuffer"]: return "bytes" if type.name == "variant": return "object" if type.name == "datetime": return "[DateTime](common.md#datetime)" if type.name == "stationurl": return "[StationURL](common.md#stationurl)" if type.name == "result": return "[Result](common.md#result)" if type.name == "anydata": if type.template: return self.format_type(type.template[0]) return "[Data](common.md)" if type.name == "ResultRange": return "[ResultRange](common.md#resultrange)" if type.name == "NotificationEvent": return "[NotificationEvent](notification.md#notificationevent)" if type.name in self.file.structs: return "[%s](#%s)" %(type.name, type.name.lower()) if type.name in NUMERIC_TYPES: return "int" if type.name == "list": return "list[%s]" %self.format_type(type.template[0]) if type.name == "map": return "dict[%s, %s]" %( self.format_type(type.template[0]), self.format_type(type.template[1]) ) raise ValueError("Unknown type: %s" %type.name) def format_return_value(self, method): if len(method.response.vars) > 1: return "[RMCResponse](common.md)" if len(method.response.vars) == 1: return self.format_type(method.response.vars[0].type) return "None" def format_constant(self, type, value): if type.name in self.file.structs: return "[%s](#%s)()" %(type.name, type.name.lower()) if type.name == "ResultRange": return "[ResultRange](common.md#resultrange)()" if type.name == "NotificationEvent": return "[NotificationEvent](notification.md#notificationevent)()" if type.name in NUMERIC_TYPES + ["bool"]: return str(value) if type.name in ["buffer", "qbuffer"]: return 'b"%s"' %value if type.name in ["string", "stationurl"]: return '"%s"' %value if type.name == "datetime": if value == 0: return "[DateTime](common.md#datetime).never()" elif value == 671076024059: return "[DateTime](common.md#datetime).future()" return "[DateTime](common.md#datetime)(%i)" %value if type.name == "list": entries = [] for entry in value: entries.append(self.format_constant(type.template[0], entry)) return "[%s]" %", ".join(entries) if type.name == "map": items = [] for key, value in value.items(): key = self.format_constant(type.template[0], key) value = self.format_constant(type.template[1], value) items.append("%s: %s" %(key, value)) return "{%s}" %", ".join(items) raise ValueError("Unknown type: %s" %type.name) def process(filename): filepath = os.path.join("nintendo/files/proto", filename) name = os.path.splitext(filename)[0] print("Parsing %s" %filename) with open(filepath) as f: text = f.read() tokens = Tokenizer().process(text) file = Parser().process(tokens) code = CodeGenerator().process(file) docs = DocsGenerator().process(file, name) with open("nintendo/nex/%s.py" %name, "wb") as f: f.write(code.encode()) with open("docs/reference/nex/%s.md" %name, "wb") as f: f.write(docs.encode()) for name in os.listdir("nintendo/files/proto"): process(name) ================================================ FILE: mkdocs.yml ================================================ site_name: NintendoClients theme: readthedocs extra_css: [style.css] ================================================ FILE: nintendo/__init__.py ================================================ ================================================ FILE: nintendo/files/config/3ds.cfg ================================================ prudp.version = 0 prudp.fragment_size = 962 ================================================ FILE: nintendo/files/config/default.cfg ================================================ nex.version = 0 nex.client_version = 0 nex.struct_header = 0 nex.pid_size = 4 prudp.access_key = prudp.version = 2 prudp.minor_version = 4 prudp.supported_functions = 0 prudp.transport = 0 prudp.compression = 0 prudp.encryption = 1 prudp.resend_timeout = 1 prudp.resend_limit = 2 prudp.ping_timeout = 5 prudp.fragment_size = 1300 prudp.max_substream_id = 0 prudp_v0.signature_version = 0 prudp_v0.flags_version = 1 prudp_v0.checksum_version = 1 kerberos.key_size = 32 kerberos.key_derivation = 0 kerberos.ticket_version = 1 ================================================ FILE: nintendo/files/config/friends.cfg ================================================ prudp.version = 0 prudp.fragment_size = 962 prudp_v0.signature_version = 1 kerberos.key_size = 16 ================================================ FILE: nintendo/files/config/switch.cfg ================================================ prudp.minor_version = 5 prudp.transport = 2 prudp.encryption = 0 prudp.resend_timeout = 5 prudp.resend_limit = 0 kerberos.key_derivation = 1 nex.pid_size = 8 nex.struct_header = 1 ================================================ FILE: nintendo/files/proto/aauser.proto ================================================ struct ApplicationInfo { uint64 title_id; uint16 title_version; } protocol AAUser : 123 { method register_application(uint64 title_id) {} method unregister_application(uint64 title_id) {} method set_application_info(list application_info) {} method get_application_info() { list info; } } ================================================ FILE: nintendo/files/proto/account.proto ================================================ struct AccountData { pid pid; string name; uint32 groups; string email; datetime creation_date; datetime effective_date; string not_effective_message; datetime expiry_date; string expired_message; } struct BasicAccountInfo { pid pid; string name; } protocol Account : 25 { method create_account(string name, string key, uint32 groups, string email) { result result; } method delete_account(pid pid) {} method disable_account(pid pid, datetime until, string message) { result result; } method change_password(string new_key) { bool result; } method test_capability(uint32 capability) { bool result; } method get_name(pid pid) { string name; } method get_account_data() { result result; AccountData data; } method get_private_data() { bool result; anydata data; } method get_public_data(pid pid) { bool result; anydata data; } method get_multiple_public_data(list pids) { bool result; list data; } method update_account_name(string name) { result result; } method update_account_email(string email) { result result; } method update_custom_data(anydata public_data, anydata private_data) { result result; } method find_by_name_regex(uint32 groups, string regex, ResultRange range) { list accounts; } method update_account_expiry_date(pid pid, datetime expiry, string message) {} method update_account_effective_date(pid pid, datetime effective_from, string message) {} method update_status(string status) {} method get_status(pid pid) { string status; } method get_last_connection_stats(pid pid) { datetime last_session_login; datetime last_session_logout; datetime current_session_login; } method reset_password() { bool result; } method create_account_with_custom_data( string name, string key, uint32 groups, string email, anydata public_data, anydata private_data ) {} method retrieve_account() { AccountData account_data; anydata public_data; anydata private_data; } method update_account( string key, string email, anydata public_data, anydata private_data ) {} method change_password_by_guest(string name, string email, string key) {} method find_by_name_like(uint32 groups, string like, ResultRange range) { list accounts; } method custom_create_account(string name, string key, uint32 groups, string email, anydata auth_data) { pid pid; } method nintendo_create_account(string name, string key, uint32 groups, string email, anydata auth_data) { pid pid; string pid_hmac; } method lookup_or_create_account(string name, string key, uint32 groups, string email, anydata auth_data) { pid pid; } method disconnect_principal(pid pid) { bool result; } method disconnect_all_principals() { bool result; } } ================================================ FILE: nintendo/files/proto/authentication.proto ================================================ // Defines protocol 10 struct AuthenticationInfo : Data { string token; uint32 ngs_version = 3; uint8 token_type = 1; uint32 server_version = 0; } struct RVConnectionData { stationurl main_station = "prudp:/"; list special_protocols = []; stationurl special_station = "prudp:/"; nex 30500 { revision 1 { datetime server_time = 0; } } } struct ValidateAndRequestTicketParam { uint32 platform = 3; string username; anydata data; bool skip_version_check = false; uint32 nex_version; uint32 client_version; } struct ValidateAndRequestTicketResult { pid pid; buffer ticket; stationurl server_url; datetime server_time; string server_name; string source_key; } protocol Authentication : 10 { method login(string username) { result result; pid pid; buffer ticket; RVConnectionData connection_data; string server_name; } method login_ex(string username, anydata extra_data) { result result; pid pid; buffer ticket; RVConnectionData connection_data; string server_name; } method request_ticket(pid source, pid target) { result result; buffer ticket; } method get_pid(string username) { pid pid; } method get_name(pid pid) { string name; } method login_with_context(anydata login_data) { result result; pid pid; buffer ticket; RVConnectionData connection_data; } } protocol Authentication_NX : 10 { method validate_and_request_ticket(string username) { result result; pid pid; buffer ticket; RVConnectionData connection_data; string server_name; } method validate_and_request_ticket_with_custom_data(string username, anydata extra_data) { result result; pid pid; buffer ticket; RVConnectionData connection_data; string server_name; string source_key; } method request_ticket(pid source, pid target) { result result; buffer ticket; string key; } method get_pid(string username) { pid pid; } method get_name(pid pid) { string name; } method validate_and_request_ticket_with_param(ValidateAndRequestTicketParam param) { ValidateAndRequestTicketResult result; } } ================================================ FILE: nintendo/files/proto/datastore.proto ================================================ struct DataStoreChangeMetaCompareParam { uint32 comparison_flag; string name; DataStorePermission permission; DataStorePermission delete_permission; uint16 period; qbuffer meta_binary; list tags; uint32 referred_count; uint16 data_type; uint8 status; } struct DataStoreChangeMetaParam { uint64 data_id; uint32 modifies_flag; string name; DataStorePermission permission; DataStorePermission delete_permission; uint16 period; qbuffer meta_binary; list tags; uint64 update_password; uint32 referred_count; uint16 data_type; uint8 status; DataStoreChangeMetaCompareParam compare_param; DataStorePersistenceTarget persistence_target; } struct DataStoreChangeMetaParamV1 { uint64 data_id; uint32 modifies_flag; string name; DataStorePermission permission; DataStorePermission delete_permission; uint16 period; qbuffer meta_binary; list tags; uint64 update_password; } struct DataStoreCompletePostParam { uint64 data_id; bool success; } struct DataStoreCompletePostParamV1 { uint32 data_id; bool success; } struct DataStoreCompleteUpdateParam { uint64 data_id; uint32 version; bool success; } struct DataStoreDeleteParam { uint64 data_id; uint64 update_password; } struct DataStoreGetMetaParam { uint64 data_id = 0; DataStorePersistenceTarget persistence_target; uint8 result_option = 0; uint64 access_password = 0; } struct DataStoreGetNewArrivedNotificationsParam { uint64 last_notification_id; uint16 limit; } struct DataStoreGetNotificationUrlParam { string previous_url; } struct DataStoreGetSpecificMetaParam { list data_ids; } struct DataStoreGetSpecificMetaParamV1 { list data_ids; } struct DataStoreKeyValue { string key; string value; } struct DataStoreMetaInfo { uint64 data_id; pid owner_id; uint32 size; string name; uint16 data_type; qbuffer meta_binary; DataStorePermission permission; DataStorePermission delete_permission; datetime create_time; datetime update_time; uint16 period; uint8 status; uint32 referred_count; uint32 refer_data_id; uint32 flag; datetime referred_time; datetime expire_time; list tags; list ratings; } struct DataStoreNotification { uint64 notification_id; uint64 data_id; } struct DataStoreNotificationV1 { uint64 notification_id; uint32 data_id; } struct DataStorePasswordInfo { uint64 data_id; uint64 access_password; uint64 update_password; } struct DataStorePermission { uint8 permission = 3; list recipients = []; } struct DataStorePersistenceInfo { pid owner_id; uint16 slot_id; uint64 data_id; } struct DataStorePersistenceInitParam { uint16 persistence_id = 65535; bool delete_last_object = true; } struct DataStorePersistenceTarget { pid owner_id = 0; uint16 persistence_id = 65535; } struct DataStorePrepareGetParam { uint64 data_id = 0; uint32 lock_id = 0; DataStorePersistenceTarget persistence_target; uint64 access_password = 0; nex 30500 { list extra_data = []; } } struct DataStorePrepareGetParamV1 { uint32 data_id; uint32 lock_id = 0; } struct DataStorePreparePostParam { uint32 size; string name; uint16 data_type; qbuffer meta_binary; DataStorePermission permission; DataStorePermission delete_permission; uint32 flag; uint16 period; uint32 refer_data_id = 0; list tags = []; list rating_init_param = []; DataStorePersistenceInitParam persistence_init_param; nex 30500 { list extra_data; } } struct DataStorePreparePostParamV1 { uint32 size; string name; uint16 data_type = 0; qbuffer meta_binary = ""; DataStorePermission permission; DataStorePermission delete_permission; uint32 flag; uint16 period; uint32 refer_data_id = 0; list tags; list rating_init_param; } struct DataStorePrepareUpdateParam { uint64 data_id; uint32 size; uint64 update_password; list extra_data; } struct DataStoreRateObjectParam { sint32 rating_value; uint64 access_password; } struct DataStoreRatingInfo { sint64 total_value; uint32 count; sint64 initial_value; } struct DataStoreRatingInfoWithSlot { uint8 slot; DataStoreRatingInfo info; } struct DataStoreRatingInitParam { uint8 flag; uint8 internal_flag; uint8 lock_type; sint64 initial_value; sint32 range_min; sint32 range_max; sint8 period_hour; sint16 period_duration; } struct DataStoreRatingInitParamWithSlot { sint8 slot; DataStoreRatingInitParam param; } struct DataStoreRatingLog { bool is_rated; pid pid; sint32 rating_value; datetime lock_expiration_time; } struct DataStoreRatingTarget { uint64 data_id; sint8 slot; } struct DataStoreReqGetAdditionalMeta { pid owner_id; uint16 data_type; uint16 version; qbuffer meta_binary; } struct DataStoreReqGetInfo { string url; list headers; uint32 size; buffer root_ca_cert; nex 30500 { uint64 data_id; } } struct DataStoreReqGetInfoV1 { string url; list headers; uint32 size; buffer root_ca_cert; } struct DataStoreReqGetNotificationUrlInfo { string url; string key; string query; buffer root_ca_cert; } struct DataStoreReqPostInfo { uint64 data_id; string url; list headers; list form; buffer root_ca_cert; } struct DataStoreReqPostInfoV1 { uint32 data_id; string url; list headers; list form; buffer root_ca_cert; } struct DataStoreReqUpdateInfo { uint32 version; string url; list headers; list form; buffer root_ca_cert; } struct DataStoreSearchParam { uint8 search_target = 1; list owner_ids = []; uint8 owner_type = 0; list destination_ids = []; uint16 data_type = 65535; datetime created_after = future; datetime created_before = future; datetime updated_after = future; datetime updated_before = future; uint32 refer_data_id = 0; list tags = []; uint8 result_order_column = 0; uint8 result_order = 0; ResultRange result_range; uint8 result_option = 0; uint32 minimal_rating_frequency = 0; bool use_cache = false; bool total_count_enabled = true; list data_types = []; } struct DataStoreSearchResult { uint32 total_count; list result; uint8 total_count_type; } struct DataStoreSpecificMetaInfo { uint64 data_id; pid owner_id; uint32 size; uint16 data_type; uint32 version; } struct DataStoreSpecificMetaInfoV1 { uint32 data_id; pid owner_id; uint32 size; uint16 data_type; uint16 version; } struct DataStoreTouchObjectParam { uint64 data_id; uint32 lock_id; uint64 access_password; } protocol DataStore : 115 { method prepare_get_object_v1(DataStorePrepareGetParamV1 param) { DataStoreReqGetInfoV1 info; } method prepare_post_object_v1(DataStorePreparePostParamV1 param) { DataStoreReqPostInfoV1 info; } method complete_post_object_v1(DataStoreCompletePostParamV1 param) {} method delete_object(DataStoreDeleteParam param) {} method delete_objects(list param, bool transactional) { list results; } method change_meta_v1(DataStoreChangeMetaParamV1 param) {} method change_metas_v1(list data_ids, list param, bool transactional) { list results; } method get_meta(DataStoreGetMetaParam param) { DataStoreMetaInfo info; } method get_metas(list data_ids, DataStoreGetMetaParam param) { list info; list results; } method prepare_update_object(DataStorePrepareUpdateParam param) { DataStoreReqUpdateInfo info; } method complete_update_object(DataStoreCompleteUpdateParam param) {} method search_object(DataStoreSearchParam param) { DataStoreSearchResult result; } method get_notification_url(DataStoreGetNotificationUrlParam param) { DataStoreReqGetNotificationUrlInfo info; } method get_new_arrived_notifications_v1(DataStoreGetNewArrivedNotificationsParam param) { list result; bool has_next; } method rate_object(DataStoreRatingTarget target, DataStoreRateObjectParam param, bool fetch_ratings) { DataStoreRatingInfo info; } method get_rating(DataStoreRatingTarget target, uint64 access_password) { DataStoreRatingInfo rating; } method get_ratings(list data_ids, uint64 access_password) { list> ratings; list results; } method reset_rating(DataStoreRatingTarget target, uint64 update_password) {} method reset_ratings(list data_ids, bool transactional) { list results; } method get_specific_meta_v1(DataStoreGetSpecificMetaParamV1 param) { list infos; } method post_meta_binary(DataStorePreparePostParam param) { uint64 data_id; } method touch_object(DataStoreTouchObjectParam param) {} method get_rating_with_log(DataStoreRatingTarget target, uint64 access_password) { DataStoreRatingInfo rating; DataStoreRatingLog log; } method prepare_post_object(DataStorePreparePostParam param) { DataStoreReqPostInfo info; } method prepare_get_object(DataStorePrepareGetParam param) { DataStoreReqGetInfo info; } method complete_post_object(DataStoreCompletePostParam param) {} method get_new_arrived_notifications(DataStoreGetNewArrivedNotificationsParam param) { list result; bool has_next; } method get_specific_meta(DataStoreGetSpecificMetaParam param) { list infos; } method get_persistence_info(pid owner_id, uint16 slot_id) { DataStorePersistenceInfo info; } method get_persistence_infos(pid owner_id, list slot_ids) { list infos; list results; } method perpetuate_object(uint16 persistence_slot_id, uint64 data_id, bool delete_last_object) {} method unperpetuate_object(uint16 persistence_slot_id, bool delete_last_object) {} method prepare_get_object_or_meta_binary(DataStorePrepareGetParam param) { DataStoreReqGetInfo get_info; DataStoreReqGetAdditionalMeta additional_meta; } method get_password_info(uint64 data_id) { DataStorePasswordInfo info; } method get_password_infos(list data_ids) { list infos; list results; } method get_metas_multiple_param(list params) { list infos; list results; } method complete_post_objects(list data_ids) {} method change_meta(DataStoreChangeMetaParam param) {} method change_metas(list data_ids, list param, bool transactional) { list results; } method rate_objects(list targets, list param, bool transactional, bool fetch_ratings) { list infos; list results; } method post_meta_binary_with_data_id(uint64 data_id, DataStorePreparePostParam param) {} method post_meta_binaries_with_data_id(list data_ids, list param, bool transactional) { list results; } method rate_object_with_posting( DataStoreRatingTarget target, DataStoreRateObjectParam rate_param, DataStorePreparePostParam post_param, bool fetch_ratings ) { DataStoreRatingInfo info; } method rate_objects_with_posting( list targets, list rate_param, list post_param, bool transactional, bool fetch_ratings ) { list ratings; list results; } method get_object_infos(list data_ids) { list infos; list results; } method search_object_light(DataStoreSearchParam param) { DataStoreSearchResult result; } } ================================================ FILE: nintendo/files/proto/datastore_miitopia_3ds.proto ================================================ import datastore; /*** Enums ***/ enum Gender { MALE = 0, FEMALE = 1, ANY = 2 } enum Category { SINGING = 0, SPORT = 1, ACTING = 2, COMEDY = 3, MUSIC = 4, MARTIAL_ARTS = 5, DANCING = 6, ADVENTURING = 7, FILM_DIRECTING = 8, COOKING = 9, CHATTING = 10, PUBLIC_SPEAKING = 11, CRAFTWORK = 12, DRAWING = 13, STUDYING = 14, WRITING = 15, FASHION = 16, DINING = 17, NOT_TELLING = 18, ANY = 0xFF } /*** Method parameters ***/ struct MiiTubeSearchParam { string name; uint32 page = 0; uint8 category = 0xFF; uint8 gender = 2; uint8 country; uint8 search_type = 0; uint8 result_option = 0; } struct MiiTubeMiiInfo { DataStoreMetaInfo meta_info; uint8 category; uint8 ranking_type; } struct MiiTubeSearchResult { list result; uint32 count; uint32 page; bool has_next; } protocol DataStore_Miitopia3DS : DataStore { method(47) search_mii(MiiTubeSearchParam param) { MiiTubeSearchResult search_result; } } ================================================ FILE: nintendo/files/proto/datastore_smm.proto ================================================ import datastore; protocol DataStore_SMM : DataStore { method(61) get_application_config(uint32 id) { list config; } method(74) get_application_config_string(uint32 id) { list config; } } ================================================ FILE: nintendo/files/proto/datastore_smm2.proto ================================================ import datastore; /*** Enums ***/ enum ClearCondition { NORMAL = 0, COLLECT_COINS = 4116396131, KILL_SKIPSQUEAKS = 4042480826 } enum CourseDifficulty { EASY = 0, STANDARD = 1, EXPERT = 2, SUPER_EXPERT = 3 } enum CourseTag { NONE = 0, STANDARD = 1, PUZZLE_SOLVING = 2, SPEEDRUN = 3, AUTOSCROLL = 4, AUTO_MARIO = 5, SHORT_AND_SWEET = 6, MULTIPLAYER_VS = 7, THEMED = 8, MUSIC = 9 } enum CourseTheme { GROUND = 0, UNDERGROUND = 1, CASTLE = 2, AIRSHIP = 3, UNDERWATER = 4, GHOST_HOUSE = 5, SNOW = 6, DESERT = 7, SKY = 8, FOREST = 9 } enum GameStyle { SMB1 = 0, SMB3 = 1, SMW = 2, NSMBU = 3, SM3DW = 4 } enum MultiplayerStatsKeys { MULTIPLAYER_SCORE = 0, VERSUS_PLAYS = 2, VERSUS_WINS = 3, COOP_PLAYS = 10, COOP_WINS = 11 } enum PlayStatsKeys { PLAYS = 0, CLEARS = 1, ATTEMPTS = 2, DEATHS = 3 } /*** Option flags ***/ enum CourseOption { PLAY_STATS = 1, RATINGS = 2, TIME_STATS = 4, COMMENT_STATS = 8, UNK9 = 0x10, UNK10 = 0x20, UNK8 = 0x40, ONE_SCREEN_THUMBNAIL = 0x80, ENTIRE_THUMBNAIL = 0x100, ALL = 0x1FF } enum EventCourseOption { UNK3 = 1, GET_INFO = 2, BEST_TIME = 8, ONE_SCREEN_THUMBNAIL = 0x10, ENTIRE_THUMBNAIL = 0x20, UNK1 = 0x40, MEDAL_TIME = 0x100, GHOST = 0x200, ALL = 0x3FF } enum UserOption { PLAY_STATS = 1, MAKER_STATS = 2, UNK2 = 4, ENDLESS_MODE = 8, MULTIPLAYER_STATS = 0x10, BADGE_INFO = 0x20, UNK8 = 0x40, UNK9 = 0x80, UNK1 = 0x200, UNK7 = 0x400, UNK11 = 0x1000, UNK13 = 0x2000, UNK15 = 0x8000, ALL = 0xFFFF } /*** Method parameters ***/ struct GetCoursesParam { list data_ids; uint32 option = 0; } struct GetCoursesEventParam {} struct SearchCommentsInOrderParam { uint64 data_id; ResultRange range; } struct GetEventCourseGhostParam { uint64 data_id; uint32 time; uint8 count; } struct GetEventCourseHistogramParam { uint64 data_id; } struct GetUserOrCourseParam { string code; uint32 user_option = 0; uint32 course_option = 0; } struct GetUsersParam { list pids; uint32 option = 0; } struct RegisterUserParam { string name; UnknownStruct1 unk1; qbuffer unk2; uint8 language; string country; string device_id; } struct SearchCoursesPostedByParam { uint32 option = 0; ResultRange range; list pids; } struct SearchCoursesPositiveRatedByParam { uint32 option = 0; uint32 count; uint64 pid; } struct SearchCoursesPlayedByParam { uint32 option = 0; uint32 count; uint64 pid; } struct SearchCoursesEndlessModeParam { uint32 option = 0; uint32 count; uint8 difficulty; } struct SearchCoursesFirstClearParam { uint64 pid; uint32 option = 0; ResultRange range; } struct SearchCoursesBestTimeParam { uint64 pid; uint32 option = 0; ResultRange range; } struct SearchCoursesEventParam { uint32 option = 0; } struct SearchCoursesLatestParam { uint32 option = 0; ResultRange range; } struct SearchUsersPlayedCourseParam { uint64 data_id; uint32 option = 0; uint32 count; } struct SearchUsersClearedCourseParam { uint64 data_id; uint32 option = 0; uint32 count; } struct SearchUsersPositiveRatedCourseParam { uint64 data_id; uint32 option = 0; uint32 count; } struct SearchCoursesPointRankingParam { uint32 option = 0; ResultRange range; uint8 difficulty; list reject_regions = []; } struct SearchUsersUserPointParam { uint32 option = 0; buffer buffer; ResultRange range; } struct SyncUserProfileParam { string username; UnknownStruct1 unk1; qbuffer unk2; uint8 unk3; string country; bool unk4; bool unk5; string unk_guid; uint32 unk6; } struct GetWorldMapParam { list ids; uint32 option = 0; } struct SearchWorldMapPickUpParam { uint32 count; } struct SearchWorldMapPlayedByParam { uint32 unk1; uint32 unk2; } /*** Other structures ***/ struct BadgeInfo { uint16 unk1; uint8 unk2; } struct CommentInfo { uint64 unk1; string unk2; uint8 unk3; uint8 unk4; uint64 unk5; uint16 unk6; uint16 unk7; uint8 unk8; uint8 unk9; uint16 unk10; bool unk11; bool unk12; datetime unk13; qbuffer unk14; string unk15; CommentPictureReqGetInfoWithoutHeaders picture; uint16 unk16; uint8 unk17; } struct DeathPositionInfo { uint64 data_id; uint16 x; uint16 y; bool is_subworld; } struct CommentPictureReqGetInfoWithoutHeaders { string url; uint8 data_type; uint32 unk1; buffer unk2; string filename; } struct CourseInfo { uint64 data_id; string code; pid owner_id; string name; string description; uint8 game_style; uint8 course_theme; datetime upload_time; uint8 difficulty; uint8 tag1; uint8 tag2; uint8 unk1; uint32 clear_condition; uint16 clear_condition_magnitude; uint16 unk2; qbuffer unk3; map play_stats; map ratings; map unk4; CourseTimeStats time_stats; map comment_stats; uint8 unk9; uint8 unk10; uint8 unk11; uint8 unk12; RelationObjectReqGetInfo one_screen_thumbnail; RelationObjectReqGetInfo entire_thumbnail; } struct WorldMapInfo { string id; pid owner_id; qbuffer unk1; RelationObjectReqGetInfo thumbnail; uint8 worlds; uint8 levels; uint8 unk2; datetime unk3; list data_ids; map unk4; uint32 unk5; uint8 unk6; uint8 unk7; } struct CourseTimeStats { pid first_completion; pid world_record_holder; uint32 world_record; uint32 upload_time; } struct EventCourseGhostInfo { RelationObjectReqGetInfo replay_file; uint32 time; pid pid; } struct EventCourseHistogram { uint64 data_id; uint32 unk1; uint32 unk2; uint32 unk3; list values; map medals; uint32 unk4; } struct EventCourseInfo { uint64 data_id; string name; string description; uint8 game_style; uint8 course_theme; bool unk1; bool unk2; datetime upload_time; DataStoreReqGetInfo get_info; map unk3; UnknownStruct6 unk4; uint8 unk5; EventCourseThumbnail one_screen_thumbnail; EventCourseThumbnail entire_thumbnail; revision 1 { datetime end_time; uint8 unk6; uint32 unk7; uint16 unk8; uint16 unk9; uint32 best_time; uint32 unk10; uint32 medal_time; RelationObjectReqGetInfo personal_ghost; } } struct EventCourseStatusInfo { uint64 unk1; bool unk2; datetime unk3; } struct EventCourseThumbnail { string url; list headers; uint32 filesize; buffer root_ca_cert; string filename; } struct RelationObjectReqGetInfo { string url; uint8 data_type; uint32 size; buffer unk; string filename; } struct ReqGetInfoHeadersInfo { list headers; uint32 expiration; } struct SyncUserProfileResult { uint64 pid; string username; UnknownStruct1 unk1; qbuffer unk2; uint8 unk3; string country; uint8 unk4; bool unk5; bool unk6; } struct UserInfo { pid pid; string code; string name; UnknownStruct1 unk1; qbuffer unk2; string country; uint8 region; datetime last_active; bool unk3; bool unk4; bool unk5; map play_stats; map maker_stats; map endless_challenge_high_scores; map multiplayer_stats; map unk7; list badges; map unk8; map unk9; revision 1 { bool unk10; datetime unk11; bool unk12; } revision 2 { UnknownStruct3 unk13; } revision 3 { string unk14; map unk15; bool unk16; } } /*** Unknown structures ***/ struct UnknownStruct1 { uint16 unk1; uint16 unk2; uint16 unk3; uint16 unk4; } struct UnknownStruct3 { bool unk1; datetime unk2; } struct UnknownStruct6 { uint64 unk1; uint32 unk2; } protocol DataStore_SMM2 : DataStore { method(47) register_user(RegisterUserParam param) {} method(48) get_users(GetUsersParam param) { list users; list results; } method(49) sync_user_profile(SyncUserProfileParam param) { SyncUserProfileResult result; } method(50) search_users_user_point(SearchUsersUserPointParam param) { list users; list ranks; bool result; } method(53) search_users_played_course(SearchUsersPlayedCourseParam param) { list users; } method(54) search_users_cleared_course(SearchUsersClearedCourseParam param) { list users; } method(55) search_users_positive_rated_course(SearchUsersPositiveRatedCourseParam param) { list users; } method(59) update_last_login_time() {} method(65) get_username_ng_type() { uint8 unk; } method(70) get_courses(GetCoursesParam param) { list courses; list results; } method(71) search_courses_point_ranking(SearchCoursesPointRankingParam param) { list courses; list ranks; bool result; } method(73) search_courses_latest(SearchCoursesLatestParam param) { list courses; bool result; } method(74) search_courses_posted_by(SearchCoursesPostedByParam param) { list courses; bool result; } method(75) search_courses_positive_rated_by(SearchCoursesPositiveRatedByParam param) { list courses; } method(76) search_courses_played_by(SearchCoursesPlayedByParam param) { list courses; } method(79) search_courses_endless_mode(SearchCoursesEndlessModeParam param) { list courses; } method(80) search_courses_first_clear(SearchCoursesFirstClearParam param) { list courses; bool result; } method(81) search_courses_best_time(SearchCoursesBestTimeParam param) { list courses; bool result; } method(85) get_courses_event(GetCoursesParam param, GetCoursesEventParam dummy) { list courses; list results; } method(86) search_courses_event(SearchCoursesEventParam param) { list courses; } method(94) search_comments_in_order(SearchCommentsInOrderParam param) { list comments; bool result; } method(95) search_comments(uint64 data_id) { list comments; } method(103) get_death_positions(uint64 data_id) { list positions; } method(131) get_user_or_course(GetUserOrCourseParam param) { UserInfo user; CourseInfo course; } method(134) get_req_get_info_headers_info(uint8 type) { ReqGetInfoHeadersInfo result; } method(153) get_event_course_stamp() { uint32 stamps; } method(154) get_event_course_status() { EventCourseStatusInfo info; } method(156) get_event_course_histogram(GetEventCourseHistogramParam param) { EventCourseHistogram histogram; } method(157) get_event_course_ghost(GetEventCourseGhostParam param) { list ghosts; } method(160) get_world_map(GetWorldMapParam param) { list maps; list results; } method(162) search_world_map_pick_up(SearchWorldMapPickUpParam param) { list maps; } } ================================================ FILE: nintendo/files/proto/debug.proto ================================================ struct ApiCall { string name; datetime time; pid pid; } struct ApiCallSummary { string name; uint32 limit_exceeded; uint32 duration; uint32 limit; datetime start; uint32 limit_exceeded_count; uint32 total_count; } protocol Debug : 116 { method enable_api_recorder() {} method disable_api_recorder() {} method is_api_recorder_enabled() { bool enabled; } method get_api_calls(list pids, datetime start, datetime end) { list calls; } method set_exclude_joined_matchmake_session; method get_exclude_joined_matchmake_session; method get_api_call_summary(pid pid, datetime start, datetime end, bool only_limit_exceeded) { list summaries; } } ================================================ FILE: nintendo/files/proto/friends.proto ================================================ // 3DS structures struct AccountExtraInfo { uint64 local_friend_code; uint32 move_count; string token; } struct FriendComment : Data { uint32 pid; string comment; datetime modified_at; } struct FriendKey { uint32 unk1; datetime unk2; } struct FriendMii : Data { pid pid; Mii mii; datetime modified_at; } struct FriendMiiList : Data { uint32 unk1; MiiList mii; datetime unk2; } struct FriendPersistentInfo : Data { pid pid; uint8 region; uint8 country; uint8 area; uint8 language; uint8 platform; GameKey game_key; string message; datetime message_updated; datetime friended; datetime last_online; } struct FriendPicture : Data { uint32 unk; buffer data; datetime datetime; } struct FriendPresence : Data { pid pid; NintendoPresence presence; } struct FriendRelationship : Data { pid pid; uint64 friend_code; uint8 is_complete; } struct GameKey : Data { uint64 title_id = 0; uint16 title_version = 0; } struct Mii : Data { string name; bool unk1; uint8 unk2; buffer mii_data; } struct MiiList : Data { string unk1; bool unk2; uint8 unk3; list mii_datas; } struct MyProfile : Data { uint8 region; uint8 country; uint8 area; uint8 language; uint8 platform; uint64 local_friend_code_seed; string mac_address; string serial_number; } struct NintendoPresence : Data { uint32 changed_bit_flag; GameKey game_key; string game_mode_description; uint32 join_availability_flag; uint8 matchmake_system_type; uint32 join_game_id; uint32 join_game_mode; pid owner_pid; uint32 join_group_id; buffer application_data; } struct PlayedGame : Data { GameKey game_key; datetime datetime; } // Wii U structures struct BlacklistedPrincipal : Data { PrincipalBasicInfo principal_info; GameKey game_key; datetime since; } struct Comment : Data { uint8 unk; string text; datetime changed; } struct FriendInfo : Data { NNAInfo nna_info; NintendoPresenceV2 presence; Comment comment; datetime befriended; datetime last_online; uint64 unk; } struct FriendRequest : Data { PrincipalBasicInfo principal_info; FriendRequestMessage message; datetime sent; } struct FriendRequestMessage : Data { uint64 friend_request_id; uint8 unk1; uint8 unk2; string message; uint8 unk3; string string; GameKey game_key; datetime datetime; datetime expires; } struct MiiV2 : Data { string name; uint8 unk1 = 0; uint8 unk2 = 0; buffer data; datetime datetime = 0; } struct NNAInfo : Data { PrincipalBasicInfo principal_info; uint8 unk1 = 94; uint8 unk2 = 11; } struct NintendoCreateAccountData : Data { NNAInfo info; string token; datetime birthday; uint64 unk; } struct NintendoPresenceV2 : Data { uint32 flags = 0; bool is_online = false; GameKey game_key; uint8 unk1 = 0; string message = ""; uint32 unk2 = 0; uint8 unk3 = 0; uint32 game_server_id = 0; uint32 unk4 = 0; uint32 pid = 0; uint32 gathering_id = 0; buffer application_data = ""; uint8 unk5 = 3; uint8 unk6 = 3; uint8 unk7 = 3; } struct PersistentNotification : Data { uint64 unk1; uint32 unk2; uint32 unk3; uint32 unk4; string string; } struct PrincipalBasicInfo : Data { pid pid; string nnid; MiiV2 mii; uint8 unk = 2; } struct PrincipalPreference : Data { bool show_online_status; bool show_current_title; bool block_friend_requests; } struct PrincipalRequestBlockSetting : Data { uint32 pid; bool blocked; } protocol Friends_V1 : 101 { method update_profile(MyProfile profile_data) {} method update_mii(Mii mii) {} method update_mii_list(MiiList mii_list) {} method update_played_games(list played_games) {} method update_preference(bool show_online_status, bool show_current_title, bool block_friend_requests) {} method get_friend_mii(list friends) { list miis; } method get_friend_mii_list(list friends) { list mii_lists; } method is_active_game(list unk1, GameKey game_key) { list unk; } method get_principal_id_by_local_friend_code(uint64 unk1, list unk2) { list friend_relationships; } method get_friend_relationships(list principal_ids) { list friend_relationships; } method add_friend_by_principal_id(uint64 friend_seed, pid pid) { FriendRelationship friend_relationship; } method add_friend_by_principal_ids(uint64 unk, list pids) { list friend_relationships; } method remove_friend_by_local_friend_code(uint64 friend_code) {} method remove_friend_by_principal_id(pid pid) {} method get_all_friends() { list friend_relationships; } method update_black_list(list unk) {} method sync_friend(uint64 friend_seed, list principal_ids, list unk) { list friend_list; } method update_presence(NintendoPresence presence_info, bool unk) {} method update_favorite_game_key(GameKey game_key) {} method update_comment(string comment) {} method update_picture(uint32 unk, buffer picture) {} method get_friend_presence(list principal_ids) { list friend_presence_list; } method get_friend_comment(list friends) { list comments; } method get_friend_picture(list principal_ids) { list friend_pictures; } method get_friend_persistent_info(list principal_ids) { list persistent_infos; } method send_invitation(list unk) {} } protocol Friends_V2 : 102 { method update_and_get_all_information(NNAInfo nna_info, NintendoPresenceV2 presence, datetime birthday) { PrincipalPreference principal_preference; Comment comment; list friends; list sent_requests; list received_requests; list blacklist; bool unk1; list notifications; bool unk2; } method add_friend(pid pid) { FriendRequest request; FriendInfo info; } method add_friend_by_name(string name) { FriendRequest request; FriendInfo info; } method remove_friend(pid pid) {} method add_friend_request( uint32 unk1, uint8 unk2, string unk3, uint8 unk4, string unk5, GameKey game_key, datetime unk6 ) { FriendRequest request; FriendInfo info; } method cancel_friend_request(uint64 id) {} method accept_friend_request(uint64 id) { FriendInfo info; } method delete_friend_request(uint64 id) {} method deny_friend_request(uint64 id) { BlacklistedPrincipal blacklist; } method mark_friend_requests_as_received(list ids) {} method add_black_list(BlacklistedPrincipal principal) { BlacklistedPrincipal principal; } method remove_black_list(pid pid) {} method update_presence(NintendoPresenceV2 presence) {} method update_mii(MiiV2 mii) { datetime unk; } method update_comment(Comment comment) { datetime unk; } method update_preference(PrincipalPreference preference) {} method get_basic_info(list pids) { list info; } method delete_persistent_notification(list notifications) {} method check_setting_status() { uint8 unk; } method get_request_block_settings(list unk) { list settings; } } ================================================ FILE: nintendo/files/proto/health.proto ================================================ protocol Health : 18 { method ping_daemon() { bool result; } method ping_database() { bool result; } method run_sanity_check() { bool result; } method fix_sanity_errors() { bool result; } } ================================================ FILE: nintendo/files/proto/matchmaking.proto ================================================ enum MatchmakeSystem { GLOBAL = 1, FRIENDS = 2 } struct Gathering { uint32 id = 0; pid owner = 0; pid host = 0; uint16 min_participants = 0; uint16 max_participants = 0; uint32 participation_policy = 1; uint32 policy_argument = 0; uint32 flags = 512; uint32 state = 0; string description = ""; } struct GatheringURLs { uint32 gid; list urls; } struct GatheringStats { pid pid; uint32 flags; list values; } struct Invitation { uint32 gid; uint32 guest; string message; } struct ParticipantDetails { pid pid; string name; string message; uint16 participants; } struct DeletionEntry { uint32 gid; pid pid; uint32 reason; } struct MatchmakeParam { map param = {}; } struct MatchmakeSessionSearchCriteria { list attribs = ["", "", "", "", "", ""]; string game_mode = ""; string min_participants = ""; string max_participants = ""; string matchmake_system = ""; bool vacant_only = true; bool exclude_locked = true; bool exclude_non_host_pid = false; uint32 selection_method = 0; nex 30500 { uint16 vacant_participants = 1; } nex 40000 { MatchmakeParam param; bool exclude_user_password = false; bool exclude_system_password = false; uint32 refer_gid = 0; string codeword = ""; ResultRange range; } } struct MatchmakeSession : Gathering { uint32 game_mode = 0; list attribs = [0, 0, 0, 0, 0, 0]; bool open_participation = true; uint32 matchmake_system = 0; buffer application_data = ""; uint32 num_participants = 0; nex 30000 - 40000 { nex 30500 { uint8 progress_score = 100; } nex 30000 { buffer session_key = ""; } nex 30500 { uint32 option = 0; } nex 30600 { revision 1 { MatchmakeParam param; datetime started_time = 0; } } nex 30700 { revision 2 { string user_password = ""; } } nex 30800 { revision 3 { uint32 refer_gid = 0; bool user_password_enabled = false; bool system_password_enabled = false; } } } nex 40000 { uint8 progress_score = 100; buffer session_key = ""; uint32 option = 0; MatchmakeParam param; datetime started_time = 0; string user_password = ""; uint32 refer_gid = 0; bool user_password_enabled = false; bool system_password_enabled = false; string codeword = ""; } } struct MatchmakeBlockListParam { uint32 options = 0; } struct CreateMatchmakeSessionParam { MatchmakeSession session; list additional_participants; uint32 gid_for_participation_check; uint32 options; string join_message; uint16 num_participants; } struct JoinMatchmakeSessionParam { uint32 gid; list participants; uint32 gid_for_participation_check; uint32 options; uint8 behavior; string user_password; string system_password; string join_message; uint16 num_participants; uint16 extra_participants; MatchmakeBlockListParam block_list; } struct UpdateMatchmakeSessionParam { uint32 gid; uint32 modification_flags; list attributes; bool open_participation; buffer application_buffer; uint8 progress_score; MatchmakeParam param; datetime started_time; string user_password; uint32 game_mode; string description; uint16 min_participants; uint16 max_participants; uint32 matchmake_system; uint32 participation_policy; uint32 policy_argument; string codeword; } struct AutoMatchmakeParam { MatchmakeSession session; list participants; uint32 gid_for_participation_check; uint32 options; string join_message; uint16 num_participants; list search_criteria; list target_gids; MatchmakeBlockListParam block_list; } struct FindMatchmakeSessionByParticipantParam { list pids; uint32 options; MatchmakeBlockListParam block_list; } struct FindMatchmakeSessionByParticipantResult { pid pid; MatchmakeSession session; } struct PersistentGathering : Gathering { uint32 type; string password; list attribs; buffer application_buffer; datetime participation_start; datetime participation_end; uint32 matchmake_session_count; uint32 num_participants; } struct SimpleCommunity { uint32 gid; uint32 matchmake_session_count; } struct PlayingSession { pid pid; anydata gathering; } struct SimplePlayingSession { pid pid; uint32 gid; uint32 game_mode; uint32 attribute; } /*** MatchmakeReferee structures ***/ struct MatchmakeRefereeRound { uint64 id; uint32 gid; uint32 state; uint32 personal_data_category; list results; } struct MatchmakeRefereeStartRoundParam { uint32 personal_data_category; uint32 gid; list pids; } struct MatchmakeRefereeEndRoundParam { uint64 round_id; list results; } struct MatchmakeRefereePersonalRoundResult { pid pid; uint32 personal_round_result_flag; uint32 round_win_loss; sint32 rating_change; qbuffer buffer; } struct MatchmakeRefereeStats { uint64 unique_id; uint32 category; pid pid; uint32 recent_disconnection; uint32 recent_violation; uint32 recent_mismatch; uint32 recent_win; uint32 recent_loss; uint32 recent_draw; uint32 total_disconnect; uint32 total_violation; uint32 total_mismatch; uint32 total_win; uint32 total_loss; uint32 total_draw; uint32 rating_value; } struct MatchmakeRefereeStatsTarget { pid pid; uint32 category; } struct MatchmakeRefereeStatsInitParam { uint32 category; uint32 initial_rating; } protocol MatchMaking : 21 { method register_gathering(anydata gathering) { uint32 gid; } method unregister_gathering(uint32 gid) { bool result; } method unregister_gatherings(list gids) { bool result; } method update_gathering(anydata gathering) { bool result; } method invite(uint32 gid, list pids, string message) { bool result; } method accept_invitation(uint32 gid, string message) { bool result; } method decline_invitation(uint32 gid, string message) { bool result; } method cancel_invitation(uint32 gid, list pids, string message) { bool result; } method get_invitations_sent(uint32 gid) { list invitations; } method get_invitations_received() { list invitations; } method participate(uint32 gid, string message) { bool result; } method cancel_participation(uint32 gid, string message) { bool result; } method get_participants(uint32 gid) { list participants; } method add_participants(uint32 gid, list pids, string message) { bool result; } method get_detailed_participants(uint32 gid) { list details; } method get_participants_urls(uint32 gid) { list urls; } method find_by_type(string type, ResultRange range) { list> gatherings; } method find_by_description(string description, ResultRange range) { list> gatherings; } method find_by_description_regex(string regex, ResultRange range) { list> gatherings; } method find_by_id(list ids) { list> gatherings; } method find_by_single_id(uint32 gid) { bool result; anydata gathering; } method find_by_owner(pid owner, ResultRange range) { list> gatherings; } method find_by_participants(list pids) { list> gatherings; } method find_invitations(ResultRange range) { list> gatherings; } method find_by_sql_query(string query, ResultRange range) { list> gatherings; } method launch_session(uint32 gid, string url) { bool result; } method update_session_url(uint32 gid, string url) { bool result; } method get_session_url(uint32 gid) { bool result; string url; } method get_state(uint32 gid) { bool result; uint32 state; } method set_state(uint32 gid, uint32 state) { bool result; } method report_stats(uint32 gid, list stats) { bool result; } method get_stats(uint32 gid, list pids, list columns) { bool result; list stats; } method delete_gathering(uint32 gid) { bool result; } method get_pending_deletions(uint32 reason, ResultRange range) { bool result; list deletions; } method delete_from_deletions(list deletions) { bool result; } method migrate_gathering_ownership_v1(uint32 gid, list potential_owners) { bool result; } method find_by_description_like(string description, ResultRange range) { list> gatherings; } method register_local_url(uint32 gid, stationurl url) {} method register_local_urls(uint32 gid, list urls) {} method update_session_host_v1(uint32 gid) {} method get_session_urls(uint32 gid) { list urls; } method update_session_host(uint32 gid, bool is_migrate_owner) {} method update_gathering_ownership(uint32 gid, bool participants_only) { bool result; } method migrate_gathering_ownership(uint32 gid, list potential_owners, bool participants_only) {} } protocol MatchMaking_Ext : 50 { method end_participation(uint32 gid, string message) { bool result; } method get_participants(uint32 gid, bool only_active) { list participants; } method get_detailed_participants(uint32 gid, bool only_active) { list details; } method get_participants_urls(list gids) { list urls; } method get_gathering_relations(uint32 id, string descr) { string result; } method delete_from_deletions(list deletions, pid pid) {} } protocol MatchmakeExtension : 109 { method close_participation(uint32 gid) {} method open_participation(uint32 gid) {} method auto_matchmake_postpone(anydata gathering, string message) { anydata gathering; } method browse_matchmake_session(MatchmakeSessionSearchCriteria search_criteria, ResultRange range) { list> gatherings; } method browse_matchmake_session_with_host_urls(MatchmakeSessionSearchCriteria search_criteria, ResultRange range) { list> gatherings; list urls; } method create_matchmake_session(anydata gathering, string description, uint16 num_participants) { uint32 gid; buffer session_key; } method join_matchmake_session(uint32 gid, string message) { buffer session_key; } method modify_current_game_attribute(uint32 gid, uint32 attrib, uint32 value) {} method update_notification_data(uint32 type, pid param1, pid param2, string param3) {} method get_friend_notification_data(sint32 type) { list notifications; } method update_application_buffer(uint32 gid, buffer buffer) {} method update_matchmake_session_attribute(uint32 gid, list attribs) {} method get_friend_notification_data_list(list types) { list notifications; } method update_matchmake_session(anydata gathering) {} method auto_matchmake_with_search_criteria_postpone( list search_criteria, anydata gathering, string message ) { anydata gathering; } method get_playing_session(list pids) { list sessions; } method create_community(PersistentGathering community, string message) { uint32 gid; } method update_community(PersistentGathering community) {} method join_community(uint32 gid, string message, string password) {} method find_community_by_gathering_id(list gids) { list communities; } method find_official_community(bool available_only, ResultRange range) { list communities; } method find_community_by_participant(pid pid, ResultRange range) { list communities; } method update_privacy_setting(bool online_status, bool community_participation) {} method get_my_block_list() { list pids; } method add_to_block_list(list pids) {} method remove_from_block_list(list pids) {} method clear_my_block_list() {} method report_violation(pid pid, string username, uint32 violation_code) {} method is_violation_user() { bool flag; uint32 score; } method join_matchmake_session_ex(uint32 gid, string gmessage, bool ignore_block_list, uint16 num_participants) { buffer session_key; } method get_simple_playing_session(list pids, bool include_login_user) { list session; } method get_simple_community(list gids) { list communities; } method auto_matchmake_with_gathering_id_postpone(list gids, anydata gathering, string message) { anydata joined_gathering; } method update_progress_score(uint32 gid, uint8 score) {} method debug_notify_event(pid pid, uint32 main_type, uint32 sub_type, uint64 param1, uint64 param2, string param3) {} method generate_matchmake_session_system_password(uint32 gid) { string password; } method clear_matchmake_session_system_password(uint32 gid) {} method create_matchmake_session_with_param(CreateMatchmakeSessionParam param) { MatchmakeSession session; } method join_matchmake_session_with_param(JoinMatchmakeSessionParam param) { MatchmakeSession session; } method auto_matchmake_with_param_postpone(AutoMatchmakeParam param) { MatchmakeSession session; } method find_matchmake_session_by_gathering_id_detail(uint32 gid) { MatchmakeSession session; } method browse_matchmake_session_no_holder(MatchmakeSessionSearchCriteria search_criteria, ResultRange range) { list sessions; } method browse_matchmake_session_with_host_urls_no_holder(MatchmakeSessionSearchCriteria search_criteria, ResultRange range) { list sessions; list urls; } method update_matchmake_session_part(UpdateMatchmakeSessionParam param) {} method request_matchmaking(AutoMatchmakeParam param) { uint64 request_id; } method withdraw_matchmaking(uint64 request_id) {} method withdraw_matchmaking_all() {} method find_matchmake_session_by_gathering_id(list gids) { list sessions; } method find_matchmake_session_by_single_gathering_id(uint32 gid) { MatchmakeSession session; } method find_matchmake_session_by_owner(pid pid, ResultRange range) { list sessions; } method find_matchmake_session_by_participant(FindMatchmakeSessionByParticipantParam param) { list result; } method browse_matchmake_session_no_holder_no_result_range( MatchmakeSessionSearchCriteria search_criteria ) { list sessions; } method browse_matchmake_session_with_host_urls_no_holder_no_result_range( MatchmakeSessionSearchCriteria search_criteria ) { list sessions; list urls; } } protocol MatchmakeReferee : 120 { method start_round(MatchmakeRefereeStartRoundParam param) { uint64 round_id; } method get_start_round_param(uint64 round_id) { MatchmakeRefereeStartRoundParam param; } method end_round(MatchmakeRefereeEndRoundParam param) {} method end_round_without_report(uint64 round_id) {} method get_round_participants(uint64 round_id) { list pids; } method get_not_summarized_round() { list rounds; } method get_round(uint64 round) { MatchmakeRefereeRound round; } method get_stats_primary(MatchmakeRefereeStatsTarget target) { MatchmakeRefereeStats stats; } method get_stats_primaries(list targets) { list stats; list results; } method get_stats_all(MatchmakeRefereeStatsTarget target) { list stats; } method create_stats(MatchmakeRefereeStatsInitParam param) { MatchmakeRefereeStats stats; } method get_or_create_stats(MatchmakeRefereeStatsInitParam param) { MatchmakeRefereeStats stats; } method reset_stats() {} } ================================================ FILE: nintendo/files/proto/matchmaking_eagle.proto ================================================ import matchmaking; struct MatchmakeRefereeStartRoundParam { uint32 personal_data_category; uint32 gid; list pids; uint8 report_summary_mode; uint32 event_id; } struct MatchmakeRefereePersonalRoundResult { pid pid; uint32 personal_round_result_flag; uint32 round_win_loss; sint32 rating_value_change; qbuffer buffer; uint8 report_summary_mode; uint32 event_id; } protocol MatchmakeReferee : 120 { method start_round(MatchmakeRefereeStartRoundParam param) { uint64 round_id; } method get_start_round_param(uint64 round_id) { MatchmakeRefereeStartRoundParam param; } method end_round(MatchmakeRefereeEndRoundParam param) {} method end_round_with_partial_report(MatchmakeRefereeEndRoundParam param) {} method end_round_without_report(uint64 round_id) {} method get_round_participants(uint64 round_id) { list pids; } method get_not_summarized_round() { list rounds; } method get_round(uint64 round) { MatchmakeRefereeRound round; } method get_stats_primary(MatchmakeRefereeStatsTarget target) { MatchmakeRefereeStats stats; } method get_stats_primaries(list targets) { list stats; list results; } method get_stats_all(MatchmakeRefereeStatsTarget target) { list stats; } method create_stats(MatchmakeRefereeStatsInitParam param) { MatchmakeRefereeStats stats; } method get_or_create_stats(MatchmakeRefereeStatsInitParam param) { MatchmakeRefereeStats stats; } method reset_stats() {} method get_event_point; method reset_event_point; } ================================================ FILE: nintendo/files/proto/matchmaking_mhxx.proto ================================================ import matchmaking; struct FriendUserParam { string name; } struct FriendUserInfo { uint64 pid; string name; uint32 presence; } protocol MatchmakeExtension_MHXX : MatchmakeExtension { method(54) update_friend_user_profile(FriendUserParam param) {} method get_friend_user_profiles(list pids) { list infos; } method get_friends() { list infos; } method add_friends(list pids) {} method remove_friend(uint64 pid) {} method find_community_by_owner(uint64 id, ResultRange range) { list lst_community; } } ================================================ FILE: nintendo/files/proto/matchmaking_mk8.proto ================================================ import matchmaking; struct SimpleSearchObject { uint32 id; pid owner; list attributes; qbuffer metadata; uint32 community_id; string community_code; SimpleSearchDateTimeAttribute datetime; } struct SimpleSearchDateTimeAttribute { uint32 unk1; uint32 unk2; uint32 unk3; uint32 unk4; datetime start_time; datetime end_time; } struct SimpleSearchParam { uint32 unk1; pid unk2; list conditions; string unk3; ResultRange range; datetime unk4; } struct SimpleSearchCondition { uint32 value; uint32 operator; } protocol MatchmakeExtension_MK8 : MatchmakeExtension { method(36) create_simple_search_object(SimpleSearchObject object) { uint32 id; } method update_simple_search_object(uint32 id, SimpleSearchObject object) {} method delete_simple_search_object(uint32 id) {} method search_simple_search_object(SimpleSearchParam param) { list objects; } method join_matchmake_session_with_extra_participants(uint32 gid, string join_message, bool ignore_blacklist, uint16 participation_count, uint32 extra_participants) { buffer session_key; } method search_simple_search_object_by_object_ids(list ids) { list objects; } } ================================================ FILE: nintendo/files/proto/matchmaking_mk8d.proto ================================================ import matchmaking; enum SimpleSearchConditionOperator { ANY = 0, EQUAL = 1, GREATER_THAN = 2, LESS_THAN = 3, GREATER_THAN_OR_EQUAL = 4, LESS_THAN_OR_EQUAL = 5 } struct SimpleSearchObject { uint32 id; pid owner; list attributes; qbuffer metadata; uint32 community_id; string community_code; SimpleSearchDateTimeAttribute datetime; nex 40000 { revision 1 { uint32 liveliness_rate; datetime liveliness_update_time; } } } struct SimpleSearchDateTimeAttribute { uint32 start_daytime; uint32 end_daytime; uint32 start_time; uint32 end_time; datetime start_datetime; datetime end_datetime; } struct SimpleSearchParam { uint32 id = 0; pid owner = 0; list conditions = []; string community_code = ""; ResultRange range; datetime datetime = never; } struct SimpleSearchCondition { uint32 value; uint32 operator; } protocol MatchmakeExtension_MK8D : MatchmakeExtension { method(54) create_simple_search_object(SimpleSearchObject object) { uint32 id; } method update_simple_search_object(uint32 id, SimpleSearchObject object) {} method delete_simple_search_object(uint32 id) {} method search_simple_search_object(SimpleSearchParam param) { list objects; } method search_simple_search_object_by_object_ids(list ids) { list objects; } method join_matchmake_session_with_extra_participants(uint32 gid, string join_message, bool ignore_blacklist, uint16 participation_count, uint32 extra_participants) { buffer session_key; } method custom_get_simple_playing_session; method create_competition(SimpleSearchObject competition) { SimpleSearchObject competition; } method delete_competition(uint32 id) {} method register_favorite_competition(uint32 id) {} method unregister_favorite_competition(uint32 id) {} method get_favorite_competition() { list competitions; } method get_team_participants; method find_community_by_owner; } ================================================ FILE: nintendo/files/proto/messaging.proto ================================================ enum RecipientType { PRINCIPAL = 1, GATHERING = 2 } struct MessageRecipient { uint32 type; pid pid; uint32 gid; } struct UserMessage : Data { uint32 id; uint32 parent_id; pid sender; datetime reception_time; uint32 life_time; uint32 flags; string subject; string sender_name; MessageRecipient recipient; } struct TextMessage : UserMessage { string body; } struct BinaryMessage : UserMessage { qbuffer body; } protocol Messaging : 23 { method deliver_message(anydata message) { anydata modified_message; list sandbox_node_ids; list participants; } method get_number_of_messages(MessageRecipient recipient) { uint32 number; } method get_message_headers(MessageRecipient recipient, ResultRange range) { list headers; } method retrieve_all_messages_within_range(MessageRecipient recipient, ResultRange range) { list messages; } method retrieve_messages(MessageRecipient recipient, list message_ids, bool leave_on_server) { list messages; } method delete_messages(MessageRecipient recipient, list message_ids) {} method delete_all_messages(MessageRecipient recipient) { uint32 number_deleted; } } protocol MessageDelivery : 27 { set noresponse; method deliver_message(anydata message) {} } ================================================ FILE: nintendo/files/proto/monitoring.proto ================================================ protocol Monitoring : 19 { method ping_daemon() { bool result; } method get_cluster_members() { list members; } } ================================================ FILE: nintendo/files/proto/nattraversal.proto ================================================ protocol NATTraversal : 3 { method request_probe_initiation(list target_urls) {} method initiate_probe(stationurl station_to_probe) {} method request_probe_initiation_ext( list target_urls, stationurl station_to_probe ) {} method report_nat_traversal_result(uint32 cid, bool result) {} method report_nat_properties(uint32 natm, uint32 natf, uint32 rtt) {} method get_relay_signature_key() { sint32 mode; datetime time; string address; uint16 port; sint32 address_type; uint32 game_server_id; } method report_nat_traversal_result_detail(uint32 cid, bool result, sint32 detail, uint32 rtt) {} } ================================================ FILE: nintendo/files/proto/nintendonotification.proto ================================================ struct u8KeyValue : Data { uint8 key; uint8 value; } struct u32KeyValue : Data { uint8 key; uint32 value; } struct u64KeyValue : Data { uint8 key; uint64 value; } struct StringKeyValue : Data { uint8 key; string value; } enum NintendoNotificationType { LOGOUT = 10, PRESENCE_CHANGE = 24, UNFRIENDED = 26, FRIENDED = 30, STATUS_CHANGE = 33 } struct NintendoNotificationEvent { uint32 type; pid pid; anydata data; } struct NintendoNotificationEventGeneral : Data { uint32 param1; uint64 param2; uint64 param3; string text; } struct NintendoNotificationEventKeyValue : Data { list u8; list u32; list u64; list string; } struct NintendoNotificationEventProfile : Data { uint8 region; uint8 country; uint8 area; uint8 language; uint8 platform; } protocol NintendoNotification : 100 { set noresponse; method process_nintendo_notification_event(NintendoNotificationEvent event) {} method process_nintendo_notification_event_alt(NintendoNotificationEvent event) {} } ================================================ FILE: nintendo/files/proto/notification.proto ================================================ struct NotificationEvent { pid pid; uint32 type; pid param1 = 0; pid param2 = 0; string text = ""; nex 30500 { pid param3 = 0; } nex 40000 { revision 1 { map map = {}; } } } protocol Notification : 14 { set noresponse; method process_notification_event(NotificationEvent event) {} } ================================================ FILE: nintendo/files/proto/ranking.proto ================================================ enum RankingOrderCalc { STANDARD = 0, ORDINAL = 1 } enum RankingMode { GLOBAL = 0, GLOBAL_AROUND_SELF = 1, SELF = 4 } enum RankingStatFlags { RANKING_COUNT = 1, TOTAL_SCORE = 2, LOWEST_SCORE = 4, HIGHEST_SCORE = 8, AVERAGE_SCORE = 16, ALL = 31 } struct RankingOrderParam { uint8 order_calc = 0; uint8 group_index = 255; uint8 group_num = 0; uint8 time_scope = 2; uint32 offset = 0; uint8 count = 10; } struct RankingRankData { pid pid; uint64 unique_id; uint32 rank; uint32 category; uint32 score; list groups; uint64 param; buffer common_data; nex 40000 { datetime update_time; } } struct RankingResult { list data; uint32 total; datetime since_time; } struct RankingCachedResult : RankingResult { datetime created_time; datetime expired_time; uint8 max_length; } struct RankingStats { list stats; } struct RankingScoreData { uint32 category; uint32 score; uint8 order; uint8 update_mode; list groups; uint64 param; } struct RankingChangeAttributesParam { uint8 flags; list groups; uint64 param; } protocol Ranking : 112 { method upload_score(RankingScoreData score_data, uint64 unique_id) {} method delete_score(uint32 category, uint64 unique_id) {} method delete_all_scores(uint64 unique_id) {} method upload_common_data(buffer common_data, uint64 unique_id) {} method delete_common_data(uint64 unique_id) {} method get_common_data(uint64 unique_id) { buffer data; } method change_attributes(uint32 category, RankingChangeAttributesParam param, uint64 unique_id) {} method change_all_attributes(RankingChangeAttributesParam param, uint64 unique_id) {} method get_ranking(uint8 mode, uint32 category, RankingOrderParam order, uint64 unique_id, pid pid) { RankingResult result; } method get_approx_order(uint32 category, RankingOrderParam order, uint32 score, uint64 unique_id, pid pid) { uint32 order; } method get_stats(uint32 category, RankingOrderParam order, uint32 flags) { RankingStats stats; } method get_ranking_by_pid_list(list pids, uint8 mode, uint32 category, RankingOrderParam order, uint64 unique_id) { RankingResult result; } method get_ranking_by_unique_id_list(list ids, uint8 mode, uint32 category, RankingOrderParam order, uint64 unique_id) { RankingResult result; } method get_cached_topx_ranking(uint32 category, RankingOrderParam order) { RankingCachedResult result; } method get_cached_topx_rankings(list categories, list order) { list results; } } ================================================ FILE: nintendo/files/proto/ranking2.proto ================================================ enum RankingMode { GLOBAL_AROUND_SELF = 1, GLOBAL = 2, FRIENDS = 3 } struct Ranking2CategorySetting { uint32 min_score; uint32 max_score; uint32 lowest_rank; uint16 reset_month; uint8 reset_day; uint8 reset_hour; uint8 reset_mode; uint8 max_seasons_to_go_back; bool score_order; } struct Ranking2ChartInfo { datetime create_time; uint32 index; uint32 category; sint32 season; uint8 bins_size; uint8 sampling_rate; bool score_order; uint32 estimate_length; uint32 estimate_highest_score; uint32 estimate_lowest_score; uint32 estimate_median_score; double estimate_average_score; uint32 highest_bins_score; uint32 lowest_bins_score; uint32 bins_width; uint32 attribute1; uint32 attribute2; list quantities; } struct Ranking2ChartInfoInput { uint32 chart_index; uint8 seasons_to_go_back; } struct Ranking2CommonData { string username; qbuffer mii; qbuffer binary_data; } struct Ranking2EstimateScoreRankInput { uint32 category; uint8 seasons_to_go_back; uint32 score; } struct Ranking2EstimateScoreRankOutput { uint32 rank; uint32 length; uint32 score; uint32 category; sint32 season; uint8 sampling_rate; } struct Ranking2GetByListParam { uint32 category; uint32 offset; uint32 length; uint32 sort_flags; uint32 option_flags; uint8 seasons_to_go_back; } struct Ranking2GetParam { uint64 unique_id = 0; pid pid = 0; uint32 category; uint32 offset = 0; uint32 count = 10; uint32 sort_flags = 0; uint32 option_flags = 0; uint8 mode = 2; uint8 seasons_to_go_back = 0; } struct Ranking2Info { list data; uint32 lowest_rank; uint32 num_entries; sint32 season; } struct Ranking2RankData { uint64 misc; uint64 unique_id; pid pid; uint32 rank; uint32 score; Ranking2CommonData common_data; } struct Ranking2ScoreData { uint64 misc; uint32 category; uint32 score; } protocol Ranking2 : 122 { method put_score(list socres, uint64 unique_id) {} method get_common_data(uint32 option_flags, pid pid, uint64 unique_id) { Ranking2CommonData common_data; } method put_common_data(Ranking2CommonData data, uint64 unique_id) {} method delete_common_data(uint64 unique_id) {} method get_ranking(Ranking2GetParam param) { Ranking2Info info; } method get_ranking_by_principal_id(Ranking2GetByListParam param, list pids) { Ranking2Info info; } method get_category_setting(uint32 category) { Ranking2CategorySetting setting; } method get_ranking_chart(Ranking2ChartInfoInput input) { Ranking2ChartInfo info; } method get_ranking_charts(list inputs) { list infos; } method get_estimate_score_rank(Ranking2EstimateScoreRankInput input) { Ranking2EstimateScoreRankOutput output; } } ================================================ FILE: nintendo/files/proto/ranking2_eagle.proto ================================================ import ranking2; struct Ranking2EstimateMyScoreRankInput { uint32 category; uint8 seasons_to_go_back; } protocol Ranking2 : Ranking2 { method(11) get_estimate_my_score_rank(Ranking2EstimateMyScoreRankInput input) { Ranking2EstimateScoreRankOutput output; } } ================================================ FILE: nintendo/files/proto/ranking_mk8.proto ================================================ import ranking; struct CompetitionRankingInfo { uint32 id; uint32 num_participants; list team_scores; } struct CompetitionRankingInfoGetParam { uint8 rank_order; ResultRange range; } struct CompetitionRankingUploadScoreParam { uint32 id; uint32 season_id; uint32 unk3; uint32 score; uint8 team_id; uint32 team_score; bool is_first_upload; qbuffer metadata; } protocol Ranking_MK8 : Ranking { method(14) get_competition_ranking_score; method upload_competition_ranking_score(CompetitionRankingUploadScoreParam param) { bool result; } method get_competition_info(CompetitionRankingInfoGetParam param) { list info; } } ================================================ FILE: nintendo/files/proto/ranking_mk8d.proto ================================================ import ranking; struct CommonDataList { list data; } struct CompetitionRankingGetScoreParam { uint32 id; ResultRange range; } struct CompetitionRankingInfo { uint32 id; uint32 num_participants; list team_scores; } struct CompetitionRankingInfoGetParam { uint8 rank_order; ResultRange range; } struct CompetitionRankingScoreData { uint32 rank; pid pid; uint32 score; datetime last_update; uint8 team_id = 255; qbuffer metadata; } struct CompetitionRankingScoreInfo { uint32 season_id; list scores; uint32 num_participants; list team_scores; } struct CompetitionRankingUploadScoreParam { uint32 id; uint32 season_id; uint32 unk3; uint32 score; uint8 team_id; uint32 team_score; bool is_first_upload; qbuffer metadata; } struct ScorePack { list data; } protocol Ranking_MK8D : Ranking { method(16) get_competition_ranking_score(CompetitionRankingGetScoreParam param) { list info; } method upload_competition_ranking_score(CompetitionRankingUploadScoreParam param) { bool result; } method get_competition_info(CompetitionRankingInfoGetParam param) { list info; } method upload_score_pack(RankingScoreData score_data, qbuffer metadata) {} method get_score_pack(list pids, uint32 category) { ScorePack result; } method execute_delete_score_job; method get_commmon_data_by_pid_list(list pids) { CommonDataList list; } } ================================================ FILE: nintendo/files/proto/remotelog.proto ================================================ protocol RemoteLogDevice : 1 { method log(string message) {} } ================================================ FILE: nintendo/files/proto/screening.proto ================================================ protocol Screening : 124 { method report_data_store_content; method report_user; } ================================================ FILE: nintendo/files/proto/secure.proto ================================================ struct ConnectionData { stationurl station; uint32 connection_id; } struct NintendoLoginData { string token; } protocol SecureConnection : 11 { method register(list urls) { result result; uint32 connection_id; stationurl public_station; } method request_connection_data(uint32 cid, pid pid) { bool result; list connection_data; } method request_urls(uint32 cid, pid pid) { bool result; list urls; } method register_ex(list urls, anydata login_data) { result result; uint32 connection_id; stationurl public_station; } method test_connectivity() {} method update_urls(list urls) {} method replace_url(stationurl url, stationurl new) {} method send_report(uint32 report_id, qbuffer data) {} } ================================================ FILE: nintendo/files/proto/subscriber.proto ================================================ protocol Subscriber : 121 { method hello; method post_content; method get_content; method follow; method unfollow_all_and_follow; method unfollow; method get_following; method get_follower; method get_num_followers; method get_timeline; method delete_content; method get_content_multi; method update_user_status; method get_friend_user_statuses; method get_user_statuses; } ================================================ FILE: nintendo/files/proto/utility.proto ================================================ struct UniqueIdInfo { uint64 unique_id = 0; uint64 password = 0; } protocol Utility : 110 { method acquire_nex_unique_id() { uint64 unique_id; } method acquire_nex_unique_id_with_password() { UniqueIdInfo info; } method associate_nex_unique_id_with_my_principal_id(UniqueIdInfo info) {} method associate_nex_unique_ids_with_my_principal_id(list infos) {} method get_associated_nex_unique_id_with_my_principal_id() { UniqueIdInfo info; } method get_associated_nex_unique_ids_with_my_principal_id() { list infos; } method get_integer_settings(uint32 index) { map settings; } method get_string_settings(uint32 index) { map settings; } } ================================================ FILE: nintendo/miis.py ================================================ from anynet import streams import struct def swap32(data, offs): struct.pack_into("I", data, offs)[0]) def swap16(data, offs): struct.pack_into("H", data, offs)[0]) def crc16(data): hash = 0 for char in data: for i in range(8): flag = hash & 0x8000 hash = (hash << 1) & 0xFFFF if flag: hash ^= 0x1021 hash ^= char return hash HairColors = [ (.118, .102, .094), (.251, .125, .063), (.361, .094, .039), (.486, .227, .078), (.471, .471, .502), (.306, .243, .063), (.533, .345, .094), (.816, .627, .290) ] class MiiData: #This struct contains tightly packed bit fields holding #enough information to generate a model of this mii #Names may contain all characters except '%' and '\' #Most other fields are also limited to a range of #values, as indicated by the comments behind them #If this struct contains invalid values the Wii U is likely #going to crash when it tries to render the mii model def decode(self, stream): data = stream.read(0x60) stream = streams.BitStreamIn(self.swap_endian(data), ">") #FFLiMiiDataCore self.birth_platform = stream.bits(4) #1 - 7 self.unk1 = stream.bits(4) self.unk2 = stream.bits(4) #0 - 9 self.unk3 = stream.bits(4) #0 - 9 self.font_region = stream.bits(4) #0 - 3 self.region_move = stream.bits(2) #0 - 3 self.unk4 = stream.bit() self.copyable = bool(stream.bit()) self.mii_version = stream.u8() self.author_id = stream.repeat(stream.u8, 8) self.mii_id = stream.repeat(stream.u8, 10) self.unk5 = stream.read(2) self.unk6 = stream.bit() #Always 0? self.unk7 = stream.bit() self.color = stream.bits(4) #0 - 11 self.birth_day = stream.bits(5) #1 - number of days in month self.birth_month = stream.bits(4) #1 - 12 self.gender = stream.bit() #0=male, 1=female self.mii_name = stream.wchars(10).split("\0")[0] self.size = stream.u8() #0 - 0x80 self.fatness = stream.u8() #0 - 0x80 self.blush_type = stream.bits(4) #0 - 11 self.face_style = stream.bits(4) #0 - 11 self.face_color = stream.bits(3) #0 - 5 self.face_type = stream.bits(4) #0 - 11 self.local_only = bool(stream.bit()) self.hair_mirrored = bool(stream.bits(5)) #0 - 1 self.hair_color = stream.bits(3) #0 - 7 self.hair_type = stream.u8() #0 - 131 self.eye_thickness = stream.bits(3) #0 - 6 self.eye_scale = stream.bits(4) #0 - 7 self.eye_color = stream.bits(3) #0 - 5 self.eye_type = stream.bits(6) #0 - 59 self.eye_height = stream.bits(7) #0 - 18 self.eye_distance = stream.bits(4) #0 - 12 self.eye_rotation = stream.bits(5) #0 - 7 self.eyebrow_thickness = stream.bits(4) #0 - 6 self.eyebrow_scale = stream.bits(4) #0 - 8 self.eyebrow_color = stream.bits(3) #0 - 7 self.eyebrow_type = stream.bits(5) #0 - 23 self.eyebrow_height = stream.bits(7) #3 - 18 self.eyebrow_distance = stream.bits(4) #0 - 12 self.eyebrow_rotation = stream.bits(5) #0 - 11 self.nose_height = stream.bits(7) #0 - 18 self.nose_scale = stream.bits(4) #0 - 8 self.nose_type = stream.bits(5) #0 - 17 self.mouth_thickness = stream.bits(3) #0 - 6 self.mouth_scale = stream.bits(4) #0 - 8 self.mouth_color = stream.bits(3) #0 - 4 self.mouth_type = stream.bits(6) #0 - 35 self.unk34 = stream.u8() #Always 0? self.mustache_type = stream.bits(3) #0 - 5 self.mouth_height = stream.bits(5) #0 - 18 self.mustache_height = stream.bits(6) #0 - 16 self.mustache_scale = stream.bits(4) #0 - 8 self.beard_color = stream.bits(3) #0 - 7 self.beard_type = stream.bits(3) #0 - 5 self.glass_height = stream.bits(5) #0 - 20 self.glass_scale = stream.bits(4) #0 - 7 self.glass_color = stream.bits(3) #0 - 5 self.glass_type = stream.bits(4) #0 - 8 self.unk43 = stream.bit() #Always 0? self.mole_ypos = stream.bits(5) #0 - 30 self.mole_xpos = stream.bits(5) #0 - 16 self.mole_scale = stream.bits(4) #0 - 8 self.mole_enabled = stream.bit() #0 - 1 #FFLiMiiDataOfficial self.creator_name = stream.wchars(10).split("\0")[0] #FFLStoreData self.unk48 = stream.read(2) stream.u16() #CRC16 of this whole struct if crc16(data) != 0: raise ValueError("Mii data checksum not valid") def encode(self, outstream): stream = streams.BitStreamOut(">") #FFLiMiiDataCore stream.bits(self.birth_platform, 4) stream.bits(self.unk1, 4) stream.bits(self.unk2, 4) stream.bits(self.unk3, 4) stream.bits(self.font_region, 4) stream.bits(self.region_move, 2) stream.bit(self.unk4) stream.bit(self.copyable) stream.u8(self.mii_version) stream.repeat(self.author_id, stream.u8) stream.repeat(self.mii_id, stream.u8) stream.write(self.unk5) stream.bit(self.unk6) stream.bit(self.unk7) stream.bits(self.color, 4) stream.bits(self.birth_day, 5) stream.bits(self.birth_month, 4) stream.bit(self.gender) stream.wchars(self.mii_name + "\0" * (10 - len(self.mii_name))) stream.u8(self.size) stream.u8(self.fatness) stream.bits(self.blush_type, 4) stream.bits(self.face_style, 4) stream.bits(self.face_color, 3) stream.bits(self.face_type, 4) stream.bit(self.local_only) stream.bits(self.hair_mirrored, 5) stream.bits(self.hair_color, 3) stream.u8(self.hair_type) stream.bits(self.eye_thickness, 3) stream.bits(self.eye_scale, 4) stream.bits(self.eye_color, 3) stream.bits(self.eye_type, 6) stream.bits(self.eye_height, 7) stream.bits(self.eye_distance, 4) stream.bits(self.eye_rotation, 5) stream.bits(self.eyebrow_thickness, 4) stream.bits(self.eyebrow_scale, 4) stream.bits(self.eyebrow_color, 3) stream.bits(self.eyebrow_type, 5) stream.bits(self.eyebrow_height, 7) stream.bits(self.eyebrow_distance, 4) stream.bits(self.eyebrow_rotation, 5) stream.bits(self.nose_height, 7) stream.bits(self.nose_scale, 4) stream.bits(self.nose_type, 5) stream.bits(self.mouth_thickness, 3) stream.bits(self.mouth_scale, 4) stream.bits(self.mouth_color, 3) stream.bits(self.mouth_type, 6) stream.u8(self.unk34) stream.bits(self.mustache_type, 3) stream.bits(self.mouth_height, 5) stream.bits(self.mustache_height, 6) stream.bits(self.mustache_scale, 4) stream.bits(self.beard_color, 3) stream.bits(self.beard_type, 3) stream.bits(self.glass_height, 5) stream.bits(self.glass_scale, 4) stream.bits(self.glass_color, 3) stream.bits(self.glass_type, 4) stream.bit(self.unk43) stream.bits(self.mole_ypos, 5) stream.bits(self.mole_xpos, 5) stream.bits(self.mole_scale, 4) stream.bit(self.mole_enabled) #FFLiMiiDataOfficial stream.wchars(self.creator_name + "\0" * (10 - len(self.creator_name))) #FFLStoreData stream.write(self.unk48) data = self.swap_endian(stream.get()) outstream.write(data) outstream.u16(crc16(data + b"\0\0")) def swap_endian(self, data): array = bytearray(data) #FFLiMiiDataCore swap32(array, 0) for i in range(0x18, 0x2E, 2): swap16(array, i) for i in range(0x30, 0x48, 2): swap16(array, i) #FFLiMiiDataOfficial for i in range(0x48, 0x5C, 2): swap16(array, i) #FFLStoreData swap16(array, 0x5C) return bytes(array) def build(self): stream = streams.StreamOut(">") self.encode(stream) return stream.get() @classmethod def parse(cls, data): instance = cls() instance.decode(streams.StreamIn(data, ">")) return instance ================================================ FILE: nintendo/nasc.py ================================================ from anynet import http, tls from nintendo import resources import datetime import secrets import base64 import logging logger = logging.getLogger(__name__) MEDIA_TYPE_SYSTEM = 0 MEDIA_TYPE_DIGITAL = 1 MEDIA_TYPE_CARTRIDGE = 2 def b64decode(text): text = text.replace(".", "+").replace("-", "/").replace("*", "=") return base64.b64decode(text) def b64encode(text): # Convert to bytes if necessary if isinstance(text, str): text = text.encode() text = base64.b64encode(text).decode() return text.replace("+", ".").replace("/", "-").replace("=", "*") def decode_form(form): return {key: b64decode(value) for key, value in form.items()} def encode_form(form): return {key: b64encode(value) for key, value in form.items()} def parse_date(text): return datetime.datetime.strptime(text, "%Y%m%d%H%M%S") # Known error codes: # 001: success # 109: missing or malformed parameter in request # 110: game server is no longer available # 119: fpd version is outdated # 121: device certificate is invalid # 122: uid hmac is invalid # 125: game id is invalid class NASCError(Exception): def __init__(self, status_code, form): self.status_code = status_code returncd = form["returncd"].decode() self.return_code = None if returncd == "null" else int(returncd) self.retry = bool(int(form["retry"].decode())) self.datetime = parse_date(form["datetime"].decode()) def __str__(self): if self.return_code is None: return "NASC request failed with error code null" return "NASC request failed with error code %i" %self.return_code class LoginResponse: def __init__(self): self.host = None self.port = None self.token = None self.datetime = None @classmethod def parse(cls, form): host, port = form["locator"].decode().split(":") inst = cls() inst.host = host inst.port = int(port) inst.token = b64encode(form["token"]) inst.datetime = parse_date(form["datetime"].decode()) return inst class NASCClient: def __init__(self): self.url = "nasc.nintendowifi.net" ca = resources.certificate("Nintendo_CA_G3.der") cert = resources.certificate("CTR_Common_Prod_1.der") key = resources.private_key("CTR_Common_Prod_1.key") self.context = tls.TLSContext() self.context.set_authority(ca) self.context.set_certificate(cert, key) self.sdk_version_major = 0 self.sdk_version_minor = 0 self.title_id = None self.title_version = None self.product_code = "----" self.maker_code = "00" self.media_type = MEDIA_TYPE_SYSTEM self.rom_id = None self.serial_number = None self.mac_address = None self.fcd_cert = None self.device_name = "" self.unit_code = "2" self.bss_id = secrets.token_hex(6) self.ap_info = "01:0000000000" self.region = 3 self.language = 2 self.pid = None self.pid_hmac = None self.password = None self.fpd_version = 16 self.environment = "L1" def set_context(self, context): self.context = context def set_url(self, url): self.url = url def set_sdk_version(self, major_version, minor_version): self.sdk_major_version = major_version self.sdk_minor_version = minor_version def set_title( self, title_id, title_version, product_code="----", maker_code="00", media_type=MEDIA_TYPE_SYSTEM, rom_id=None ): if media_type == MEDIA_TYPE_CARTRIDGE and rom_id is None: raise ValueError("Rom ID is required for cartridge media type") self.title_id = title_id self.title_version = title_version self.product_code = product_code self.maker_code = maker_code self.media_type = media_type self.rom_id = rom_id def set_device(self, serial_number, mac_address, fcd_cert, name="", unit_code="2"): self.serial_number = serial_number self.mac_address = mac_address self.fcd_cert = fcd_cert self.device_name = name self.unit_code = unit_code def set_network(self, bss_id, ap_info): self.bss_id = bss_id self.ap_info = ap_info def set_locale(self, region, language): self.region = region self.language = language def set_user(self, pid, pid_hmac): self.pid = pid self.pid_hmac = pid_hmac self.password = None def set_password(self, password): self.pid = None self.pid_hmac = None self.password = password def set_fpd_version(self, version): self.fpd_version = version def set_environment(self, environment): self.environment = environment async def request(self, req): # Apply Nintendo's custom base64 encoding req.form = encode_form(req.form) # Must manually decode form here since server doesn't return correct content-type response = await http.request(self.url, req, self.context) response.form = decode_form(http.formdecode(response.text)) return_code = response.form["returncd"].decode() if return_code == "null" or int(return_code) != 1: raise NASCError(response.status_code, response.form) return response async def login(self, game_server_id, nickname=""): if self.title_id is None: raise ValueError("Please configure the title (set_title)") if self.serial_number is None: raise ValueError("Please configure the device (set_device)") if self.pid is None and self.password is None: raise ValueError("Please configure a user id or password (set_user / set_password)") req = http.HTTPRequest.post("/ac") req.headers["Host"] = self.url req.headers["X-GameId"] = "%08X" %game_server_id req.headers["User-Agent"] = "CTR FPD/%04X" %self.fpd_version # The real 3DS seems to add this header twice for some reason req.headers.add("Content-Type", "application/x-www-form-urlencoded") req.headers.add("Content-Type", "application/x-www-form-urlencoded") now = datetime.datetime.now() device_time = now.strftime("%y%m%d%H%M%S") req.form = {} req.form["gameid"] = "%08X" %game_server_id req.form["sdkver"] = "%03i%03i" %(self.sdk_version_major, self.sdk_version_minor) req.form["titleid"] = "%016X" %self.title_id req.form["gamecd"] = self.product_code req.form["gamever"] = "%04X" %self.title_version req.form["mediatype"] = str(self.media_type) if self.media_type == MEDIA_TYPE_CARTRIDGE: req.form["romid"] = self.rom_id req.form["makercd"] = self.maker_code req.form["unitcd"] = self.unit_code req.form["macadr"] = self.mac_address req.form["bssid"] = self.bss_id req.form["apinfo"] = self.ap_info req.form["fcdcert"] = self.fcd_cert req.form["devname"] = self.device_name.encode("utf-16-le") req.form["servertype"] = self.environment req.form["fpdver"] = "%04X" %self.fpd_version req.form["devtime"] = device_time req.form["lang"] = "%02X" %self.language req.form["region"] = "%02X" %self.region req.form["csnum"] = self.serial_number if self.pid_hmac is not None: req.form["uidhmac"] = self.pid_hmac req.form["userid"] = str(self.pid) else: req.form["passwd"] = self.password req.form["action"] = "LOGIN" req.form["ingamesn"] = nickname response = await self.request(req) return LoginResponse.parse(response.form) ================================================ FILE: nintendo/nex/__init__.py ================================================ ================================================ FILE: nintendo/nex/aauser.py ================================================ # This file was generated automatically by generate_protocols.py from nintendo.nex import notification, rmc, common, streams import logging logger = logging.getLogger(__name__) class ApplicationInfo(common.Structure): def __init__(self): super().__init__() self.title_id = None self.title_version = None def check_required(self, settings, version): for field in ['title_id', 'title_version']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.title_id = stream.u64() self.title_version = stream.u16() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.title_id) stream.u16(self.title_version) class AAUserProtocol: METHOD_REGISTER_APPLICATION = 1 METHOD_UNREGISTER_APPLICATION = 2 METHOD_SET_APPLICATION_INFO = 3 METHOD_GET_APPLICATION_INFO = 4 PROTOCOL_ID = 0x7B class AAUserClient(AAUserProtocol): def __init__(self, client): self.settings = client.settings self.client = client async def register_application(self, title_id): logger.info("AAUserClient.register_application()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(title_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REGISTER_APPLICATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AAUserClient.register_application -> done") async def unregister_application(self, title_id): logger.info("AAUserClient.unregister_application()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(title_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UNREGISTER_APPLICATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AAUserClient.unregister_application -> done") async def set_application_info(self, application_info): logger.info("AAUserClient.set_application_info()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(application_info, stream.add) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SET_APPLICATION_INFO, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AAUserClient.set_application_info -> done") async def get_application_info(self): logger.info("AAUserClient.get_application_info()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_APPLICATION_INFO, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.list(ApplicationInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AAUserClient.get_application_info -> done") return info class AAUserServer(AAUserProtocol): def __init__(self): self.methods = { self.METHOD_REGISTER_APPLICATION: self.handle_register_application, self.METHOD_UNREGISTER_APPLICATION: self.handle_unregister_application, self.METHOD_SET_APPLICATION_INFO: self.handle_set_application_info, self.METHOD_GET_APPLICATION_INFO: self.handle_get_application_info, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on AAUserServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_register_application(self, client, input, output): logger.info("AAUserServer.register_application()") #--- request --- title_id = input.u64() await self.register_application(client, title_id) async def handle_unregister_application(self, client, input, output): logger.info("AAUserServer.unregister_application()") #--- request --- title_id = input.u64() await self.unregister_application(client, title_id) async def handle_set_application_info(self, client, input, output): logger.info("AAUserServer.set_application_info()") #--- request --- application_info = input.list(ApplicationInfo) await self.set_application_info(client, application_info) async def handle_get_application_info(self, client, input, output): logger.info("AAUserServer.get_application_info()") #--- request --- response = await self.get_application_info(client) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def register_application(self, *args): logger.warning("AAUserServer.register_application not implemented") raise common.RMCError("Core::NotImplemented") async def unregister_application(self, *args): logger.warning("AAUserServer.unregister_application not implemented") raise common.RMCError("Core::NotImplemented") async def set_application_info(self, *args): logger.warning("AAUserServer.set_application_info not implemented") raise common.RMCError("Core::NotImplemented") async def get_application_info(self, *args): logger.warning("AAUserServer.get_application_info not implemented") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/account.py ================================================ # This file was generated automatically by generate_protocols.py from nintendo.nex import notification, rmc, common, streams import logging logger = logging.getLogger(__name__) class AccountData(common.Structure): def __init__(self): super().__init__() self.pid = None self.name = None self.groups = None self.email = None self.creation_date = None self.effective_date = None self.not_effective_message = None self.expiry_date = None self.expired_message = None def check_required(self, settings, version): for field in ['pid', 'name', 'groups', 'email', 'creation_date', 'effective_date', 'not_effective_message', 'expiry_date', 'expired_message']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.name = stream.string() self.groups = stream.u32() self.email = stream.string() self.creation_date = stream.datetime() self.effective_date = stream.datetime() self.not_effective_message = stream.string() self.expiry_date = stream.datetime() self.expired_message = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.string(self.name) stream.u32(self.groups) stream.string(self.email) stream.datetime(self.creation_date) stream.datetime(self.effective_date) stream.string(self.not_effective_message) stream.datetime(self.expiry_date) stream.string(self.expired_message) class BasicAccountInfo(common.Structure): def __init__(self): super().__init__() self.pid = None self.name = None def check_required(self, settings, version): for field in ['pid', 'name']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.name = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.string(self.name) class AccountProtocol: METHOD_CREATE_ACCOUNT = 1 METHOD_DELETE_ACCOUNT = 2 METHOD_DISABLE_ACCOUNT = 3 METHOD_CHANGE_PASSWORD = 4 METHOD_TEST_CAPABILITY = 5 METHOD_GET_NAME = 6 METHOD_GET_ACCOUNT_DATA = 7 METHOD_GET_PRIVATE_DATA = 8 METHOD_GET_PUBLIC_DATA = 9 METHOD_GET_MULTIPLE_PUBLIC_DATA = 10 METHOD_UPDATE_ACCOUNT_NAME = 11 METHOD_UPDATE_ACCOUNT_EMAIL = 12 METHOD_UPDATE_CUSTOM_DATA = 13 METHOD_FIND_BY_NAME_REGEX = 14 METHOD_UPDATE_ACCOUNT_EXPIRY_DATE = 15 METHOD_UPDATE_ACCOUNT_EFFECTIVE_DATE = 16 METHOD_UPDATE_STATUS = 17 METHOD_GET_STATUS = 18 METHOD_GET_LAST_CONNECTION_STATS = 19 METHOD_RESET_PASSWORD = 20 METHOD_CREATE_ACCOUNT_WITH_CUSTOM_DATA = 21 METHOD_RETRIEVE_ACCOUNT = 22 METHOD_UPDATE_ACCOUNT = 23 METHOD_CHANGE_PASSWORD_BY_GUEST = 24 METHOD_FIND_BY_NAME_LIKE = 25 METHOD_CUSTOM_CREATE_ACCOUNT = 26 METHOD_NINTENDO_CREATE_ACCOUNT = 27 METHOD_LOOKUP_OR_CREATE_ACCOUNT = 28 METHOD_DISCONNECT_PRINCIPAL = 29 METHOD_DISCONNECT_ALL_PRINCIPALS = 30 PROTOCOL_ID = 0x19 class AccountClient(AccountProtocol): def __init__(self, client): self.settings = client.settings self.client = client async def create_account(self, name, key, groups, email): logger.info("AccountClient.create_account()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(name) stream.string(key) stream.u32(groups) stream.string(email) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CREATE_ACCOUNT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.result() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.create_account -> done") return result async def delete_account(self, pid): logger.info("AccountClient.delete_account()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_ACCOUNT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.delete_account -> done") async def disable_account(self, pid, until, message): logger.info("AccountClient.disable_account()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) stream.datetime(until) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DISABLE_ACCOUNT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.result() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.disable_account -> done") return result async def change_password(self, new_key): logger.info("AccountClient.change_password()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(new_key) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CHANGE_PASSWORD, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.change_password -> done") return result async def test_capability(self, capability): logger.info("AccountClient.test_capability()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(capability) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_TEST_CAPABILITY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.test_capability -> done") return result async def get_name(self, pid): logger.info("AccountClient.get_name()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_NAME, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) name = stream.string() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.get_name -> done") return name async def get_account_data(self): logger.info("AccountClient.get_account_data()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_ACCOUNT_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.result() obj.data = stream.extract(AccountData) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.get_account_data -> done") return obj async def get_private_data(self): logger.info("AccountClient.get_private_data()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PRIVATE_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.data = stream.anydata() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.get_private_data -> done") return obj async def get_public_data(self, pid): logger.info("AccountClient.get_public_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PUBLIC_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.data = stream.anydata() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.get_public_data -> done") return obj async def get_multiple_public_data(self, pids): logger.info("AccountClient.get_multiple_public_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_MULTIPLE_PUBLIC_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.data = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.get_multiple_public_data -> done") return obj async def update_account_name(self, name): logger.info("AccountClient.update_account_name()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(name) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_ACCOUNT_NAME, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.result() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.update_account_name -> done") return result async def update_account_email(self, email): logger.info("AccountClient.update_account_email()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(email) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_ACCOUNT_EMAIL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.result() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.update_account_email -> done") return result async def update_custom_data(self, public_data, private_data): logger.info("AccountClient.update_custom_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(public_data) stream.anydata(private_data) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_CUSTOM_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.result() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.update_custom_data -> done") return result async def find_by_name_regex(self, groups, regex, range): logger.info("AccountClient.find_by_name_regex()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(groups) stream.string(regex) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_NAME_REGEX, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) accounts = stream.list(BasicAccountInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.find_by_name_regex -> done") return accounts async def update_account_expiry_date(self, pid, expiry, message): logger.info("AccountClient.update_account_expiry_date()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) stream.datetime(expiry) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_ACCOUNT_EXPIRY_DATE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.update_account_expiry_date -> done") async def update_account_effective_date(self, pid, effective_from, message): logger.info("AccountClient.update_account_effective_date()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) stream.datetime(effective_from) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_ACCOUNT_EFFECTIVE_DATE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.update_account_effective_date -> done") async def update_status(self, status): logger.info("AccountClient.update_status()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(status) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_STATUS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.update_status -> done") async def get_status(self, pid): logger.info("AccountClient.get_status()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATUS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) status = stream.string() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.get_status -> done") return status async def get_last_connection_stats(self, pid): logger.info("AccountClient.get_last_connection_stats()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_LAST_CONNECTION_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.last_session_login = stream.datetime() obj.last_session_logout = stream.datetime() obj.current_session_login = stream.datetime() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.get_last_connection_stats -> done") return obj async def reset_password(self): logger.info("AccountClient.reset_password()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RESET_PASSWORD, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.reset_password -> done") return result async def create_account_with_custom_data(self, name, key, groups, email, public_data, private_data): logger.info("AccountClient.create_account_with_custom_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(name) stream.string(key) stream.u32(groups) stream.string(email) stream.anydata(public_data) stream.anydata(private_data) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CREATE_ACCOUNT_WITH_CUSTOM_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.create_account_with_custom_data -> done") async def retrieve_account(self): logger.info("AccountClient.retrieve_account()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RETRIEVE_ACCOUNT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.account_data = stream.extract(AccountData) obj.public_data = stream.anydata() obj.private_data = stream.anydata() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.retrieve_account -> done") return obj async def update_account(self, key, email, public_data, private_data): logger.info("AccountClient.update_account()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(key) stream.string(email) stream.anydata(public_data) stream.anydata(private_data) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_ACCOUNT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.update_account -> done") async def change_password_by_guest(self, name, email, key): logger.info("AccountClient.change_password_by_guest()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(name) stream.string(email) stream.string(key) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CHANGE_PASSWORD_BY_GUEST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.change_password_by_guest -> done") async def find_by_name_like(self, groups, like, range): logger.info("AccountClient.find_by_name_like()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(groups) stream.string(like) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_NAME_LIKE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) accounts = stream.list(BasicAccountInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.find_by_name_like -> done") return accounts async def custom_create_account(self, name, key, groups, email, auth_data): logger.info("AccountClient.custom_create_account()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(name) stream.string(key) stream.u32(groups) stream.string(email) stream.anydata(auth_data) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CUSTOM_CREATE_ACCOUNT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) pid = stream.pid() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.custom_create_account -> done") return pid async def nintendo_create_account(self, name, key, groups, email, auth_data): logger.info("AccountClient.nintendo_create_account()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(name) stream.string(key) stream.u32(groups) stream.string(email) stream.anydata(auth_data) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_NINTENDO_CREATE_ACCOUNT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.pid = stream.pid() obj.pid_hmac = stream.string() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.nintendo_create_account -> done") return obj async def lookup_or_create_account(self, name, key, groups, email, auth_data): logger.info("AccountClient.lookup_or_create_account()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(name) stream.string(key) stream.u32(groups) stream.string(email) stream.anydata(auth_data) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_LOOKUP_OR_CREATE_ACCOUNT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) pid = stream.pid() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.lookup_or_create_account -> done") return pid async def disconnect_principal(self, pid): logger.info("AccountClient.disconnect_principal()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DISCONNECT_PRINCIPAL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.disconnect_principal -> done") return result async def disconnect_all_principals(self): logger.info("AccountClient.disconnect_all_principals()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DISCONNECT_ALL_PRINCIPALS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AccountClient.disconnect_all_principals -> done") return result class AccountServer(AccountProtocol): def __init__(self): self.methods = { self.METHOD_CREATE_ACCOUNT: self.handle_create_account, self.METHOD_DELETE_ACCOUNT: self.handle_delete_account, self.METHOD_DISABLE_ACCOUNT: self.handle_disable_account, self.METHOD_CHANGE_PASSWORD: self.handle_change_password, self.METHOD_TEST_CAPABILITY: self.handle_test_capability, self.METHOD_GET_NAME: self.handle_get_name, self.METHOD_GET_ACCOUNT_DATA: self.handle_get_account_data, self.METHOD_GET_PRIVATE_DATA: self.handle_get_private_data, self.METHOD_GET_PUBLIC_DATA: self.handle_get_public_data, self.METHOD_GET_MULTIPLE_PUBLIC_DATA: self.handle_get_multiple_public_data, self.METHOD_UPDATE_ACCOUNT_NAME: self.handle_update_account_name, self.METHOD_UPDATE_ACCOUNT_EMAIL: self.handle_update_account_email, self.METHOD_UPDATE_CUSTOM_DATA: self.handle_update_custom_data, self.METHOD_FIND_BY_NAME_REGEX: self.handle_find_by_name_regex, self.METHOD_UPDATE_ACCOUNT_EXPIRY_DATE: self.handle_update_account_expiry_date, self.METHOD_UPDATE_ACCOUNT_EFFECTIVE_DATE: self.handle_update_account_effective_date, self.METHOD_UPDATE_STATUS: self.handle_update_status, self.METHOD_GET_STATUS: self.handle_get_status, self.METHOD_GET_LAST_CONNECTION_STATS: self.handle_get_last_connection_stats, self.METHOD_RESET_PASSWORD: self.handle_reset_password, self.METHOD_CREATE_ACCOUNT_WITH_CUSTOM_DATA: self.handle_create_account_with_custom_data, self.METHOD_RETRIEVE_ACCOUNT: self.handle_retrieve_account, self.METHOD_UPDATE_ACCOUNT: self.handle_update_account, self.METHOD_CHANGE_PASSWORD_BY_GUEST: self.handle_change_password_by_guest, self.METHOD_FIND_BY_NAME_LIKE: self.handle_find_by_name_like, self.METHOD_CUSTOM_CREATE_ACCOUNT: self.handle_custom_create_account, self.METHOD_NINTENDO_CREATE_ACCOUNT: self.handle_nintendo_create_account, self.METHOD_LOOKUP_OR_CREATE_ACCOUNT: self.handle_lookup_or_create_account, self.METHOD_DISCONNECT_PRINCIPAL: self.handle_disconnect_principal, self.METHOD_DISCONNECT_ALL_PRINCIPALS: self.handle_disconnect_all_principals, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on AccountServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_create_account(self, client, input, output): logger.info("AccountServer.create_account()") #--- request --- name = input.string() key = input.string() groups = input.u32() email = input.string() response = await self.create_account(client, name, key, groups, email) #--- response --- if not isinstance(response, common.Result): raise RuntimeError("Expected common.Result, got %s" %response.__class__.__name__) output.result(response) async def handle_delete_account(self, client, input, output): logger.info("AccountServer.delete_account()") #--- request --- pid = input.pid() await self.delete_account(client, pid) async def handle_disable_account(self, client, input, output): logger.info("AccountServer.disable_account()") #--- request --- pid = input.pid() until = input.datetime() message = input.string() response = await self.disable_account(client, pid, until, message) #--- response --- if not isinstance(response, common.Result): raise RuntimeError("Expected common.Result, got %s" %response.__class__.__name__) output.result(response) async def handle_change_password(self, client, input, output): logger.info("AccountServer.change_password()") #--- request --- new_key = input.string() response = await self.change_password(client, new_key) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_test_capability(self, client, input, output): logger.info("AccountServer.test_capability()") #--- request --- capability = input.u32() response = await self.test_capability(client, capability) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_name(self, client, input, output): logger.info("AccountServer.get_name()") #--- request --- pid = input.pid() response = await self.get_name(client, pid) #--- response --- if not isinstance(response, str): raise RuntimeError("Expected str, got %s" %response.__class__.__name__) output.string(response) async def handle_get_account_data(self, client, input, output): logger.info("AccountServer.get_account_data()") #--- request --- response = await self.get_account_data(client) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'data']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.result(response.result) output.add(response.data) async def handle_get_private_data(self, client, input, output): logger.info("AccountServer.get_private_data()") #--- request --- response = await self.get_private_data(client) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'data']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.anydata(response.data) async def handle_get_public_data(self, client, input, output): logger.info("AccountServer.get_public_data()") #--- request --- pid = input.pid() response = await self.get_public_data(client, pid) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'data']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.anydata(response.data) async def handle_get_multiple_public_data(self, client, input, output): logger.info("AccountServer.get_multiple_public_data()") #--- request --- pids = input.list(input.pid) response = await self.get_multiple_public_data(client, pids) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'data']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.list(response.data, output.anydata) async def handle_update_account_name(self, client, input, output): logger.info("AccountServer.update_account_name()") #--- request --- name = input.string() response = await self.update_account_name(client, name) #--- response --- if not isinstance(response, common.Result): raise RuntimeError("Expected common.Result, got %s" %response.__class__.__name__) output.result(response) async def handle_update_account_email(self, client, input, output): logger.info("AccountServer.update_account_email()") #--- request --- email = input.string() response = await self.update_account_email(client, email) #--- response --- if not isinstance(response, common.Result): raise RuntimeError("Expected common.Result, got %s" %response.__class__.__name__) output.result(response) async def handle_update_custom_data(self, client, input, output): logger.info("AccountServer.update_custom_data()") #--- request --- public_data = input.anydata() private_data = input.anydata() response = await self.update_custom_data(client, public_data, private_data) #--- response --- if not isinstance(response, common.Result): raise RuntimeError("Expected common.Result, got %s" %response.__class__.__name__) output.result(response) async def handle_find_by_name_regex(self, client, input, output): logger.info("AccountServer.find_by_name_regex()") #--- request --- groups = input.u32() regex = input.string() range = input.extract(common.ResultRange) response = await self.find_by_name_regex(client, groups, regex, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_update_account_expiry_date(self, client, input, output): logger.info("AccountServer.update_account_expiry_date()") #--- request --- pid = input.pid() expiry = input.datetime() message = input.string() await self.update_account_expiry_date(client, pid, expiry, message) async def handle_update_account_effective_date(self, client, input, output): logger.info("AccountServer.update_account_effective_date()") #--- request --- pid = input.pid() effective_from = input.datetime() message = input.string() await self.update_account_effective_date(client, pid, effective_from, message) async def handle_update_status(self, client, input, output): logger.info("AccountServer.update_status()") #--- request --- status = input.string() await self.update_status(client, status) async def handle_get_status(self, client, input, output): logger.info("AccountServer.get_status()") #--- request --- pid = input.pid() response = await self.get_status(client, pid) #--- response --- if not isinstance(response, str): raise RuntimeError("Expected str, got %s" %response.__class__.__name__) output.string(response) async def handle_get_last_connection_stats(self, client, input, output): logger.info("AccountServer.get_last_connection_stats()") #--- request --- pid = input.pid() response = await self.get_last_connection_stats(client, pid) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['last_session_login', 'last_session_logout', 'current_session_login']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.datetime(response.last_session_login) output.datetime(response.last_session_logout) output.datetime(response.current_session_login) async def handle_reset_password(self, client, input, output): logger.info("AccountServer.reset_password()") #--- request --- response = await self.reset_password(client) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_create_account_with_custom_data(self, client, input, output): logger.info("AccountServer.create_account_with_custom_data()") #--- request --- name = input.string() key = input.string() groups = input.u32() email = input.string() public_data = input.anydata() private_data = input.anydata() await self.create_account_with_custom_data(client, name, key, groups, email, public_data, private_data) async def handle_retrieve_account(self, client, input, output): logger.info("AccountServer.retrieve_account()") #--- request --- response = await self.retrieve_account(client) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['account_data', 'public_data', 'private_data']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.add(response.account_data) output.anydata(response.public_data) output.anydata(response.private_data) async def handle_update_account(self, client, input, output): logger.info("AccountServer.update_account()") #--- request --- key = input.string() email = input.string() public_data = input.anydata() private_data = input.anydata() await self.update_account(client, key, email, public_data, private_data) async def handle_change_password_by_guest(self, client, input, output): logger.info("AccountServer.change_password_by_guest()") #--- request --- name = input.string() email = input.string() key = input.string() await self.change_password_by_guest(client, name, email, key) async def handle_find_by_name_like(self, client, input, output): logger.info("AccountServer.find_by_name_like()") #--- request --- groups = input.u32() like = input.string() range = input.extract(common.ResultRange) response = await self.find_by_name_like(client, groups, like, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_custom_create_account(self, client, input, output): logger.info("AccountServer.custom_create_account()") #--- request --- name = input.string() key = input.string() groups = input.u32() email = input.string() auth_data = input.anydata() response = await self.custom_create_account(client, name, key, groups, email, auth_data) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.pid(response) async def handle_nintendo_create_account(self, client, input, output): logger.info("AccountServer.nintendo_create_account()") #--- request --- name = input.string() key = input.string() groups = input.u32() email = input.string() auth_data = input.anydata() response = await self.nintendo_create_account(client, name, key, groups, email, auth_data) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['pid', 'pid_hmac']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.pid(response.pid) output.string(response.pid_hmac) async def handle_lookup_or_create_account(self, client, input, output): logger.info("AccountServer.lookup_or_create_account()") #--- request --- name = input.string() key = input.string() groups = input.u32() email = input.string() auth_data = input.anydata() response = await self.lookup_or_create_account(client, name, key, groups, email, auth_data) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.pid(response) async def handle_disconnect_principal(self, client, input, output): logger.info("AccountServer.disconnect_principal()") #--- request --- pid = input.pid() response = await self.disconnect_principal(client, pid) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_disconnect_all_principals(self, client, input, output): logger.info("AccountServer.disconnect_all_principals()") #--- request --- response = await self.disconnect_all_principals(client) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def create_account(self, *args): logger.warning("AccountServer.create_account not implemented") raise common.RMCError("Core::NotImplemented") async def delete_account(self, *args): logger.warning("AccountServer.delete_account not implemented") raise common.RMCError("Core::NotImplemented") async def disable_account(self, *args): logger.warning("AccountServer.disable_account not implemented") raise common.RMCError("Core::NotImplemented") async def change_password(self, *args): logger.warning("AccountServer.change_password not implemented") raise common.RMCError("Core::NotImplemented") async def test_capability(self, *args): logger.warning("AccountServer.test_capability not implemented") raise common.RMCError("Core::NotImplemented") async def get_name(self, *args): logger.warning("AccountServer.get_name not implemented") raise common.RMCError("Core::NotImplemented") async def get_account_data(self, *args): logger.warning("AccountServer.get_account_data not implemented") raise common.RMCError("Core::NotImplemented") async def get_private_data(self, *args): logger.warning("AccountServer.get_private_data not implemented") raise common.RMCError("Core::NotImplemented") async def get_public_data(self, *args): logger.warning("AccountServer.get_public_data not implemented") raise common.RMCError("Core::NotImplemented") async def get_multiple_public_data(self, *args): logger.warning("AccountServer.get_multiple_public_data not implemented") raise common.RMCError("Core::NotImplemented") async def update_account_name(self, *args): logger.warning("AccountServer.update_account_name not implemented") raise common.RMCError("Core::NotImplemented") async def update_account_email(self, *args): logger.warning("AccountServer.update_account_email not implemented") raise common.RMCError("Core::NotImplemented") async def update_custom_data(self, *args): logger.warning("AccountServer.update_custom_data not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_name_regex(self, *args): logger.warning("AccountServer.find_by_name_regex not implemented") raise common.RMCError("Core::NotImplemented") async def update_account_expiry_date(self, *args): logger.warning("AccountServer.update_account_expiry_date not implemented") raise common.RMCError("Core::NotImplemented") async def update_account_effective_date(self, *args): logger.warning("AccountServer.update_account_effective_date not implemented") raise common.RMCError("Core::NotImplemented") async def update_status(self, *args): logger.warning("AccountServer.update_status not implemented") raise common.RMCError("Core::NotImplemented") async def get_status(self, *args): logger.warning("AccountServer.get_status not implemented") raise common.RMCError("Core::NotImplemented") async def get_last_connection_stats(self, *args): logger.warning("AccountServer.get_last_connection_stats not implemented") raise common.RMCError("Core::NotImplemented") async def reset_password(self, *args): logger.warning("AccountServer.reset_password not implemented") raise common.RMCError("Core::NotImplemented") async def create_account_with_custom_data(self, *args): logger.warning("AccountServer.create_account_with_custom_data not implemented") raise common.RMCError("Core::NotImplemented") async def retrieve_account(self, *args): logger.warning("AccountServer.retrieve_account not implemented") raise common.RMCError("Core::NotImplemented") async def update_account(self, *args): logger.warning("AccountServer.update_account not implemented") raise common.RMCError("Core::NotImplemented") async def change_password_by_guest(self, *args): logger.warning("AccountServer.change_password_by_guest not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_name_like(self, *args): logger.warning("AccountServer.find_by_name_like not implemented") raise common.RMCError("Core::NotImplemented") async def custom_create_account(self, *args): logger.warning("AccountServer.custom_create_account not implemented") raise common.RMCError("Core::NotImplemented") async def nintendo_create_account(self, *args): logger.warning("AccountServer.nintendo_create_account not implemented") raise common.RMCError("Core::NotImplemented") async def lookup_or_create_account(self, *args): logger.warning("AccountServer.lookup_or_create_account not implemented") raise common.RMCError("Core::NotImplemented") async def disconnect_principal(self, *args): logger.warning("AccountServer.disconnect_principal not implemented") raise common.RMCError("Core::NotImplemented") async def disconnect_all_principals(self, *args): logger.warning("AccountServer.disconnect_all_principals not implemented") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/authentication.py ================================================ # This file was generated automatically by generate_protocols.py from nintendo.nex import notification, rmc, common, streams import logging logger = logging.getLogger(__name__) class AuthenticationInfo(common.Data): def __init__(self): super().__init__() self.token = None self.ngs_version = 3 self.token_type = 1 self.server_version = 0 def check_required(self, settings, version): for field in ['token']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.token = stream.string() self.ngs_version = stream.u32() self.token_type = stream.u8() self.server_version = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.token) stream.u32(self.ngs_version) stream.u8(self.token_type) stream.u32(self.server_version) common.DataHolder.register(AuthenticationInfo, "AuthenticationInfo") class RVConnectionData(common.Structure): def __init__(self): super().__init__() self.main_station = common.StationURL.parse("prudp:/") self.special_protocols = [] self.special_station = common.StationURL.parse("prudp:/") self.server_time = common.DateTime(0) def max_version(self, settings): version = 0 if settings["nex.version"] >= 30500: version = 1 return version def check_required(self, settings, version): if settings["nex.version"] >= 30500: if version >= 1: pass def load(self, stream, version): self.main_station = stream.stationurl() self.special_protocols = stream.list(stream.u8) self.special_station = stream.stationurl() if stream.settings["nex.version"] >= 30500: if version >= 1: self.server_time = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.stationurl(self.main_station) stream.list(self.special_protocols, stream.u8) stream.stationurl(self.special_station) if stream.settings["nex.version"] >= 30500: if version >= 1: stream.datetime(self.server_time) class ValidateAndRequestTicketParam(common.Structure): def __init__(self): super().__init__() self.platform = 3 self.username = None self.data = None self.skip_version_check = False self.nex_version = None self.client_version = None def check_required(self, settings, version): for field in ['username', 'data', 'nex_version', 'client_version']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.platform = stream.u32() self.username = stream.string() self.data = stream.anydata() self.skip_version_check = stream.bool() self.nex_version = stream.u32() self.client_version = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.platform) stream.string(self.username) stream.anydata(self.data) stream.bool(self.skip_version_check) stream.u32(self.nex_version) stream.u32(self.client_version) class ValidateAndRequestTicketResult(common.Structure): def __init__(self): super().__init__() self.pid = None self.ticket = None self.server_url = None self.server_time = None self.server_name = None self.source_key = None def check_required(self, settings, version): for field in ['pid', 'ticket', 'server_url', 'server_time', 'server_name', 'source_key']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.ticket = stream.buffer() self.server_url = stream.stationurl() self.server_time = stream.datetime() self.server_name = stream.string() self.source_key = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.buffer(self.ticket) stream.stationurl(self.server_url) stream.datetime(self.server_time) stream.string(self.server_name) stream.string(self.source_key) class AuthenticationProtocol: METHOD_LOGIN = 1 METHOD_LOGIN_EX = 2 METHOD_REQUEST_TICKET = 3 METHOD_GET_PID = 4 METHOD_GET_NAME = 5 METHOD_LOGIN_WITH_CONTEXT = 6 PROTOCOL_ID = 0xA class AuthenticationProtocolNX: METHOD_VALIDATE_AND_REQUEST_TICKET = 1 METHOD_VALIDATE_AND_REQUEST_TICKET_WITH_CUSTOM_DATA = 2 METHOD_REQUEST_TICKET = 3 METHOD_GET_PID = 4 METHOD_GET_NAME = 5 METHOD_VALIDATE_AND_REQUEST_TICKET_WITH_PARAM = 6 PROTOCOL_ID = 0xA class AuthenticationClient(AuthenticationProtocol): def __init__(self, client): self.settings = client.settings self.client = client async def login(self, username): logger.info("AuthenticationClient.login()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(username) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_LOGIN, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.result() obj.pid = stream.pid() obj.ticket = stream.buffer() obj.connection_data = stream.extract(RVConnectionData) obj.server_name = stream.string() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AuthenticationClient.login -> done") return obj async def login_ex(self, username, extra_data): logger.info("AuthenticationClient.login_ex()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(username) stream.anydata(extra_data) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_LOGIN_EX, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.result() obj.pid = stream.pid() obj.ticket = stream.buffer() obj.connection_data = stream.extract(RVConnectionData) obj.server_name = stream.string() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AuthenticationClient.login_ex -> done") return obj async def request_ticket(self, source, target): logger.info("AuthenticationClient.request_ticket()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(source) stream.pid(target) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REQUEST_TICKET, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.result() obj.ticket = stream.buffer() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AuthenticationClient.request_ticket -> done") return obj async def get_pid(self, username): logger.info("AuthenticationClient.get_pid()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(username) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) pid = stream.pid() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AuthenticationClient.get_pid -> done") return pid async def get_name(self, pid): logger.info("AuthenticationClient.get_name()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_NAME, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) name = stream.string() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AuthenticationClient.get_name -> done") return name async def login_with_context(self, login_data): logger.info("AuthenticationClient.login_with_context()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(login_data) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_LOGIN_WITH_CONTEXT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.result() obj.pid = stream.pid() obj.ticket = stream.buffer() obj.connection_data = stream.extract(RVConnectionData) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AuthenticationClient.login_with_context -> done") return obj class AuthenticationClientNX(AuthenticationProtocolNX): def __init__(self, client): self.settings = client.settings self.client = client async def validate_and_request_ticket(self, username): logger.info("AuthenticationClientNX.validate_and_request_ticket()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(username) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_VALIDATE_AND_REQUEST_TICKET, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.result() obj.pid = stream.pid() obj.ticket = stream.buffer() obj.connection_data = stream.extract(RVConnectionData) obj.server_name = stream.string() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AuthenticationClientNX.validate_and_request_ticket -> done") return obj async def validate_and_request_ticket_with_custom_data(self, username, extra_data): logger.info("AuthenticationClientNX.validate_and_request_ticket_with_custom_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(username) stream.anydata(extra_data) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_VALIDATE_AND_REQUEST_TICKET_WITH_CUSTOM_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.result() obj.pid = stream.pid() obj.ticket = stream.buffer() obj.connection_data = stream.extract(RVConnectionData) obj.server_name = stream.string() obj.source_key = stream.string() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AuthenticationClientNX.validate_and_request_ticket_with_custom_data -> done") return obj async def request_ticket(self, source, target): logger.info("AuthenticationClientNX.request_ticket()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(source) stream.pid(target) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REQUEST_TICKET, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.result() obj.ticket = stream.buffer() obj.key = stream.string() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AuthenticationClientNX.request_ticket -> done") return obj async def get_pid(self, username): logger.info("AuthenticationClientNX.get_pid()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(username) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) pid = stream.pid() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AuthenticationClientNX.get_pid -> done") return pid async def get_name(self, pid): logger.info("AuthenticationClientNX.get_name()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_NAME, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) name = stream.string() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AuthenticationClientNX.get_name -> done") return name async def validate_and_request_ticket_with_param(self, param): logger.info("AuthenticationClientNX.validate_and_request_ticket_with_param()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_VALIDATE_AND_REQUEST_TICKET_WITH_PARAM, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.extract(ValidateAndRequestTicketResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("AuthenticationClientNX.validate_and_request_ticket_with_param -> done") return result class AuthenticationServer(AuthenticationProtocol): def __init__(self): self.methods = { self.METHOD_LOGIN: self.handle_login, self.METHOD_LOGIN_EX: self.handle_login_ex, self.METHOD_REQUEST_TICKET: self.handle_request_ticket, self.METHOD_GET_PID: self.handle_get_pid, self.METHOD_GET_NAME: self.handle_get_name, self.METHOD_LOGIN_WITH_CONTEXT: self.handle_login_with_context, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on AuthenticationServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_login(self, client, input, output): logger.info("AuthenticationServer.login()") #--- request --- username = input.string() response = await self.login(client, username) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'pid', 'ticket', 'connection_data', 'server_name']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.result(response.result) output.pid(response.pid) output.buffer(response.ticket) output.add(response.connection_data) output.string(response.server_name) async def handle_login_ex(self, client, input, output): logger.info("AuthenticationServer.login_ex()") #--- request --- username = input.string() extra_data = input.anydata() response = await self.login_ex(client, username, extra_data) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'pid', 'ticket', 'connection_data', 'server_name']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.result(response.result) output.pid(response.pid) output.buffer(response.ticket) output.add(response.connection_data) output.string(response.server_name) async def handle_request_ticket(self, client, input, output): logger.info("AuthenticationServer.request_ticket()") #--- request --- source = input.pid() target = input.pid() response = await self.request_ticket(client, source, target) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'ticket']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.result(response.result) output.buffer(response.ticket) async def handle_get_pid(self, client, input, output): logger.info("AuthenticationServer.get_pid()") #--- request --- username = input.string() response = await self.get_pid(client, username) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.pid(response) async def handle_get_name(self, client, input, output): logger.info("AuthenticationServer.get_name()") #--- request --- pid = input.pid() response = await self.get_name(client, pid) #--- response --- if not isinstance(response, str): raise RuntimeError("Expected str, got %s" %response.__class__.__name__) output.string(response) async def handle_login_with_context(self, client, input, output): logger.info("AuthenticationServer.login_with_context()") #--- request --- login_data = input.anydata() response = await self.login_with_context(client, login_data) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'pid', 'ticket', 'connection_data']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.result(response.result) output.pid(response.pid) output.buffer(response.ticket) output.add(response.connection_data) async def login(self, *args): logger.warning("AuthenticationServer.login not implemented") raise common.RMCError("Core::NotImplemented") async def login_ex(self, *args): logger.warning("AuthenticationServer.login_ex not implemented") raise common.RMCError("Core::NotImplemented") async def request_ticket(self, *args): logger.warning("AuthenticationServer.request_ticket not implemented") raise common.RMCError("Core::NotImplemented") async def get_pid(self, *args): logger.warning("AuthenticationServer.get_pid not implemented") raise common.RMCError("Core::NotImplemented") async def get_name(self, *args): logger.warning("AuthenticationServer.get_name not implemented") raise common.RMCError("Core::NotImplemented") async def login_with_context(self, *args): logger.warning("AuthenticationServer.login_with_context not implemented") raise common.RMCError("Core::NotImplemented") class AuthenticationServerNX(AuthenticationProtocolNX): def __init__(self): self.methods = { self.METHOD_VALIDATE_AND_REQUEST_TICKET: self.handle_validate_and_request_ticket, self.METHOD_VALIDATE_AND_REQUEST_TICKET_WITH_CUSTOM_DATA: self.handle_validate_and_request_ticket_with_custom_data, self.METHOD_REQUEST_TICKET: self.handle_request_ticket, self.METHOD_GET_PID: self.handle_get_pid, self.METHOD_GET_NAME: self.handle_get_name, self.METHOD_VALIDATE_AND_REQUEST_TICKET_WITH_PARAM: self.handle_validate_and_request_ticket_with_param, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on AuthenticationServerNX: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_validate_and_request_ticket(self, client, input, output): logger.info("AuthenticationServerNX.validate_and_request_ticket()") #--- request --- username = input.string() response = await self.validate_and_request_ticket(client, username) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'pid', 'ticket', 'connection_data', 'server_name']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.result(response.result) output.pid(response.pid) output.buffer(response.ticket) output.add(response.connection_data) output.string(response.server_name) async def handle_validate_and_request_ticket_with_custom_data(self, client, input, output): logger.info("AuthenticationServerNX.validate_and_request_ticket_with_custom_data()") #--- request --- username = input.string() extra_data = input.anydata() response = await self.validate_and_request_ticket_with_custom_data(client, username, extra_data) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'pid', 'ticket', 'connection_data', 'server_name', 'source_key']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.result(response.result) output.pid(response.pid) output.buffer(response.ticket) output.add(response.connection_data) output.string(response.server_name) output.string(response.source_key) async def handle_request_ticket(self, client, input, output): logger.info("AuthenticationServerNX.request_ticket()") #--- request --- source = input.pid() target = input.pid() response = await self.request_ticket(client, source, target) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'ticket', 'key']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.result(response.result) output.buffer(response.ticket) output.string(response.key) async def handle_get_pid(self, client, input, output): logger.info("AuthenticationServerNX.get_pid()") #--- request --- username = input.string() response = await self.get_pid(client, username) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.pid(response) async def handle_get_name(self, client, input, output): logger.info("AuthenticationServerNX.get_name()") #--- request --- pid = input.pid() response = await self.get_name(client, pid) #--- response --- if not isinstance(response, str): raise RuntimeError("Expected str, got %s" %response.__class__.__name__) output.string(response) async def handle_validate_and_request_ticket_with_param(self, client, input, output): logger.info("AuthenticationServerNX.validate_and_request_ticket_with_param()") #--- request --- param = input.extract(ValidateAndRequestTicketParam) response = await self.validate_and_request_ticket_with_param(client, param) #--- response --- if not isinstance(response, ValidateAndRequestTicketResult): raise RuntimeError("Expected ValidateAndRequestTicketResult, got %s" %response.__class__.__name__) output.add(response) async def validate_and_request_ticket(self, *args): logger.warning("AuthenticationServerNX.validate_and_request_ticket not implemented") raise common.RMCError("Core::NotImplemented") async def validate_and_request_ticket_with_custom_data(self, *args): logger.warning("AuthenticationServerNX.validate_and_request_ticket_with_custom_data not implemented") raise common.RMCError("Core::NotImplemented") async def request_ticket(self, *args): logger.warning("AuthenticationServerNX.request_ticket not implemented") raise common.RMCError("Core::NotImplemented") async def get_pid(self, *args): logger.warning("AuthenticationServerNX.get_pid not implemented") raise common.RMCError("Core::NotImplemented") async def get_name(self, *args): logger.warning("AuthenticationServerNX.get_name not implemented") raise common.RMCError("Core::NotImplemented") async def validate_and_request_ticket_with_param(self, *args): logger.warning("AuthenticationServerNX.validate_and_request_ticket_with_param not implemented") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/backend.py ================================================ from nintendo.nex import rmc, authentication, kerberos, common from anynet import tls import contextlib import logging logger = logging.getLogger(__name__) class LoginResult: def __init__(self, pid, ticket, source_key, secure_station): self.pid = pid self.ticket = ticket self.source_key = source_key self.secure_station = secure_station class BackEndClient: def __init__(self, settings, client, host, port): self.settings = settings self.auth_client = client self.auth_host = host self.auth_port = port if self.settings["nex.version"] < 40000: self.auth_proto = authentication.AuthenticationClient(client) else: self.auth_proto = authentication.AuthenticationClientNX(client) if self.settings["kerberos.key_derivation"] == 0: self.key_derivation = kerberos.KeyDerivationOld(65000, 1024) else: self.key_derivation = kerberos.KeyDerivationNew(1, 1) @contextlib.asynccontextmanager async def login(self, username, password=None, auth_info=None, servers=[]): if self.settings["nex.version"] < 40000: result = await self.login_old(username, auth_info) elif self.settings["nex.version"] < 40400: result = await self.login_switch(username, auth_info) else: result = await self.login_with_param(username, auth_info) secure_station = result.secure_station kerberos_key = result.source_key if not kerberos_key: if password is None: raise ValueError("A password is required for this account") # Derive kerberos key from password kerberos_key = self.key_derivation.derive_key( password.encode(), result.pid ) # Decrypt ticket from login response ticket = kerberos.ClientTicket.decrypt(result.ticket, kerberos_key, self.settings) if ticket.target != secure_station["PID"]: # Request ticket for secure server response = await self.auth_proto.request_ticket( result.pid, secure_station["PID"] ) # Check for errors and decrypt ticket response.result.raise_if_error() ticket = kerberos.ClientTicket.decrypt(response.ticket, kerberos_key, self.settings) creds = kerberos.Credentials(ticket, result.pid, secure_station["CID"]) # The secure server may reside at the same # address as the authentication server host = secure_station["address"] port = secure_station["port"] if host == "0.0.0.1": host, port = self.auth_host, self.auth_port # Connect to secure server stream_id = secure_station["sid"] context = tls.TLSContext() async with rmc.connect(self.settings, host, port, stream_id, context, creds, servers) as client: yield client async def login_old(self, username, auth_info): if auth_info: response = await self.auth_proto.login_ex(username, auth_info) else: response = await self.auth_proto.login(username) response.result.raise_if_error() return LoginResult( response.pid, response.ticket, None, response.connection_data.main_station ) async def login_switch(self, username, auth_info): if auth_info: response = await self.auth_proto.validate_and_request_ticket_with_custom_data( username, auth_info ) response.result.raise_if_error() return LoginResult( response.pid, response.ticket, bytes.fromhex(response.source_key), response.connection_data.main_station ) else: response = await self.auth_proto.validate_and_request_ticket(username) response.result.raise_if_error() return LoginResult( response.pid, response.ticket, None, response.connection_data.main_station ) async def login_with_param(self, username, auth_info): param = authentication.ValidateAndRequestTicketParam() param.username = username if auth_info: param.data = auth_info else: param.data = common.NullData() param.nex_version = self.settings["nex.version"] param.client_version = self.settings["nex.client_version"] response = await self.auth_proto.validate_and_request_ticket_with_param(param) return LoginResult( response.pid, response.ticket, bytes.fromhex(response.source_key), response.server_url ) def login_guest(self): return self.login("guest", "MMQea3n!fsik") @contextlib.asynccontextmanager async def connect(settings, host, port): context = tls.TLSContext() async with rmc.connect(settings, host, port, context=context) as client: yield BackEndClient(settings, client, host, port) ================================================ FILE: nintendo/nex/common.py ================================================ from nintendo.nex.errors import error_names, error_codes from nintendo.nex import streams import datetime, time import logging logger = logging.getLogger(__name__) ERROR_MASK = 1 << 31 class RMCError(Exception): def __init__(self, code="Core::Unknown"): self.res = Result.error(code) def __str__(self): return str(self.res) def result(self): return self.res def name(self): return self.res.name() def code(self): return self.res.code() class Result: def __init__(self, code=0x10001): self.error_code = code def __str__(self): return "%s (0x%08X)" %(self.name(), self.code()) @staticmethod def success(code="Core::Unknown"): if type(code) == str: code = error_codes[code] return Result(code & ~ERROR_MASK) @staticmethod def error(code="Core::Unknown"): if type(code) == str: code = error_codes[code] return Result(code | ERROR_MASK) def is_success(self): return not self.error_code & ERROR_MASK def is_error(self): return bool(self.error_code & ERROR_MASK) def code(self): return self.error_code def name(self): if self.is_success(): return "success" return error_names.get(self.error_code & ~ERROR_MASK, "unknown error") def raise_if_error(self): if self.is_error(): raise RMCError(self.error_code) # Black magic going on here class Structure: def max_version(self, settings): return 0 def get_hierarchy(self): hierarchy = [] cls = self.__class__ while cls != Structure: hierarchy.append(cls) cls = cls.__bases__[0] return hierarchy[::-1] def encode(self, stream): hierarchy = self.get_hierarchy() for cls in hierarchy: if stream.settings["nex.struct_header"]: version = cls.max_version(self, stream.settings) substream = streams.StreamOut(stream.settings) cls.save(self, substream, version) stream.u8(version) stream.buffer(substream.get()) else: cls.save(self, stream, 0) def decode(self, stream): hierarchy = self.get_hierarchy() for cls in hierarchy: if stream.settings["nex.struct_header"]: max_version = cls.max_version(self, stream.settings) version = stream.u8() if version > max_version: logger.warning( "Struct %s version is higher than expected (%i > %i)", cls.__name__, version, max_version ) substream = stream.substream() cls.load(self, substream, version) if not substream.eof(): logger.warning( "Struct %s has unexpected size (got %i bytes, but only %i were read)", cls.__name__, substream.size(), substream.tell() ) else: cls.load(self, stream, 0) def load(self, stream, version): raise NotImplementedError("%s.load()" %self.__class__.__name__) def save(self, stream, version): raise NotImplementedError("%s.save()" %self.__class__.__name__) class Data(Structure): def save(self, stream, version): pass def load(self, stream, version): pass class DataHolder: object_map = {} def __init__(self): self.data = None def encode(self, stream): stream.string(self.data.__class__.__name__) substream = streams.StreamOut(stream.settings) substream.add(self.data) stream.u32(len(substream.get()) + 4) stream.buffer(substream.get()) def decode(self, stream): name = stream.string() substream = stream.substream().substream() self.data = substream.extract(self.object_map[name]) @classmethod def register(cls, object, name): cls.object_map[name] = object class NullData(Data): def save(self, stream, version): pass def load(self, stream, version): pass DataHolder.register(NullData, "NullData") class StationURL: str_params = ["address", "Uri", "Rsa", "Ra", "Ntrpa"] int_params = [ "port", "stream", "sid", "PID", "CID", "type", "RVCID", "natm", "natf", "upnp", "pmp", "probeinit", "PRID", "fastproberesponse", "NodeID", "R", "Rsp", "Rp", "Tpt", "Pl", "Ntrpp" ] def __init__(self, scheme="prudp", **kwargs): self.urlscheme = scheme self.params = kwargs def __repr__(self): params = ";".join( ["%s=%s" %(key, value) for key, value in self.params.items()] ) if self.urlscheme: return "%s:/%s" %(self.urlscheme, params) return params def __getitem__(self, field): if field in self.str_params: return str(self.params.get(field, "")) if field in self.int_params: return int(self.params.get(field, 0)) raise KeyError(field) def __setitem__(self, field, value): self.params[field] = value def scheme(self): return self.urlscheme def address(self): return self["address"], self["port"] def is_public(self): return bool(self["type"] & 2) def is_behind_nat(self): return bool(self["type"] & 1) def is_global(self): return self.is_public() and not self.is_behind_nat() def copy(self): return StationURL(self.urlscheme, **self.params) @classmethod def parse(cls, string): if string: scheme, fields = string.split(":/") params = {} if fields: params = dict(field.split("=") for field in fields.split(";")) return cls(scheme, **params) else: return cls() class DateTime: def __init__(self, value): self.val = value def second(self): return self.val & 63 def minute(self): return (self.val >> 6) & 63 def hour(self): return (self.val >> 12) & 31 def day(self): return (self.val >> 17) & 31 def month(self): return (self.val >> 22) & 15 def year(self): return self.val >> 26 def value(self): return self.val def standard_datetime(self): return datetime.datetime( self.year(), self.month(), self.day(), self.hour(), self.minute(), self.second(), tzinfo=datetime.UTC ) def timestamp(self): return int(self.standard_datetime().timestamp()) def __repr__(self): return "%i-%i-%i %i:%02i:%02i" %(self.day(), self.month(), self.year(), self.hour(), self.minute(), self.second()) @classmethod def never(cls): return cls(0) @classmethod def future(cls): return cls.make(9999, 12, 31, 23, 59, 59) @classmethod def make(cls, year, month=1, day=1, hour=0, minute=0, second=0): return cls(second | (minute << 6) | (hour << 12) | (day << 17) | (month << 22) | (year << 26)) @classmethod def fromtimestamp(cls, timestamp): dt = datetime.datetime.fromtimestamp(timestamp, datetime.UTC) return cls.make(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second) @classmethod def now(cls): return cls.fromtimestamp(time.time()) class ResultRange(Structure): def __init__(self, offset=0, size=10): self.offset = offset self.size = size def load(self, stream, version): self.offset = stream.u32() self.size = stream.u32() def save(self, stream, version): stream.u32(self.offset) stream.u32(self.size) ================================================ FILE: nintendo/nex/datastore.py ================================================ # This file was generated automatically by generate_protocols.py from nintendo.nex import notification, rmc, common, streams import logging logger = logging.getLogger(__name__) class DataStoreChangeMetaCompareParam(common.Structure): def __init__(self): super().__init__() self.comparison_flag = None self.name = None self.permission = DataStorePermission() self.delete_permission = DataStorePermission() self.period = None self.meta_binary = None self.tags = None self.referred_count = None self.data_type = None self.status = None def check_required(self, settings, version): for field in ['comparison_flag', 'name', 'period', 'meta_binary', 'tags', 'referred_count', 'data_type', 'status']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.comparison_flag = stream.u32() self.name = stream.string() self.permission = stream.extract(DataStorePermission) self.delete_permission = stream.extract(DataStorePermission) self.period = stream.u16() self.meta_binary = stream.qbuffer() self.tags = stream.list(stream.string) self.referred_count = stream.u32() self.data_type = stream.u16() self.status = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.comparison_flag) stream.string(self.name) stream.add(self.permission) stream.add(self.delete_permission) stream.u16(self.period) stream.qbuffer(self.meta_binary) stream.list(self.tags, stream.string) stream.u32(self.referred_count) stream.u16(self.data_type) stream.u8(self.status) class DataStoreChangeMetaParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.modifies_flag = None self.name = None self.permission = DataStorePermission() self.delete_permission = DataStorePermission() self.period = None self.meta_binary = None self.tags = None self.update_password = None self.referred_count = None self.data_type = None self.status = None self.compare_param = DataStoreChangeMetaCompareParam() self.persistence_target = DataStorePersistenceTarget() def check_required(self, settings, version): for field in ['data_id', 'modifies_flag', 'name', 'period', 'meta_binary', 'tags', 'update_password', 'referred_count', 'data_type', 'status']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.modifies_flag = stream.u32() self.name = stream.string() self.permission = stream.extract(DataStorePermission) self.delete_permission = stream.extract(DataStorePermission) self.period = stream.u16() self.meta_binary = stream.qbuffer() self.tags = stream.list(stream.string) self.update_password = stream.u64() self.referred_count = stream.u32() self.data_type = stream.u16() self.status = stream.u8() self.compare_param = stream.extract(DataStoreChangeMetaCompareParam) self.persistence_target = stream.extract(DataStorePersistenceTarget) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.modifies_flag) stream.string(self.name) stream.add(self.permission) stream.add(self.delete_permission) stream.u16(self.period) stream.qbuffer(self.meta_binary) stream.list(self.tags, stream.string) stream.u64(self.update_password) stream.u32(self.referred_count) stream.u16(self.data_type) stream.u8(self.status) stream.add(self.compare_param) stream.add(self.persistence_target) class DataStoreChangeMetaParamV1(common.Structure): def __init__(self): super().__init__() self.data_id = None self.modifies_flag = None self.name = None self.permission = DataStorePermission() self.delete_permission = DataStorePermission() self.period = None self.meta_binary = None self.tags = None self.update_password = None def check_required(self, settings, version): for field in ['data_id', 'modifies_flag', 'name', 'period', 'meta_binary', 'tags', 'update_password']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.modifies_flag = stream.u32() self.name = stream.string() self.permission = stream.extract(DataStorePermission) self.delete_permission = stream.extract(DataStorePermission) self.period = stream.u16() self.meta_binary = stream.qbuffer() self.tags = stream.list(stream.string) self.update_password = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.modifies_flag) stream.string(self.name) stream.add(self.permission) stream.add(self.delete_permission) stream.u16(self.period) stream.qbuffer(self.meta_binary) stream.list(self.tags, stream.string) stream.u64(self.update_password) class DataStoreCompletePostParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.success = None def check_required(self, settings, version): for field in ['data_id', 'success']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.success = stream.bool() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.bool(self.success) class DataStoreCompletePostParamV1(common.Structure): def __init__(self): super().__init__() self.data_id = None self.success = None def check_required(self, settings, version): for field in ['data_id', 'success']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u32() self.success = stream.bool() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.data_id) stream.bool(self.success) class DataStoreCompleteUpdateParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.version = None self.success = None def check_required(self, settings, version): for field in ['data_id', 'version', 'success']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.version = stream.u32() self.success = stream.bool() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.version) stream.bool(self.success) class DataStoreDeleteParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.update_password = None def check_required(self, settings, version): for field in ['data_id', 'update_password']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.update_password = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u64(self.update_password) class DataStoreGetMetaParam(common.Structure): def __init__(self): super().__init__() self.data_id = 0 self.persistence_target = DataStorePersistenceTarget() self.result_option = 0 self.access_password = 0 def check_required(self, settings, version): pass def load(self, stream, version): self.data_id = stream.u64() self.persistence_target = stream.extract(DataStorePersistenceTarget) self.result_option = stream.u8() self.access_password = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.add(self.persistence_target) stream.u8(self.result_option) stream.u64(self.access_password) class DataStoreGetNewArrivedNotificationsParam(common.Structure): def __init__(self): super().__init__() self.last_notification_id = None self.limit = None def check_required(self, settings, version): for field in ['last_notification_id', 'limit']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.last_notification_id = stream.u64() self.limit = stream.u16() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.last_notification_id) stream.u16(self.limit) class DataStoreGetNotificationUrlParam(common.Structure): def __init__(self): super().__init__() self.previous_url = None def check_required(self, settings, version): for field in ['previous_url']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.previous_url = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.previous_url) class DataStoreGetSpecificMetaParam(common.Structure): def __init__(self): super().__init__() self.data_ids = None def check_required(self, settings, version): for field in ['data_ids']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_ids = stream.list(stream.u64) def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.data_ids, stream.u64) class DataStoreGetSpecificMetaParamV1(common.Structure): def __init__(self): super().__init__() self.data_ids = None def check_required(self, settings, version): for field in ['data_ids']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_ids = stream.list(stream.u32) def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.data_ids, stream.u32) class DataStoreKeyValue(common.Structure): def __init__(self): super().__init__() self.key = None self.value = None def check_required(self, settings, version): for field in ['key', 'value']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.key = stream.string() self.value = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.key) stream.string(self.value) class DataStoreMetaInfo(common.Structure): def __init__(self): super().__init__() self.data_id = None self.owner_id = None self.size = None self.name = None self.data_type = None self.meta_binary = None self.permission = DataStorePermission() self.delete_permission = DataStorePermission() self.create_time = None self.update_time = None self.period = None self.status = None self.referred_count = None self.refer_data_id = None self.flag = None self.referred_time = None self.expire_time = None self.tags = None self.ratings = None def check_required(self, settings, version): for field in ['data_id', 'owner_id', 'size', 'name', 'data_type', 'meta_binary', 'create_time', 'update_time', 'period', 'status', 'referred_count', 'refer_data_id', 'flag', 'referred_time', 'expire_time', 'tags', 'ratings']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.owner_id = stream.pid() self.size = stream.u32() self.name = stream.string() self.data_type = stream.u16() self.meta_binary = stream.qbuffer() self.permission = stream.extract(DataStorePermission) self.delete_permission = stream.extract(DataStorePermission) self.create_time = stream.datetime() self.update_time = stream.datetime() self.period = stream.u16() self.status = stream.u8() self.referred_count = stream.u32() self.refer_data_id = stream.u32() self.flag = stream.u32() self.referred_time = stream.datetime() self.expire_time = stream.datetime() self.tags = stream.list(stream.string) self.ratings = stream.list(DataStoreRatingInfoWithSlot) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.pid(self.owner_id) stream.u32(self.size) stream.string(self.name) stream.u16(self.data_type) stream.qbuffer(self.meta_binary) stream.add(self.permission) stream.add(self.delete_permission) stream.datetime(self.create_time) stream.datetime(self.update_time) stream.u16(self.period) stream.u8(self.status) stream.u32(self.referred_count) stream.u32(self.refer_data_id) stream.u32(self.flag) stream.datetime(self.referred_time) stream.datetime(self.expire_time) stream.list(self.tags, stream.string) stream.list(self.ratings, stream.add) class DataStoreNotification(common.Structure): def __init__(self): super().__init__() self.notification_id = None self.data_id = None def check_required(self, settings, version): for field in ['notification_id', 'data_id']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.notification_id = stream.u64() self.data_id = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.notification_id) stream.u64(self.data_id) class DataStoreNotificationV1(common.Structure): def __init__(self): super().__init__() self.notification_id = None self.data_id = None def check_required(self, settings, version): for field in ['notification_id', 'data_id']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.notification_id = stream.u64() self.data_id = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.notification_id) stream.u32(self.data_id) class DataStorePasswordInfo(common.Structure): def __init__(self): super().__init__() self.data_id = None self.access_password = None self.update_password = None def check_required(self, settings, version): for field in ['data_id', 'access_password', 'update_password']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.access_password = stream.u64() self.update_password = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u64(self.access_password) stream.u64(self.update_password) class DataStorePermission(common.Structure): def __init__(self): super().__init__() self.permission = 3 self.recipients = [] def check_required(self, settings, version): pass def load(self, stream, version): self.permission = stream.u8() self.recipients = stream.list(stream.pid) def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.permission) stream.list(self.recipients, stream.pid) class DataStorePersistenceInfo(common.Structure): def __init__(self): super().__init__() self.owner_id = None self.slot_id = None self.data_id = None def check_required(self, settings, version): for field in ['owner_id', 'slot_id', 'data_id']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.owner_id = stream.pid() self.slot_id = stream.u16() self.data_id = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.owner_id) stream.u16(self.slot_id) stream.u64(self.data_id) class DataStorePersistenceInitParam(common.Structure): def __init__(self): super().__init__() self.persistence_id = 65535 self.delete_last_object = True def check_required(self, settings, version): pass def load(self, stream, version): self.persistence_id = stream.u16() self.delete_last_object = stream.bool() def save(self, stream, version): self.check_required(stream.settings, version) stream.u16(self.persistence_id) stream.bool(self.delete_last_object) class DataStorePersistenceTarget(common.Structure): def __init__(self): super().__init__() self.owner_id = 0 self.persistence_id = 65535 def check_required(self, settings, version): pass def load(self, stream, version): self.owner_id = stream.pid() self.persistence_id = stream.u16() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.owner_id) stream.u16(self.persistence_id) class DataStorePrepareGetParam(common.Structure): def __init__(self): super().__init__() self.data_id = 0 self.lock_id = 0 self.persistence_target = DataStorePersistenceTarget() self.access_password = 0 self.extra_data = [] def check_required(self, settings, version): if settings["nex.version"] >= 30500: pass def load(self, stream, version): self.data_id = stream.u64() self.lock_id = stream.u32() self.persistence_target = stream.extract(DataStorePersistenceTarget) self.access_password = stream.u64() if stream.settings["nex.version"] >= 30500: self.extra_data = stream.list(stream.string) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.lock_id) stream.add(self.persistence_target) stream.u64(self.access_password) if stream.settings["nex.version"] >= 30500: stream.list(self.extra_data, stream.string) class DataStorePrepareGetParamV1(common.Structure): def __init__(self): super().__init__() self.data_id = None self.lock_id = 0 def check_required(self, settings, version): for field in ['data_id']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u32() self.lock_id = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.data_id) stream.u32(self.lock_id) class DataStorePreparePostParam(common.Structure): def __init__(self): super().__init__() self.size = None self.name = None self.data_type = None self.meta_binary = None self.permission = DataStorePermission() self.delete_permission = DataStorePermission() self.flag = None self.period = None self.refer_data_id = 0 self.tags = [] self.rating_init_param = [] self.persistence_init_param = DataStorePersistenceInitParam() self.extra_data = None def check_required(self, settings, version): for field in ['size', 'name', 'data_type', 'meta_binary', 'flag', 'period']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) if settings["nex.version"] >= 30500: for field in ['extra_data']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.size = stream.u32() self.name = stream.string() self.data_type = stream.u16() self.meta_binary = stream.qbuffer() self.permission = stream.extract(DataStorePermission) self.delete_permission = stream.extract(DataStorePermission) self.flag = stream.u32() self.period = stream.u16() self.refer_data_id = stream.u32() self.tags = stream.list(stream.string) self.rating_init_param = stream.list(DataStoreRatingInitParamWithSlot) self.persistence_init_param = stream.extract(DataStorePersistenceInitParam) if stream.settings["nex.version"] >= 30500: self.extra_data = stream.list(stream.string) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.size) stream.string(self.name) stream.u16(self.data_type) stream.qbuffer(self.meta_binary) stream.add(self.permission) stream.add(self.delete_permission) stream.u32(self.flag) stream.u16(self.period) stream.u32(self.refer_data_id) stream.list(self.tags, stream.string) stream.list(self.rating_init_param, stream.add) stream.add(self.persistence_init_param) if stream.settings["nex.version"] >= 30500: stream.list(self.extra_data, stream.string) class DataStorePreparePostParamV1(common.Structure): def __init__(self): super().__init__() self.size = None self.name = None self.data_type = 0 self.meta_binary = b"" self.permission = DataStorePermission() self.delete_permission = DataStorePermission() self.flag = None self.period = None self.refer_data_id = 0 self.tags = None self.rating_init_param = None def check_required(self, settings, version): for field in ['size', 'name', 'flag', 'period', 'tags', 'rating_init_param']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.size = stream.u32() self.name = stream.string() self.data_type = stream.u16() self.meta_binary = stream.qbuffer() self.permission = stream.extract(DataStorePermission) self.delete_permission = stream.extract(DataStorePermission) self.flag = stream.u32() self.period = stream.u16() self.refer_data_id = stream.u32() self.tags = stream.list(stream.string) self.rating_init_param = stream.list(DataStoreRatingInitParamWithSlot) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.size) stream.string(self.name) stream.u16(self.data_type) stream.qbuffer(self.meta_binary) stream.add(self.permission) stream.add(self.delete_permission) stream.u32(self.flag) stream.u16(self.period) stream.u32(self.refer_data_id) stream.list(self.tags, stream.string) stream.list(self.rating_init_param, stream.add) class DataStorePrepareUpdateParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.size = None self.update_password = None self.extra_data = None def check_required(self, settings, version): for field in ['data_id', 'size', 'update_password', 'extra_data']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.size = stream.u32() self.update_password = stream.u64() self.extra_data = stream.list(stream.string) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.size) stream.u64(self.update_password) stream.list(self.extra_data, stream.string) class DataStoreRateObjectParam(common.Structure): def __init__(self): super().__init__() self.rating_value = None self.access_password = None def check_required(self, settings, version): for field in ['rating_value', 'access_password']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.rating_value = stream.s32() self.access_password = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.s32(self.rating_value) stream.u64(self.access_password) class DataStoreRatingInfo(common.Structure): def __init__(self): super().__init__() self.total_value = None self.count = None self.initial_value = None def check_required(self, settings, version): for field in ['total_value', 'count', 'initial_value']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.total_value = stream.s64() self.count = stream.u32() self.initial_value = stream.s64() def save(self, stream, version): self.check_required(stream.settings, version) stream.s64(self.total_value) stream.u32(self.count) stream.s64(self.initial_value) class DataStoreRatingInfoWithSlot(common.Structure): def __init__(self): super().__init__() self.slot = None self.info = DataStoreRatingInfo() def check_required(self, settings, version): for field in ['slot']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.slot = stream.u8() self.info = stream.extract(DataStoreRatingInfo) def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.slot) stream.add(self.info) class DataStoreRatingInitParam(common.Structure): def __init__(self): super().__init__() self.flag = None self.internal_flag = None self.lock_type = None self.initial_value = None self.range_min = None self.range_max = None self.period_hour = None self.period_duration = None def check_required(self, settings, version): for field in ['flag', 'internal_flag', 'lock_type', 'initial_value', 'range_min', 'range_max', 'period_hour', 'period_duration']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.flag = stream.u8() self.internal_flag = stream.u8() self.lock_type = stream.u8() self.initial_value = stream.s64() self.range_min = stream.s32() self.range_max = stream.s32() self.period_hour = stream.s8() self.period_duration = stream.s16() def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.flag) stream.u8(self.internal_flag) stream.u8(self.lock_type) stream.s64(self.initial_value) stream.s32(self.range_min) stream.s32(self.range_max) stream.s8(self.period_hour) stream.s16(self.period_duration) class DataStoreRatingInitParamWithSlot(common.Structure): def __init__(self): super().__init__() self.slot = None self.param = DataStoreRatingInitParam() def check_required(self, settings, version): for field in ['slot']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.slot = stream.s8() self.param = stream.extract(DataStoreRatingInitParam) def save(self, stream, version): self.check_required(stream.settings, version) stream.s8(self.slot) stream.add(self.param) class DataStoreRatingLog(common.Structure): def __init__(self): super().__init__() self.is_rated = None self.pid = None self.rating_value = None self.lock_expiration_time = None def check_required(self, settings, version): for field in ['is_rated', 'pid', 'rating_value', 'lock_expiration_time']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.is_rated = stream.bool() self.pid = stream.pid() self.rating_value = stream.s32() self.lock_expiration_time = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.bool(self.is_rated) stream.pid(self.pid) stream.s32(self.rating_value) stream.datetime(self.lock_expiration_time) class DataStoreRatingTarget(common.Structure): def __init__(self): super().__init__() self.data_id = None self.slot = None def check_required(self, settings, version): for field in ['data_id', 'slot']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.slot = stream.s8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.s8(self.slot) class DataStoreReqGetAdditionalMeta(common.Structure): def __init__(self): super().__init__() self.owner_id = None self.data_type = None self.version = None self.meta_binary = None def check_required(self, settings, version): for field in ['owner_id', 'data_type', 'version', 'meta_binary']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.owner_id = stream.pid() self.data_type = stream.u16() self.version = stream.u16() self.meta_binary = stream.qbuffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.owner_id) stream.u16(self.data_type) stream.u16(self.version) stream.qbuffer(self.meta_binary) class DataStoreReqGetInfo(common.Structure): def __init__(self): super().__init__() self.url = None self.headers = None self.size = None self.root_ca_cert = None self.data_id = None def check_required(self, settings, version): for field in ['url', 'headers', 'size', 'root_ca_cert']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) if settings["nex.version"] >= 30500: for field in ['data_id']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.url = stream.string() self.headers = stream.list(DataStoreKeyValue) self.size = stream.u32() self.root_ca_cert = stream.buffer() if stream.settings["nex.version"] >= 30500: self.data_id = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.url) stream.list(self.headers, stream.add) stream.u32(self.size) stream.buffer(self.root_ca_cert) if stream.settings["nex.version"] >= 30500: stream.u64(self.data_id) class DataStoreReqGetInfoV1(common.Structure): def __init__(self): super().__init__() self.url = None self.headers = None self.size = None self.root_ca_cert = None def check_required(self, settings, version): for field in ['url', 'headers', 'size', 'root_ca_cert']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.url = stream.string() self.headers = stream.list(DataStoreKeyValue) self.size = stream.u32() self.root_ca_cert = stream.buffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.url) stream.list(self.headers, stream.add) stream.u32(self.size) stream.buffer(self.root_ca_cert) class DataStoreReqGetNotificationUrlInfo(common.Structure): def __init__(self): super().__init__() self.url = None self.key = None self.query = None self.root_ca_cert = None def check_required(self, settings, version): for field in ['url', 'key', 'query', 'root_ca_cert']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.url = stream.string() self.key = stream.string() self.query = stream.string() self.root_ca_cert = stream.buffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.url) stream.string(self.key) stream.string(self.query) stream.buffer(self.root_ca_cert) class DataStoreReqPostInfo(common.Structure): def __init__(self): super().__init__() self.data_id = None self.url = None self.headers = None self.form = None self.root_ca_cert = None def check_required(self, settings, version): for field in ['data_id', 'url', 'headers', 'form', 'root_ca_cert']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.url = stream.string() self.headers = stream.list(DataStoreKeyValue) self.form = stream.list(DataStoreKeyValue) self.root_ca_cert = stream.buffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.string(self.url) stream.list(self.headers, stream.add) stream.list(self.form, stream.add) stream.buffer(self.root_ca_cert) class DataStoreReqPostInfoV1(common.Structure): def __init__(self): super().__init__() self.data_id = None self.url = None self.headers = None self.form = None self.root_ca_cert = None def check_required(self, settings, version): for field in ['data_id', 'url', 'headers', 'form', 'root_ca_cert']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u32() self.url = stream.string() self.headers = stream.list(DataStoreKeyValue) self.form = stream.list(DataStoreKeyValue) self.root_ca_cert = stream.buffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.data_id) stream.string(self.url) stream.list(self.headers, stream.add) stream.list(self.form, stream.add) stream.buffer(self.root_ca_cert) class DataStoreReqUpdateInfo(common.Structure): def __init__(self): super().__init__() self.version = None self.url = None self.headers = None self.form = None self.root_ca_cert = None def check_required(self, settings, version): for field in ['version', 'url', 'headers', 'form', 'root_ca_cert']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.version = stream.u32() self.url = stream.string() self.headers = stream.list(DataStoreKeyValue) self.form = stream.list(DataStoreKeyValue) self.root_ca_cert = stream.buffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.version) stream.string(self.url) stream.list(self.headers, stream.add) stream.list(self.form, stream.add) stream.buffer(self.root_ca_cert) class DataStoreSearchParam(common.Structure): def __init__(self): super().__init__() self.search_target = 1 self.owner_ids = [] self.owner_type = 0 self.destination_ids = [] self.data_type = 65535 self.created_after = common.DateTime(671076024059) self.created_before = common.DateTime(671076024059) self.updated_after = common.DateTime(671076024059) self.updated_before = common.DateTime(671076024059) self.refer_data_id = 0 self.tags = [] self.result_order_column = 0 self.result_order = 0 self.result_range = common.ResultRange() self.result_option = 0 self.minimal_rating_frequency = 0 self.use_cache = False self.total_count_enabled = True self.data_types = [] def check_required(self, settings, version): pass def load(self, stream, version): self.search_target = stream.u8() self.owner_ids = stream.list(stream.pid) self.owner_type = stream.u8() self.destination_ids = stream.list(stream.u64) self.data_type = stream.u16() self.created_after = stream.datetime() self.created_before = stream.datetime() self.updated_after = stream.datetime() self.updated_before = stream.datetime() self.refer_data_id = stream.u32() self.tags = stream.list(stream.string) self.result_order_column = stream.u8() self.result_order = stream.u8() self.result_range = stream.extract(common.ResultRange) self.result_option = stream.u8() self.minimal_rating_frequency = stream.u32() self.use_cache = stream.bool() self.total_count_enabled = stream.bool() self.data_types = stream.list(stream.u16) def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.search_target) stream.list(self.owner_ids, stream.pid) stream.u8(self.owner_type) stream.list(self.destination_ids, stream.u64) stream.u16(self.data_type) stream.datetime(self.created_after) stream.datetime(self.created_before) stream.datetime(self.updated_after) stream.datetime(self.updated_before) stream.u32(self.refer_data_id) stream.list(self.tags, stream.string) stream.u8(self.result_order_column) stream.u8(self.result_order) stream.add(self.result_range) stream.u8(self.result_option) stream.u32(self.minimal_rating_frequency) stream.bool(self.use_cache) stream.bool(self.total_count_enabled) stream.list(self.data_types, stream.u16) class DataStoreSearchResult(common.Structure): def __init__(self): super().__init__() self.total_count = None self.result = None self.total_count_type = None def check_required(self, settings, version): for field in ['total_count', 'result', 'total_count_type']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.total_count = stream.u32() self.result = stream.list(DataStoreMetaInfo) self.total_count_type = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.total_count) stream.list(self.result, stream.add) stream.u8(self.total_count_type) class DataStoreSpecificMetaInfo(common.Structure): def __init__(self): super().__init__() self.data_id = None self.owner_id = None self.size = None self.data_type = None self.version = None def check_required(self, settings, version): for field in ['data_id', 'owner_id', 'size', 'data_type', 'version']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.owner_id = stream.pid() self.size = stream.u32() self.data_type = stream.u16() self.version = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.pid(self.owner_id) stream.u32(self.size) stream.u16(self.data_type) stream.u32(self.version) class DataStoreSpecificMetaInfoV1(common.Structure): def __init__(self): super().__init__() self.data_id = None self.owner_id = None self.size = None self.data_type = None self.version = None def check_required(self, settings, version): for field in ['data_id', 'owner_id', 'size', 'data_type', 'version']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u32() self.owner_id = stream.pid() self.size = stream.u32() self.data_type = stream.u16() self.version = stream.u16() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.data_id) stream.pid(self.owner_id) stream.u32(self.size) stream.u16(self.data_type) stream.u16(self.version) class DataStoreTouchObjectParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.lock_id = None self.access_password = None def check_required(self, settings, version): for field in ['data_id', 'lock_id', 'access_password']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.lock_id = stream.u32() self.access_password = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.lock_id) stream.u64(self.access_password) class DataStoreProtocol: METHOD_PREPARE_GET_OBJECT_V1 = 1 METHOD_PREPARE_POST_OBJECT_V1 = 2 METHOD_COMPLETE_POST_OBJECT_V1 = 3 METHOD_DELETE_OBJECT = 4 METHOD_DELETE_OBJECTS = 5 METHOD_CHANGE_META_V1 = 6 METHOD_CHANGE_METAS_V1 = 7 METHOD_GET_META = 8 METHOD_GET_METAS = 9 METHOD_PREPARE_UPDATE_OBJECT = 10 METHOD_COMPLETE_UPDATE_OBJECT = 11 METHOD_SEARCH_OBJECT = 12 METHOD_GET_NOTIFICATION_URL = 13 METHOD_GET_NEW_ARRIVED_NOTIFICATIONS_V1 = 14 METHOD_RATE_OBJECT = 15 METHOD_GET_RATING = 16 METHOD_GET_RATINGS = 17 METHOD_RESET_RATING = 18 METHOD_RESET_RATINGS = 19 METHOD_GET_SPECIFIC_META_V1 = 20 METHOD_POST_META_BINARY = 21 METHOD_TOUCH_OBJECT = 22 METHOD_GET_RATING_WITH_LOG = 23 METHOD_PREPARE_POST_OBJECT = 24 METHOD_PREPARE_GET_OBJECT = 25 METHOD_COMPLETE_POST_OBJECT = 26 METHOD_GET_NEW_ARRIVED_NOTIFICATIONS = 27 METHOD_GET_SPECIFIC_META = 28 METHOD_GET_PERSISTENCE_INFO = 29 METHOD_GET_PERSISTENCE_INFOS = 30 METHOD_PERPETUATE_OBJECT = 31 METHOD_UNPERPETUATE_OBJECT = 32 METHOD_PREPARE_GET_OBJECT_OR_META_BINARY = 33 METHOD_GET_PASSWORD_INFO = 34 METHOD_GET_PASSWORD_INFOS = 35 METHOD_GET_METAS_MULTIPLE_PARAM = 36 METHOD_COMPLETE_POST_OBJECTS = 37 METHOD_CHANGE_META = 38 METHOD_CHANGE_METAS = 39 METHOD_RATE_OBJECTS = 40 METHOD_POST_META_BINARY_WITH_DATA_ID = 41 METHOD_POST_META_BINARIES_WITH_DATA_ID = 42 METHOD_RATE_OBJECT_WITH_POSTING = 43 METHOD_RATE_OBJECTS_WITH_POSTING = 44 METHOD_GET_OBJECT_INFOS = 45 METHOD_SEARCH_OBJECT_LIGHT = 46 PROTOCOL_ID = 0x73 class DataStoreClient(DataStoreProtocol): def __init__(self, client): self.settings = client.settings self.client = client async def prepare_get_object_v1(self, param): logger.info("DataStoreClient.prepare_get_object_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PREPARE_GET_OBJECT_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreReqGetInfoV1) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.prepare_get_object_v1 -> done") return info async def prepare_post_object_v1(self, param): logger.info("DataStoreClient.prepare_post_object_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PREPARE_POST_OBJECT_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreReqPostInfoV1) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.prepare_post_object_v1 -> done") return info async def complete_post_object_v1(self, param): logger.info("DataStoreClient.complete_post_object_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_COMPLETE_POST_OBJECT_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.complete_post_object_v1 -> done") async def delete_object(self, param): logger.info("DataStoreClient.delete_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.delete_object -> done") async def delete_objects(self, param, transactional): logger.info("DataStoreClient.delete_objects()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(param, stream.add) stream.bool(transactional) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_OBJECTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.delete_objects -> done") return results async def change_meta_v1(self, param): logger.info("DataStoreClient.change_meta_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CHANGE_META_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.change_meta_v1 -> done") async def change_metas_v1(self, data_ids, param, transactional): logger.info("DataStoreClient.change_metas_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) stream.list(param, stream.add) stream.bool(transactional) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CHANGE_METAS_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.change_metas_v1 -> done") return results async def get_meta(self, param): logger.info("DataStoreClient.get_meta()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_META, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreMetaInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.get_meta -> done") return info async def get_metas(self, data_ids, param): logger.info("DataStoreClient.get_metas()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_METAS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.info = stream.list(DataStoreMetaInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.get_metas -> done") return obj async def prepare_update_object(self, param): logger.info("DataStoreClient.prepare_update_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PREPARE_UPDATE_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreReqUpdateInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.prepare_update_object -> done") return info async def complete_update_object(self, param): logger.info("DataStoreClient.complete_update_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_COMPLETE_UPDATE_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.complete_update_object -> done") async def search_object(self, param): logger.info("DataStoreClient.search_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.extract(DataStoreSearchResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.search_object -> done") return result async def get_notification_url(self, param): logger.info("DataStoreClient.get_notification_url()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_NOTIFICATION_URL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreReqGetNotificationUrlInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.get_notification_url -> done") return info async def get_new_arrived_notifications_v1(self, param): logger.info("DataStoreClient.get_new_arrived_notifications_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_NEW_ARRIVED_NOTIFICATIONS_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.list(DataStoreNotificationV1) obj.has_next = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.get_new_arrived_notifications_v1 -> done") return obj async def rate_object(self, target, param, fetch_ratings): logger.info("DataStoreClient.rate_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) stream.add(param) stream.bool(fetch_ratings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RATE_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreRatingInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.rate_object -> done") return info async def get_rating(self, target, access_password): logger.info("DataStoreClient.get_rating()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) stream.u64(access_password) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RATING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) rating = stream.extract(DataStoreRatingInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.get_rating -> done") return rating async def get_ratings(self, data_ids, access_password): logger.info("DataStoreClient.get_ratings()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) stream.u64(access_password) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RATINGS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.ratings = stream.list(lambda: stream.list(DataStoreRatingInfoWithSlot)) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.get_ratings -> done") return obj async def reset_rating(self, target, update_password): logger.info("DataStoreClient.reset_rating()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) stream.u64(update_password) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RESET_RATING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.reset_rating -> done") async def reset_ratings(self, data_ids, transactional): logger.info("DataStoreClient.reset_ratings()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) stream.bool(transactional) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RESET_RATINGS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.reset_ratings -> done") return results async def get_specific_meta_v1(self, param): logger.info("DataStoreClient.get_specific_meta_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SPECIFIC_META_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) infos = stream.list(DataStoreSpecificMetaInfoV1) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.get_specific_meta_v1 -> done") return infos async def post_meta_binary(self, param): logger.info("DataStoreClient.post_meta_binary()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_POST_META_BINARY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) data_id = stream.u64() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.post_meta_binary -> done") return data_id async def touch_object(self, param): logger.info("DataStoreClient.touch_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_TOUCH_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.touch_object -> done") async def get_rating_with_log(self, target, access_password): logger.info("DataStoreClient.get_rating_with_log()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) stream.u64(access_password) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RATING_WITH_LOG, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.rating = stream.extract(DataStoreRatingInfo) obj.log = stream.extract(DataStoreRatingLog) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.get_rating_with_log -> done") return obj async def prepare_post_object(self, param): logger.info("DataStoreClient.prepare_post_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PREPARE_POST_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreReqPostInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.prepare_post_object -> done") return info async def prepare_get_object(self, param): logger.info("DataStoreClient.prepare_get_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PREPARE_GET_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreReqGetInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.prepare_get_object -> done") return info async def complete_post_object(self, param): logger.info("DataStoreClient.complete_post_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_COMPLETE_POST_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.complete_post_object -> done") async def get_new_arrived_notifications(self, param): logger.info("DataStoreClient.get_new_arrived_notifications()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_NEW_ARRIVED_NOTIFICATIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.list(DataStoreNotification) obj.has_next = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.get_new_arrived_notifications -> done") return obj async def get_specific_meta(self, param): logger.info("DataStoreClient.get_specific_meta()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SPECIFIC_META, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) infos = stream.list(DataStoreSpecificMetaInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.get_specific_meta -> done") return infos async def get_persistence_info(self, owner_id, slot_id): logger.info("DataStoreClient.get_persistence_info()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(owner_id) stream.u16(slot_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PERSISTENCE_INFO, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStorePersistenceInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.get_persistence_info -> done") return info async def get_persistence_infos(self, owner_id, slot_ids): logger.info("DataStoreClient.get_persistence_infos()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(owner_id) stream.list(slot_ids, stream.u16) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PERSISTENCE_INFOS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.infos = stream.list(DataStorePersistenceInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.get_persistence_infos -> done") return obj async def perpetuate_object(self, persistence_slot_id, data_id, delete_last_object): logger.info("DataStoreClient.perpetuate_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.u16(persistence_slot_id) stream.u64(data_id) stream.bool(delete_last_object) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PERPETUATE_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.perpetuate_object -> done") async def unperpetuate_object(self, persistence_slot_id, delete_last_object): logger.info("DataStoreClient.unperpetuate_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.u16(persistence_slot_id) stream.bool(delete_last_object) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UNPERPETUATE_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.unperpetuate_object -> done") async def prepare_get_object_or_meta_binary(self, param): logger.info("DataStoreClient.prepare_get_object_or_meta_binary()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PREPARE_GET_OBJECT_OR_META_BINARY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.get_info = stream.extract(DataStoreReqGetInfo) obj.additional_meta = stream.extract(DataStoreReqGetAdditionalMeta) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.prepare_get_object_or_meta_binary -> done") return obj async def get_password_info(self, data_id): logger.info("DataStoreClient.get_password_info()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(data_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PASSWORD_INFO, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStorePasswordInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.get_password_info -> done") return info async def get_password_infos(self, data_ids): logger.info("DataStoreClient.get_password_infos()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PASSWORD_INFOS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.infos = stream.list(DataStorePasswordInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.get_password_infos -> done") return obj async def get_metas_multiple_param(self, params): logger.info("DataStoreClient.get_metas_multiple_param()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(params, stream.add) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_METAS_MULTIPLE_PARAM, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.infos = stream.list(DataStoreMetaInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.get_metas_multiple_param -> done") return obj async def complete_post_objects(self, data_ids): logger.info("DataStoreClient.complete_post_objects()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_COMPLETE_POST_OBJECTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.complete_post_objects -> done") async def change_meta(self, param): logger.info("DataStoreClient.change_meta()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CHANGE_META, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.change_meta -> done") async def change_metas(self, data_ids, param, transactional): logger.info("DataStoreClient.change_metas()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) stream.list(param, stream.add) stream.bool(transactional) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CHANGE_METAS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.change_metas -> done") return results async def rate_objects(self, targets, param, transactional, fetch_ratings): logger.info("DataStoreClient.rate_objects()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(targets, stream.add) stream.list(param, stream.add) stream.bool(transactional) stream.bool(fetch_ratings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RATE_OBJECTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.infos = stream.list(DataStoreRatingInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.rate_objects -> done") return obj async def post_meta_binary_with_data_id(self, data_id, param): logger.info("DataStoreClient.post_meta_binary_with_data_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(data_id) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_POST_META_BINARY_WITH_DATA_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.post_meta_binary_with_data_id -> done") async def post_meta_binaries_with_data_id(self, data_ids, param, transactional): logger.info("DataStoreClient.post_meta_binaries_with_data_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) stream.list(param, stream.add) stream.bool(transactional) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_POST_META_BINARIES_WITH_DATA_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.post_meta_binaries_with_data_id -> done") return results async def rate_object_with_posting(self, target, rate_param, post_param, fetch_ratings): logger.info("DataStoreClient.rate_object_with_posting()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) stream.add(rate_param) stream.add(post_param) stream.bool(fetch_ratings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RATE_OBJECT_WITH_POSTING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreRatingInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.rate_object_with_posting -> done") return info async def rate_objects_with_posting(self, targets, rate_param, post_param, transactional, fetch_ratings): logger.info("DataStoreClient.rate_objects_with_posting()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(targets, stream.add) stream.list(rate_param, stream.add) stream.list(post_param, stream.add) stream.bool(transactional) stream.bool(fetch_ratings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RATE_OBJECTS_WITH_POSTING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.ratings = stream.list(DataStoreRatingInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.rate_objects_with_posting -> done") return obj async def get_object_infos(self, data_ids): logger.info("DataStoreClient.get_object_infos()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_OBJECT_INFOS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.infos = stream.list(DataStoreReqGetInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.get_object_infos -> done") return obj async def search_object_light(self, param): logger.info("DataStoreClient.search_object_light()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_OBJECT_LIGHT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.extract(DataStoreSearchResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClient.search_object_light -> done") return result class DataStoreServer(DataStoreProtocol): def __init__(self): self.methods = { self.METHOD_PREPARE_GET_OBJECT_V1: self.handle_prepare_get_object_v1, self.METHOD_PREPARE_POST_OBJECT_V1: self.handle_prepare_post_object_v1, self.METHOD_COMPLETE_POST_OBJECT_V1: self.handle_complete_post_object_v1, self.METHOD_DELETE_OBJECT: self.handle_delete_object, self.METHOD_DELETE_OBJECTS: self.handle_delete_objects, self.METHOD_CHANGE_META_V1: self.handle_change_meta_v1, self.METHOD_CHANGE_METAS_V1: self.handle_change_metas_v1, self.METHOD_GET_META: self.handle_get_meta, self.METHOD_GET_METAS: self.handle_get_metas, self.METHOD_PREPARE_UPDATE_OBJECT: self.handle_prepare_update_object, self.METHOD_COMPLETE_UPDATE_OBJECT: self.handle_complete_update_object, self.METHOD_SEARCH_OBJECT: self.handle_search_object, self.METHOD_GET_NOTIFICATION_URL: self.handle_get_notification_url, self.METHOD_GET_NEW_ARRIVED_NOTIFICATIONS_V1: self.handle_get_new_arrived_notifications_v1, self.METHOD_RATE_OBJECT: self.handle_rate_object, self.METHOD_GET_RATING: self.handle_get_rating, self.METHOD_GET_RATINGS: self.handle_get_ratings, self.METHOD_RESET_RATING: self.handle_reset_rating, self.METHOD_RESET_RATINGS: self.handle_reset_ratings, self.METHOD_GET_SPECIFIC_META_V1: self.handle_get_specific_meta_v1, self.METHOD_POST_META_BINARY: self.handle_post_meta_binary, self.METHOD_TOUCH_OBJECT: self.handle_touch_object, self.METHOD_GET_RATING_WITH_LOG: self.handle_get_rating_with_log, self.METHOD_PREPARE_POST_OBJECT: self.handle_prepare_post_object, self.METHOD_PREPARE_GET_OBJECT: self.handle_prepare_get_object, self.METHOD_COMPLETE_POST_OBJECT: self.handle_complete_post_object, self.METHOD_GET_NEW_ARRIVED_NOTIFICATIONS: self.handle_get_new_arrived_notifications, self.METHOD_GET_SPECIFIC_META: self.handle_get_specific_meta, self.METHOD_GET_PERSISTENCE_INFO: self.handle_get_persistence_info, self.METHOD_GET_PERSISTENCE_INFOS: self.handle_get_persistence_infos, self.METHOD_PERPETUATE_OBJECT: self.handle_perpetuate_object, self.METHOD_UNPERPETUATE_OBJECT: self.handle_unperpetuate_object, self.METHOD_PREPARE_GET_OBJECT_OR_META_BINARY: self.handle_prepare_get_object_or_meta_binary, self.METHOD_GET_PASSWORD_INFO: self.handle_get_password_info, self.METHOD_GET_PASSWORD_INFOS: self.handle_get_password_infos, self.METHOD_GET_METAS_MULTIPLE_PARAM: self.handle_get_metas_multiple_param, self.METHOD_COMPLETE_POST_OBJECTS: self.handle_complete_post_objects, self.METHOD_CHANGE_META: self.handle_change_meta, self.METHOD_CHANGE_METAS: self.handle_change_metas, self.METHOD_RATE_OBJECTS: self.handle_rate_objects, self.METHOD_POST_META_BINARY_WITH_DATA_ID: self.handle_post_meta_binary_with_data_id, self.METHOD_POST_META_BINARIES_WITH_DATA_ID: self.handle_post_meta_binaries_with_data_id, self.METHOD_RATE_OBJECT_WITH_POSTING: self.handle_rate_object_with_posting, self.METHOD_RATE_OBJECTS_WITH_POSTING: self.handle_rate_objects_with_posting, self.METHOD_GET_OBJECT_INFOS: self.handle_get_object_infos, self.METHOD_SEARCH_OBJECT_LIGHT: self.handle_search_object_light, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on DataStoreServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_prepare_get_object_v1(self, client, input, output): logger.info("DataStoreServer.prepare_get_object_v1()") #--- request --- param = input.extract(DataStorePrepareGetParamV1) response = await self.prepare_get_object_v1(client, param) #--- response --- if not isinstance(response, DataStoreReqGetInfoV1): raise RuntimeError("Expected DataStoreReqGetInfoV1, got %s" %response.__class__.__name__) output.add(response) async def handle_prepare_post_object_v1(self, client, input, output): logger.info("DataStoreServer.prepare_post_object_v1()") #--- request --- param = input.extract(DataStorePreparePostParamV1) response = await self.prepare_post_object_v1(client, param) #--- response --- if not isinstance(response, DataStoreReqPostInfoV1): raise RuntimeError("Expected DataStoreReqPostInfoV1, got %s" %response.__class__.__name__) output.add(response) async def handle_complete_post_object_v1(self, client, input, output): logger.info("DataStoreServer.complete_post_object_v1()") #--- request --- param = input.extract(DataStoreCompletePostParamV1) await self.complete_post_object_v1(client, param) async def handle_delete_object(self, client, input, output): logger.info("DataStoreServer.delete_object()") #--- request --- param = input.extract(DataStoreDeleteParam) await self.delete_object(client, param) async def handle_delete_objects(self, client, input, output): logger.info("DataStoreServer.delete_objects()") #--- request --- param = input.list(DataStoreDeleteParam) transactional = input.bool() response = await self.delete_objects(client, param, transactional) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.result) async def handle_change_meta_v1(self, client, input, output): logger.info("DataStoreServer.change_meta_v1()") #--- request --- param = input.extract(DataStoreChangeMetaParamV1) await self.change_meta_v1(client, param) async def handle_change_metas_v1(self, client, input, output): logger.info("DataStoreServer.change_metas_v1()") #--- request --- data_ids = input.list(input.u64) param = input.list(DataStoreChangeMetaParamV1) transactional = input.bool() response = await self.change_metas_v1(client, data_ids, param, transactional) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.result) async def handle_get_meta(self, client, input, output): logger.info("DataStoreServer.get_meta()") #--- request --- param = input.extract(DataStoreGetMetaParam) response = await self.get_meta(client, param) #--- response --- if not isinstance(response, DataStoreMetaInfo): raise RuntimeError("Expected DataStoreMetaInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_metas(self, client, input, output): logger.info("DataStoreServer.get_metas()") #--- request --- data_ids = input.list(input.u64) param = input.extract(DataStoreGetMetaParam) response = await self.get_metas(client, data_ids, param) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['info', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.info, output.add) output.list(response.results, output.result) async def handle_prepare_update_object(self, client, input, output): logger.info("DataStoreServer.prepare_update_object()") #--- request --- param = input.extract(DataStorePrepareUpdateParam) response = await self.prepare_update_object(client, param) #--- response --- if not isinstance(response, DataStoreReqUpdateInfo): raise RuntimeError("Expected DataStoreReqUpdateInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_complete_update_object(self, client, input, output): logger.info("DataStoreServer.complete_update_object()") #--- request --- param = input.extract(DataStoreCompleteUpdateParam) await self.complete_update_object(client, param) async def handle_search_object(self, client, input, output): logger.info("DataStoreServer.search_object()") #--- request --- param = input.extract(DataStoreSearchParam) response = await self.search_object(client, param) #--- response --- if not isinstance(response, DataStoreSearchResult): raise RuntimeError("Expected DataStoreSearchResult, got %s" %response.__class__.__name__) output.add(response) async def handle_get_notification_url(self, client, input, output): logger.info("DataStoreServer.get_notification_url()") #--- request --- param = input.extract(DataStoreGetNotificationUrlParam) response = await self.get_notification_url(client, param) #--- response --- if not isinstance(response, DataStoreReqGetNotificationUrlInfo): raise RuntimeError("Expected DataStoreReqGetNotificationUrlInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_new_arrived_notifications_v1(self, client, input, output): logger.info("DataStoreServer.get_new_arrived_notifications_v1()") #--- request --- param = input.extract(DataStoreGetNewArrivedNotificationsParam) response = await self.get_new_arrived_notifications_v1(client, param) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'has_next']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.result, output.add) output.bool(response.has_next) async def handle_rate_object(self, client, input, output): logger.info("DataStoreServer.rate_object()") #--- request --- target = input.extract(DataStoreRatingTarget) param = input.extract(DataStoreRateObjectParam) fetch_ratings = input.bool() response = await self.rate_object(client, target, param, fetch_ratings) #--- response --- if not isinstance(response, DataStoreRatingInfo): raise RuntimeError("Expected DataStoreRatingInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_rating(self, client, input, output): logger.info("DataStoreServer.get_rating()") #--- request --- target = input.extract(DataStoreRatingTarget) access_password = input.u64() response = await self.get_rating(client, target, access_password) #--- response --- if not isinstance(response, DataStoreRatingInfo): raise RuntimeError("Expected DataStoreRatingInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_ratings(self, client, input, output): logger.info("DataStoreServer.get_ratings()") #--- request --- data_ids = input.list(input.u64) access_password = input.u64() response = await self.get_ratings(client, data_ids, access_password) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['ratings', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.ratings, lambda x: output.list(x, output.add)) output.list(response.results, output.result) async def handle_reset_rating(self, client, input, output): logger.info("DataStoreServer.reset_rating()") #--- request --- target = input.extract(DataStoreRatingTarget) update_password = input.u64() await self.reset_rating(client, target, update_password) async def handle_reset_ratings(self, client, input, output): logger.info("DataStoreServer.reset_ratings()") #--- request --- data_ids = input.list(input.u64) transactional = input.bool() response = await self.reset_ratings(client, data_ids, transactional) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.result) async def handle_get_specific_meta_v1(self, client, input, output): logger.info("DataStoreServer.get_specific_meta_v1()") #--- request --- param = input.extract(DataStoreGetSpecificMetaParamV1) response = await self.get_specific_meta_v1(client, param) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_post_meta_binary(self, client, input, output): logger.info("DataStoreServer.post_meta_binary()") #--- request --- param = input.extract(DataStorePreparePostParam) response = await self.post_meta_binary(client, param) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u64(response) async def handle_touch_object(self, client, input, output): logger.info("DataStoreServer.touch_object()") #--- request --- param = input.extract(DataStoreTouchObjectParam) await self.touch_object(client, param) async def handle_get_rating_with_log(self, client, input, output): logger.info("DataStoreServer.get_rating_with_log()") #--- request --- target = input.extract(DataStoreRatingTarget) access_password = input.u64() response = await self.get_rating_with_log(client, target, access_password) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['rating', 'log']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.add(response.rating) output.add(response.log) async def handle_prepare_post_object(self, client, input, output): logger.info("DataStoreServer.prepare_post_object()") #--- request --- param = input.extract(DataStorePreparePostParam) response = await self.prepare_post_object(client, param) #--- response --- if not isinstance(response, DataStoreReqPostInfo): raise RuntimeError("Expected DataStoreReqPostInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_prepare_get_object(self, client, input, output): logger.info("DataStoreServer.prepare_get_object()") #--- request --- param = input.extract(DataStorePrepareGetParam) response = await self.prepare_get_object(client, param) #--- response --- if not isinstance(response, DataStoreReqGetInfo): raise RuntimeError("Expected DataStoreReqGetInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_complete_post_object(self, client, input, output): logger.info("DataStoreServer.complete_post_object()") #--- request --- param = input.extract(DataStoreCompletePostParam) await self.complete_post_object(client, param) async def handle_get_new_arrived_notifications(self, client, input, output): logger.info("DataStoreServer.get_new_arrived_notifications()") #--- request --- param = input.extract(DataStoreGetNewArrivedNotificationsParam) response = await self.get_new_arrived_notifications(client, param) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'has_next']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.result, output.add) output.bool(response.has_next) async def handle_get_specific_meta(self, client, input, output): logger.info("DataStoreServer.get_specific_meta()") #--- request --- param = input.extract(DataStoreGetSpecificMetaParam) response = await self.get_specific_meta(client, param) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_persistence_info(self, client, input, output): logger.info("DataStoreServer.get_persistence_info()") #--- request --- owner_id = input.pid() slot_id = input.u16() response = await self.get_persistence_info(client, owner_id, slot_id) #--- response --- if not isinstance(response, DataStorePersistenceInfo): raise RuntimeError("Expected DataStorePersistenceInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_persistence_infos(self, client, input, output): logger.info("DataStoreServer.get_persistence_infos()") #--- request --- owner_id = input.pid() slot_ids = input.list(input.u16) response = await self.get_persistence_infos(client, owner_id, slot_ids) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['infos', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.infos, output.add) output.list(response.results, output.result) async def handle_perpetuate_object(self, client, input, output): logger.info("DataStoreServer.perpetuate_object()") #--- request --- persistence_slot_id = input.u16() data_id = input.u64() delete_last_object = input.bool() await self.perpetuate_object(client, persistence_slot_id, data_id, delete_last_object) async def handle_unperpetuate_object(self, client, input, output): logger.info("DataStoreServer.unperpetuate_object()") #--- request --- persistence_slot_id = input.u16() delete_last_object = input.bool() await self.unperpetuate_object(client, persistence_slot_id, delete_last_object) async def handle_prepare_get_object_or_meta_binary(self, client, input, output): logger.info("DataStoreServer.prepare_get_object_or_meta_binary()") #--- request --- param = input.extract(DataStorePrepareGetParam) response = await self.prepare_get_object_or_meta_binary(client, param) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['get_info', 'additional_meta']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.add(response.get_info) output.add(response.additional_meta) async def handle_get_password_info(self, client, input, output): logger.info("DataStoreServer.get_password_info()") #--- request --- data_id = input.u64() response = await self.get_password_info(client, data_id) #--- response --- if not isinstance(response, DataStorePasswordInfo): raise RuntimeError("Expected DataStorePasswordInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_password_infos(self, client, input, output): logger.info("DataStoreServer.get_password_infos()") #--- request --- data_ids = input.list(input.u64) response = await self.get_password_infos(client, data_ids) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['infos', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.infos, output.add) output.list(response.results, output.result) async def handle_get_metas_multiple_param(self, client, input, output): logger.info("DataStoreServer.get_metas_multiple_param()") #--- request --- params = input.list(DataStoreGetMetaParam) response = await self.get_metas_multiple_param(client, params) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['infos', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.infos, output.add) output.list(response.results, output.result) async def handle_complete_post_objects(self, client, input, output): logger.info("DataStoreServer.complete_post_objects()") #--- request --- data_ids = input.list(input.u64) await self.complete_post_objects(client, data_ids) async def handle_change_meta(self, client, input, output): logger.info("DataStoreServer.change_meta()") #--- request --- param = input.extract(DataStoreChangeMetaParam) await self.change_meta(client, param) async def handle_change_metas(self, client, input, output): logger.info("DataStoreServer.change_metas()") #--- request --- data_ids = input.list(input.u64) param = input.list(DataStoreChangeMetaParam) transactional = input.bool() response = await self.change_metas(client, data_ids, param, transactional) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.result) async def handle_rate_objects(self, client, input, output): logger.info("DataStoreServer.rate_objects()") #--- request --- targets = input.list(DataStoreRatingTarget) param = input.list(DataStoreRateObjectParam) transactional = input.bool() fetch_ratings = input.bool() response = await self.rate_objects(client, targets, param, transactional, fetch_ratings) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['infos', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.infos, output.add) output.list(response.results, output.result) async def handle_post_meta_binary_with_data_id(self, client, input, output): logger.info("DataStoreServer.post_meta_binary_with_data_id()") #--- request --- data_id = input.u64() param = input.extract(DataStorePreparePostParam) await self.post_meta_binary_with_data_id(client, data_id, param) async def handle_post_meta_binaries_with_data_id(self, client, input, output): logger.info("DataStoreServer.post_meta_binaries_with_data_id()") #--- request --- data_ids = input.list(input.u64) param = input.list(DataStorePreparePostParam) transactional = input.bool() response = await self.post_meta_binaries_with_data_id(client, data_ids, param, transactional) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.result) async def handle_rate_object_with_posting(self, client, input, output): logger.info("DataStoreServer.rate_object_with_posting()") #--- request --- target = input.extract(DataStoreRatingTarget) rate_param = input.extract(DataStoreRateObjectParam) post_param = input.extract(DataStorePreparePostParam) fetch_ratings = input.bool() response = await self.rate_object_with_posting(client, target, rate_param, post_param, fetch_ratings) #--- response --- if not isinstance(response, DataStoreRatingInfo): raise RuntimeError("Expected DataStoreRatingInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_rate_objects_with_posting(self, client, input, output): logger.info("DataStoreServer.rate_objects_with_posting()") #--- request --- targets = input.list(DataStoreRatingTarget) rate_param = input.list(DataStoreRateObjectParam) post_param = input.list(DataStorePreparePostParam) transactional = input.bool() fetch_ratings = input.bool() response = await self.rate_objects_with_posting(client, targets, rate_param, post_param, transactional, fetch_ratings) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['ratings', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.ratings, output.add) output.list(response.results, output.result) async def handle_get_object_infos(self, client, input, output): logger.info("DataStoreServer.get_object_infos()") #--- request --- data_ids = input.list(input.u64) response = await self.get_object_infos(client, data_ids) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['infos', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.infos, output.add) output.list(response.results, output.result) async def handle_search_object_light(self, client, input, output): logger.info("DataStoreServer.search_object_light()") #--- request --- param = input.extract(DataStoreSearchParam) response = await self.search_object_light(client, param) #--- response --- if not isinstance(response, DataStoreSearchResult): raise RuntimeError("Expected DataStoreSearchResult, got %s" %response.__class__.__name__) output.add(response) async def prepare_get_object_v1(self, *args): logger.warning("DataStoreServer.prepare_get_object_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def prepare_post_object_v1(self, *args): logger.warning("DataStoreServer.prepare_post_object_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def complete_post_object_v1(self, *args): logger.warning("DataStoreServer.complete_post_object_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def delete_object(self, *args): logger.warning("DataStoreServer.delete_object not implemented") raise common.RMCError("Core::NotImplemented") async def delete_objects(self, *args): logger.warning("DataStoreServer.delete_objects not implemented") raise common.RMCError("Core::NotImplemented") async def change_meta_v1(self, *args): logger.warning("DataStoreServer.change_meta_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def change_metas_v1(self, *args): logger.warning("DataStoreServer.change_metas_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def get_meta(self, *args): logger.warning("DataStoreServer.get_meta not implemented") raise common.RMCError("Core::NotImplemented") async def get_metas(self, *args): logger.warning("DataStoreServer.get_metas not implemented") raise common.RMCError("Core::NotImplemented") async def prepare_update_object(self, *args): logger.warning("DataStoreServer.prepare_update_object not implemented") raise common.RMCError("Core::NotImplemented") async def complete_update_object(self, *args): logger.warning("DataStoreServer.complete_update_object not implemented") raise common.RMCError("Core::NotImplemented") async def search_object(self, *args): logger.warning("DataStoreServer.search_object not implemented") raise common.RMCError("Core::NotImplemented") async def get_notification_url(self, *args): logger.warning("DataStoreServer.get_notification_url not implemented") raise common.RMCError("Core::NotImplemented") async def get_new_arrived_notifications_v1(self, *args): logger.warning("DataStoreServer.get_new_arrived_notifications_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def rate_object(self, *args): logger.warning("DataStoreServer.rate_object not implemented") raise common.RMCError("Core::NotImplemented") async def get_rating(self, *args): logger.warning("DataStoreServer.get_rating not implemented") raise common.RMCError("Core::NotImplemented") async def get_ratings(self, *args): logger.warning("DataStoreServer.get_ratings not implemented") raise common.RMCError("Core::NotImplemented") async def reset_rating(self, *args): logger.warning("DataStoreServer.reset_rating not implemented") raise common.RMCError("Core::NotImplemented") async def reset_ratings(self, *args): logger.warning("DataStoreServer.reset_ratings not implemented") raise common.RMCError("Core::NotImplemented") async def get_specific_meta_v1(self, *args): logger.warning("DataStoreServer.get_specific_meta_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def post_meta_binary(self, *args): logger.warning("DataStoreServer.post_meta_binary not implemented") raise common.RMCError("Core::NotImplemented") async def touch_object(self, *args): logger.warning("DataStoreServer.touch_object not implemented") raise common.RMCError("Core::NotImplemented") async def get_rating_with_log(self, *args): logger.warning("DataStoreServer.get_rating_with_log not implemented") raise common.RMCError("Core::NotImplemented") async def prepare_post_object(self, *args): logger.warning("DataStoreServer.prepare_post_object not implemented") raise common.RMCError("Core::NotImplemented") async def prepare_get_object(self, *args): logger.warning("DataStoreServer.prepare_get_object not implemented") raise common.RMCError("Core::NotImplemented") async def complete_post_object(self, *args): logger.warning("DataStoreServer.complete_post_object not implemented") raise common.RMCError("Core::NotImplemented") async def get_new_arrived_notifications(self, *args): logger.warning("DataStoreServer.get_new_arrived_notifications not implemented") raise common.RMCError("Core::NotImplemented") async def get_specific_meta(self, *args): logger.warning("DataStoreServer.get_specific_meta not implemented") raise common.RMCError("Core::NotImplemented") async def get_persistence_info(self, *args): logger.warning("DataStoreServer.get_persistence_info not implemented") raise common.RMCError("Core::NotImplemented") async def get_persistence_infos(self, *args): logger.warning("DataStoreServer.get_persistence_infos not implemented") raise common.RMCError("Core::NotImplemented") async def perpetuate_object(self, *args): logger.warning("DataStoreServer.perpetuate_object not implemented") raise common.RMCError("Core::NotImplemented") async def unperpetuate_object(self, *args): logger.warning("DataStoreServer.unperpetuate_object not implemented") raise common.RMCError("Core::NotImplemented") async def prepare_get_object_or_meta_binary(self, *args): logger.warning("DataStoreServer.prepare_get_object_or_meta_binary not implemented") raise common.RMCError("Core::NotImplemented") async def get_password_info(self, *args): logger.warning("DataStoreServer.get_password_info not implemented") raise common.RMCError("Core::NotImplemented") async def get_password_infos(self, *args): logger.warning("DataStoreServer.get_password_infos not implemented") raise common.RMCError("Core::NotImplemented") async def get_metas_multiple_param(self, *args): logger.warning("DataStoreServer.get_metas_multiple_param not implemented") raise common.RMCError("Core::NotImplemented") async def complete_post_objects(self, *args): logger.warning("DataStoreServer.complete_post_objects not implemented") raise common.RMCError("Core::NotImplemented") async def change_meta(self, *args): logger.warning("DataStoreServer.change_meta not implemented") raise common.RMCError("Core::NotImplemented") async def change_metas(self, *args): logger.warning("DataStoreServer.change_metas not implemented") raise common.RMCError("Core::NotImplemented") async def rate_objects(self, *args): logger.warning("DataStoreServer.rate_objects not implemented") raise common.RMCError("Core::NotImplemented") async def post_meta_binary_with_data_id(self, *args): logger.warning("DataStoreServer.post_meta_binary_with_data_id not implemented") raise common.RMCError("Core::NotImplemented") async def post_meta_binaries_with_data_id(self, *args): logger.warning("DataStoreServer.post_meta_binaries_with_data_id not implemented") raise common.RMCError("Core::NotImplemented") async def rate_object_with_posting(self, *args): logger.warning("DataStoreServer.rate_object_with_posting not implemented") raise common.RMCError("Core::NotImplemented") async def rate_objects_with_posting(self, *args): logger.warning("DataStoreServer.rate_objects_with_posting not implemented") raise common.RMCError("Core::NotImplemented") async def get_object_infos(self, *args): logger.warning("DataStoreServer.get_object_infos not implemented") raise common.RMCError("Core::NotImplemented") async def search_object_light(self, *args): logger.warning("DataStoreServer.search_object_light not implemented") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/datastore_miitopia_3ds.py ================================================ # This file was generated automatically by generate_protocols.py from nintendo.nex import notification, rmc, common, streams import logging logger = logging.getLogger(__name__) class Gender: MALE = 0 FEMALE = 1 ANY = 2 class Category: SINGING = 0 SPORT = 1 ACTING = 2 COMEDY = 3 MUSIC = 4 MARTIAL_ARTS = 5 DANCING = 6 ADVENTURING = 7 FILM_DIRECTING = 8 COOKING = 9 CHATTING = 10 PUBLIC_SPEAKING = 11 CRAFTWORK = 12 DRAWING = 13 STUDYING = 14 WRITING = 15 FASHION = 16 DINING = 17 NOT_TELLING = 18 ANY = 255 class DataStoreChangeMetaCompareParam(common.Structure): def __init__(self): super().__init__() self.comparison_flag = None self.name = None self.permission = DataStorePermission() self.delete_permission = DataStorePermission() self.period = None self.meta_binary = None self.tags = None self.referred_count = None self.data_type = None self.status = None def check_required(self, settings, version): for field in ['comparison_flag', 'name', 'period', 'meta_binary', 'tags', 'referred_count', 'data_type', 'status']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.comparison_flag = stream.u32() self.name = stream.string() self.permission = stream.extract(DataStorePermission) self.delete_permission = stream.extract(DataStorePermission) self.period = stream.u16() self.meta_binary = stream.qbuffer() self.tags = stream.list(stream.string) self.referred_count = stream.u32() self.data_type = stream.u16() self.status = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.comparison_flag) stream.string(self.name) stream.add(self.permission) stream.add(self.delete_permission) stream.u16(self.period) stream.qbuffer(self.meta_binary) stream.list(self.tags, stream.string) stream.u32(self.referred_count) stream.u16(self.data_type) stream.u8(self.status) class DataStoreChangeMetaParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.modifies_flag = None self.name = None self.permission = DataStorePermission() self.delete_permission = DataStorePermission() self.period = None self.meta_binary = None self.tags = None self.update_password = None self.referred_count = None self.data_type = None self.status = None self.compare_param = DataStoreChangeMetaCompareParam() self.persistence_target = DataStorePersistenceTarget() def check_required(self, settings, version): for field in ['data_id', 'modifies_flag', 'name', 'period', 'meta_binary', 'tags', 'update_password', 'referred_count', 'data_type', 'status']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.modifies_flag = stream.u32() self.name = stream.string() self.permission = stream.extract(DataStorePermission) self.delete_permission = stream.extract(DataStorePermission) self.period = stream.u16() self.meta_binary = stream.qbuffer() self.tags = stream.list(stream.string) self.update_password = stream.u64() self.referred_count = stream.u32() self.data_type = stream.u16() self.status = stream.u8() self.compare_param = stream.extract(DataStoreChangeMetaCompareParam) self.persistence_target = stream.extract(DataStorePersistenceTarget) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.modifies_flag) stream.string(self.name) stream.add(self.permission) stream.add(self.delete_permission) stream.u16(self.period) stream.qbuffer(self.meta_binary) stream.list(self.tags, stream.string) stream.u64(self.update_password) stream.u32(self.referred_count) stream.u16(self.data_type) stream.u8(self.status) stream.add(self.compare_param) stream.add(self.persistence_target) class DataStoreChangeMetaParamV1(common.Structure): def __init__(self): super().__init__() self.data_id = None self.modifies_flag = None self.name = None self.permission = DataStorePermission() self.delete_permission = DataStorePermission() self.period = None self.meta_binary = None self.tags = None self.update_password = None def check_required(self, settings, version): for field in ['data_id', 'modifies_flag', 'name', 'period', 'meta_binary', 'tags', 'update_password']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.modifies_flag = stream.u32() self.name = stream.string() self.permission = stream.extract(DataStorePermission) self.delete_permission = stream.extract(DataStorePermission) self.period = stream.u16() self.meta_binary = stream.qbuffer() self.tags = stream.list(stream.string) self.update_password = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.modifies_flag) stream.string(self.name) stream.add(self.permission) stream.add(self.delete_permission) stream.u16(self.period) stream.qbuffer(self.meta_binary) stream.list(self.tags, stream.string) stream.u64(self.update_password) class DataStoreCompletePostParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.success = None def check_required(self, settings, version): for field in ['data_id', 'success']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.success = stream.bool() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.bool(self.success) class DataStoreCompletePostParamV1(common.Structure): def __init__(self): super().__init__() self.data_id = None self.success = None def check_required(self, settings, version): for field in ['data_id', 'success']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u32() self.success = stream.bool() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.data_id) stream.bool(self.success) class DataStoreCompleteUpdateParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.version = None self.success = None def check_required(self, settings, version): for field in ['data_id', 'version', 'success']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.version = stream.u32() self.success = stream.bool() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.version) stream.bool(self.success) class DataStoreDeleteParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.update_password = None def check_required(self, settings, version): for field in ['data_id', 'update_password']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.update_password = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u64(self.update_password) class DataStoreGetMetaParam(common.Structure): def __init__(self): super().__init__() self.data_id = 0 self.persistence_target = DataStorePersistenceTarget() self.result_option = 0 self.access_password = 0 def check_required(self, settings, version): pass def load(self, stream, version): self.data_id = stream.u64() self.persistence_target = stream.extract(DataStorePersistenceTarget) self.result_option = stream.u8() self.access_password = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.add(self.persistence_target) stream.u8(self.result_option) stream.u64(self.access_password) class DataStoreGetNewArrivedNotificationsParam(common.Structure): def __init__(self): super().__init__() self.last_notification_id = None self.limit = None def check_required(self, settings, version): for field in ['last_notification_id', 'limit']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.last_notification_id = stream.u64() self.limit = stream.u16() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.last_notification_id) stream.u16(self.limit) class DataStoreGetNotificationUrlParam(common.Structure): def __init__(self): super().__init__() self.previous_url = None def check_required(self, settings, version): for field in ['previous_url']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.previous_url = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.previous_url) class DataStoreGetSpecificMetaParam(common.Structure): def __init__(self): super().__init__() self.data_ids = None def check_required(self, settings, version): for field in ['data_ids']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_ids = stream.list(stream.u64) def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.data_ids, stream.u64) class DataStoreGetSpecificMetaParamV1(common.Structure): def __init__(self): super().__init__() self.data_ids = None def check_required(self, settings, version): for field in ['data_ids']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_ids = stream.list(stream.u32) def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.data_ids, stream.u32) class DataStoreKeyValue(common.Structure): def __init__(self): super().__init__() self.key = None self.value = None def check_required(self, settings, version): for field in ['key', 'value']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.key = stream.string() self.value = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.key) stream.string(self.value) class DataStoreMetaInfo(common.Structure): def __init__(self): super().__init__() self.data_id = None self.owner_id = None self.size = None self.name = None self.data_type = None self.meta_binary = None self.permission = DataStorePermission() self.delete_permission = DataStorePermission() self.create_time = None self.update_time = None self.period = None self.status = None self.referred_count = None self.refer_data_id = None self.flag = None self.referred_time = None self.expire_time = None self.tags = None self.ratings = None def check_required(self, settings, version): for field in ['data_id', 'owner_id', 'size', 'name', 'data_type', 'meta_binary', 'create_time', 'update_time', 'period', 'status', 'referred_count', 'refer_data_id', 'flag', 'referred_time', 'expire_time', 'tags', 'ratings']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.owner_id = stream.pid() self.size = stream.u32() self.name = stream.string() self.data_type = stream.u16() self.meta_binary = stream.qbuffer() self.permission = stream.extract(DataStorePermission) self.delete_permission = stream.extract(DataStorePermission) self.create_time = stream.datetime() self.update_time = stream.datetime() self.period = stream.u16() self.status = stream.u8() self.referred_count = stream.u32() self.refer_data_id = stream.u32() self.flag = stream.u32() self.referred_time = stream.datetime() self.expire_time = stream.datetime() self.tags = stream.list(stream.string) self.ratings = stream.list(DataStoreRatingInfoWithSlot) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.pid(self.owner_id) stream.u32(self.size) stream.string(self.name) stream.u16(self.data_type) stream.qbuffer(self.meta_binary) stream.add(self.permission) stream.add(self.delete_permission) stream.datetime(self.create_time) stream.datetime(self.update_time) stream.u16(self.period) stream.u8(self.status) stream.u32(self.referred_count) stream.u32(self.refer_data_id) stream.u32(self.flag) stream.datetime(self.referred_time) stream.datetime(self.expire_time) stream.list(self.tags, stream.string) stream.list(self.ratings, stream.add) class DataStoreNotification(common.Structure): def __init__(self): super().__init__() self.notification_id = None self.data_id = None def check_required(self, settings, version): for field in ['notification_id', 'data_id']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.notification_id = stream.u64() self.data_id = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.notification_id) stream.u64(self.data_id) class DataStoreNotificationV1(common.Structure): def __init__(self): super().__init__() self.notification_id = None self.data_id = None def check_required(self, settings, version): for field in ['notification_id', 'data_id']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.notification_id = stream.u64() self.data_id = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.notification_id) stream.u32(self.data_id) class DataStorePasswordInfo(common.Structure): def __init__(self): super().__init__() self.data_id = None self.access_password = None self.update_password = None def check_required(self, settings, version): for field in ['data_id', 'access_password', 'update_password']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.access_password = stream.u64() self.update_password = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u64(self.access_password) stream.u64(self.update_password) class DataStorePermission(common.Structure): def __init__(self): super().__init__() self.permission = 3 self.recipients = [] def check_required(self, settings, version): pass def load(self, stream, version): self.permission = stream.u8() self.recipients = stream.list(stream.pid) def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.permission) stream.list(self.recipients, stream.pid) class DataStorePersistenceInfo(common.Structure): def __init__(self): super().__init__() self.owner_id = None self.slot_id = None self.data_id = None def check_required(self, settings, version): for field in ['owner_id', 'slot_id', 'data_id']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.owner_id = stream.pid() self.slot_id = stream.u16() self.data_id = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.owner_id) stream.u16(self.slot_id) stream.u64(self.data_id) class DataStorePersistenceInitParam(common.Structure): def __init__(self): super().__init__() self.persistence_id = 65535 self.delete_last_object = True def check_required(self, settings, version): pass def load(self, stream, version): self.persistence_id = stream.u16() self.delete_last_object = stream.bool() def save(self, stream, version): self.check_required(stream.settings, version) stream.u16(self.persistence_id) stream.bool(self.delete_last_object) class DataStorePersistenceTarget(common.Structure): def __init__(self): super().__init__() self.owner_id = 0 self.persistence_id = 65535 def check_required(self, settings, version): pass def load(self, stream, version): self.owner_id = stream.pid() self.persistence_id = stream.u16() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.owner_id) stream.u16(self.persistence_id) class DataStorePrepareGetParam(common.Structure): def __init__(self): super().__init__() self.data_id = 0 self.lock_id = 0 self.persistence_target = DataStorePersistenceTarget() self.access_password = 0 self.extra_data = [] def check_required(self, settings, version): if settings["nex.version"] >= 30500: pass def load(self, stream, version): self.data_id = stream.u64() self.lock_id = stream.u32() self.persistence_target = stream.extract(DataStorePersistenceTarget) self.access_password = stream.u64() if stream.settings["nex.version"] >= 30500: self.extra_data = stream.list(stream.string) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.lock_id) stream.add(self.persistence_target) stream.u64(self.access_password) if stream.settings["nex.version"] >= 30500: stream.list(self.extra_data, stream.string) class DataStorePrepareGetParamV1(common.Structure): def __init__(self): super().__init__() self.data_id = None self.lock_id = 0 def check_required(self, settings, version): for field in ['data_id']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u32() self.lock_id = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.data_id) stream.u32(self.lock_id) class DataStorePreparePostParam(common.Structure): def __init__(self): super().__init__() self.size = None self.name = None self.data_type = None self.meta_binary = None self.permission = DataStorePermission() self.delete_permission = DataStorePermission() self.flag = None self.period = None self.refer_data_id = 0 self.tags = [] self.rating_init_param = [] self.persistence_init_param = DataStorePersistenceInitParam() self.extra_data = None def check_required(self, settings, version): for field in ['size', 'name', 'data_type', 'meta_binary', 'flag', 'period']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) if settings["nex.version"] >= 30500: for field in ['extra_data']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.size = stream.u32() self.name = stream.string() self.data_type = stream.u16() self.meta_binary = stream.qbuffer() self.permission = stream.extract(DataStorePermission) self.delete_permission = stream.extract(DataStorePermission) self.flag = stream.u32() self.period = stream.u16() self.refer_data_id = stream.u32() self.tags = stream.list(stream.string) self.rating_init_param = stream.list(DataStoreRatingInitParamWithSlot) self.persistence_init_param = stream.extract(DataStorePersistenceInitParam) if stream.settings["nex.version"] >= 30500: self.extra_data = stream.list(stream.string) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.size) stream.string(self.name) stream.u16(self.data_type) stream.qbuffer(self.meta_binary) stream.add(self.permission) stream.add(self.delete_permission) stream.u32(self.flag) stream.u16(self.period) stream.u32(self.refer_data_id) stream.list(self.tags, stream.string) stream.list(self.rating_init_param, stream.add) stream.add(self.persistence_init_param) if stream.settings["nex.version"] >= 30500: stream.list(self.extra_data, stream.string) class DataStorePreparePostParamV1(common.Structure): def __init__(self): super().__init__() self.size = None self.name = None self.data_type = 0 self.meta_binary = b"" self.permission = DataStorePermission() self.delete_permission = DataStorePermission() self.flag = None self.period = None self.refer_data_id = 0 self.tags = None self.rating_init_param = None def check_required(self, settings, version): for field in ['size', 'name', 'flag', 'period', 'tags', 'rating_init_param']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.size = stream.u32() self.name = stream.string() self.data_type = stream.u16() self.meta_binary = stream.qbuffer() self.permission = stream.extract(DataStorePermission) self.delete_permission = stream.extract(DataStorePermission) self.flag = stream.u32() self.period = stream.u16() self.refer_data_id = stream.u32() self.tags = stream.list(stream.string) self.rating_init_param = stream.list(DataStoreRatingInitParamWithSlot) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.size) stream.string(self.name) stream.u16(self.data_type) stream.qbuffer(self.meta_binary) stream.add(self.permission) stream.add(self.delete_permission) stream.u32(self.flag) stream.u16(self.period) stream.u32(self.refer_data_id) stream.list(self.tags, stream.string) stream.list(self.rating_init_param, stream.add) class DataStorePrepareUpdateParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.size = None self.update_password = None self.extra_data = None def check_required(self, settings, version): for field in ['data_id', 'size', 'update_password', 'extra_data']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.size = stream.u32() self.update_password = stream.u64() self.extra_data = stream.list(stream.string) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.size) stream.u64(self.update_password) stream.list(self.extra_data, stream.string) class DataStoreRateObjectParam(common.Structure): def __init__(self): super().__init__() self.rating_value = None self.access_password = None def check_required(self, settings, version): for field in ['rating_value', 'access_password']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.rating_value = stream.s32() self.access_password = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.s32(self.rating_value) stream.u64(self.access_password) class DataStoreRatingInfo(common.Structure): def __init__(self): super().__init__() self.total_value = None self.count = None self.initial_value = None def check_required(self, settings, version): for field in ['total_value', 'count', 'initial_value']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.total_value = stream.s64() self.count = stream.u32() self.initial_value = stream.s64() def save(self, stream, version): self.check_required(stream.settings, version) stream.s64(self.total_value) stream.u32(self.count) stream.s64(self.initial_value) class DataStoreRatingInfoWithSlot(common.Structure): def __init__(self): super().__init__() self.slot = None self.info = DataStoreRatingInfo() def check_required(self, settings, version): for field in ['slot']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.slot = stream.u8() self.info = stream.extract(DataStoreRatingInfo) def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.slot) stream.add(self.info) class DataStoreRatingInitParam(common.Structure): def __init__(self): super().__init__() self.flag = None self.internal_flag = None self.lock_type = None self.initial_value = None self.range_min = None self.range_max = None self.period_hour = None self.period_duration = None def check_required(self, settings, version): for field in ['flag', 'internal_flag', 'lock_type', 'initial_value', 'range_min', 'range_max', 'period_hour', 'period_duration']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.flag = stream.u8() self.internal_flag = stream.u8() self.lock_type = stream.u8() self.initial_value = stream.s64() self.range_min = stream.s32() self.range_max = stream.s32() self.period_hour = stream.s8() self.period_duration = stream.s16() def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.flag) stream.u8(self.internal_flag) stream.u8(self.lock_type) stream.s64(self.initial_value) stream.s32(self.range_min) stream.s32(self.range_max) stream.s8(self.period_hour) stream.s16(self.period_duration) class DataStoreRatingInitParamWithSlot(common.Structure): def __init__(self): super().__init__() self.slot = None self.param = DataStoreRatingInitParam() def check_required(self, settings, version): for field in ['slot']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.slot = stream.s8() self.param = stream.extract(DataStoreRatingInitParam) def save(self, stream, version): self.check_required(stream.settings, version) stream.s8(self.slot) stream.add(self.param) class DataStoreRatingLog(common.Structure): def __init__(self): super().__init__() self.is_rated = None self.pid = None self.rating_value = None self.lock_expiration_time = None def check_required(self, settings, version): for field in ['is_rated', 'pid', 'rating_value', 'lock_expiration_time']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.is_rated = stream.bool() self.pid = stream.pid() self.rating_value = stream.s32() self.lock_expiration_time = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.bool(self.is_rated) stream.pid(self.pid) stream.s32(self.rating_value) stream.datetime(self.lock_expiration_time) class DataStoreRatingTarget(common.Structure): def __init__(self): super().__init__() self.data_id = None self.slot = None def check_required(self, settings, version): for field in ['data_id', 'slot']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.slot = stream.s8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.s8(self.slot) class DataStoreReqGetAdditionalMeta(common.Structure): def __init__(self): super().__init__() self.owner_id = None self.data_type = None self.version = None self.meta_binary = None def check_required(self, settings, version): for field in ['owner_id', 'data_type', 'version', 'meta_binary']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.owner_id = stream.pid() self.data_type = stream.u16() self.version = stream.u16() self.meta_binary = stream.qbuffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.owner_id) stream.u16(self.data_type) stream.u16(self.version) stream.qbuffer(self.meta_binary) class DataStoreReqGetInfo(common.Structure): def __init__(self): super().__init__() self.url = None self.headers = None self.size = None self.root_ca_cert = None self.data_id = None def check_required(self, settings, version): for field in ['url', 'headers', 'size', 'root_ca_cert']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) if settings["nex.version"] >= 30500: for field in ['data_id']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.url = stream.string() self.headers = stream.list(DataStoreKeyValue) self.size = stream.u32() self.root_ca_cert = stream.buffer() if stream.settings["nex.version"] >= 30500: self.data_id = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.url) stream.list(self.headers, stream.add) stream.u32(self.size) stream.buffer(self.root_ca_cert) if stream.settings["nex.version"] >= 30500: stream.u64(self.data_id) class DataStoreReqGetInfoV1(common.Structure): def __init__(self): super().__init__() self.url = None self.headers = None self.size = None self.root_ca_cert = None def check_required(self, settings, version): for field in ['url', 'headers', 'size', 'root_ca_cert']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.url = stream.string() self.headers = stream.list(DataStoreKeyValue) self.size = stream.u32() self.root_ca_cert = stream.buffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.url) stream.list(self.headers, stream.add) stream.u32(self.size) stream.buffer(self.root_ca_cert) class DataStoreReqGetNotificationUrlInfo(common.Structure): def __init__(self): super().__init__() self.url = None self.key = None self.query = None self.root_ca_cert = None def check_required(self, settings, version): for field in ['url', 'key', 'query', 'root_ca_cert']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.url = stream.string() self.key = stream.string() self.query = stream.string() self.root_ca_cert = stream.buffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.url) stream.string(self.key) stream.string(self.query) stream.buffer(self.root_ca_cert) class DataStoreReqPostInfo(common.Structure): def __init__(self): super().__init__() self.data_id = None self.url = None self.headers = None self.form = None self.root_ca_cert = None def check_required(self, settings, version): for field in ['data_id', 'url', 'headers', 'form', 'root_ca_cert']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.url = stream.string() self.headers = stream.list(DataStoreKeyValue) self.form = stream.list(DataStoreKeyValue) self.root_ca_cert = stream.buffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.string(self.url) stream.list(self.headers, stream.add) stream.list(self.form, stream.add) stream.buffer(self.root_ca_cert) class DataStoreReqPostInfoV1(common.Structure): def __init__(self): super().__init__() self.data_id = None self.url = None self.headers = None self.form = None self.root_ca_cert = None def check_required(self, settings, version): for field in ['data_id', 'url', 'headers', 'form', 'root_ca_cert']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u32() self.url = stream.string() self.headers = stream.list(DataStoreKeyValue) self.form = stream.list(DataStoreKeyValue) self.root_ca_cert = stream.buffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.data_id) stream.string(self.url) stream.list(self.headers, stream.add) stream.list(self.form, stream.add) stream.buffer(self.root_ca_cert) class DataStoreReqUpdateInfo(common.Structure): def __init__(self): super().__init__() self.version = None self.url = None self.headers = None self.form = None self.root_ca_cert = None def check_required(self, settings, version): for field in ['version', 'url', 'headers', 'form', 'root_ca_cert']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.version = stream.u32() self.url = stream.string() self.headers = stream.list(DataStoreKeyValue) self.form = stream.list(DataStoreKeyValue) self.root_ca_cert = stream.buffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.version) stream.string(self.url) stream.list(self.headers, stream.add) stream.list(self.form, stream.add) stream.buffer(self.root_ca_cert) class DataStoreSearchParam(common.Structure): def __init__(self): super().__init__() self.search_target = 1 self.owner_ids = [] self.owner_type = 0 self.destination_ids = [] self.data_type = 65535 self.created_after = common.DateTime(671076024059) self.created_before = common.DateTime(671076024059) self.updated_after = common.DateTime(671076024059) self.updated_before = common.DateTime(671076024059) self.refer_data_id = 0 self.tags = [] self.result_order_column = 0 self.result_order = 0 self.result_range = common.ResultRange() self.result_option = 0 self.minimal_rating_frequency = 0 self.use_cache = False self.total_count_enabled = True self.data_types = [] def check_required(self, settings, version): pass def load(self, stream, version): self.search_target = stream.u8() self.owner_ids = stream.list(stream.pid) self.owner_type = stream.u8() self.destination_ids = stream.list(stream.u64) self.data_type = stream.u16() self.created_after = stream.datetime() self.created_before = stream.datetime() self.updated_after = stream.datetime() self.updated_before = stream.datetime() self.refer_data_id = stream.u32() self.tags = stream.list(stream.string) self.result_order_column = stream.u8() self.result_order = stream.u8() self.result_range = stream.extract(common.ResultRange) self.result_option = stream.u8() self.minimal_rating_frequency = stream.u32() self.use_cache = stream.bool() self.total_count_enabled = stream.bool() self.data_types = stream.list(stream.u16) def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.search_target) stream.list(self.owner_ids, stream.pid) stream.u8(self.owner_type) stream.list(self.destination_ids, stream.u64) stream.u16(self.data_type) stream.datetime(self.created_after) stream.datetime(self.created_before) stream.datetime(self.updated_after) stream.datetime(self.updated_before) stream.u32(self.refer_data_id) stream.list(self.tags, stream.string) stream.u8(self.result_order_column) stream.u8(self.result_order) stream.add(self.result_range) stream.u8(self.result_option) stream.u32(self.minimal_rating_frequency) stream.bool(self.use_cache) stream.bool(self.total_count_enabled) stream.list(self.data_types, stream.u16) class DataStoreSearchResult(common.Structure): def __init__(self): super().__init__() self.total_count = None self.result = None self.total_count_type = None def check_required(self, settings, version): for field in ['total_count', 'result', 'total_count_type']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.total_count = stream.u32() self.result = stream.list(DataStoreMetaInfo) self.total_count_type = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.total_count) stream.list(self.result, stream.add) stream.u8(self.total_count_type) class DataStoreSpecificMetaInfo(common.Structure): def __init__(self): super().__init__() self.data_id = None self.owner_id = None self.size = None self.data_type = None self.version = None def check_required(self, settings, version): for field in ['data_id', 'owner_id', 'size', 'data_type', 'version']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.owner_id = stream.pid() self.size = stream.u32() self.data_type = stream.u16() self.version = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.pid(self.owner_id) stream.u32(self.size) stream.u16(self.data_type) stream.u32(self.version) class DataStoreSpecificMetaInfoV1(common.Structure): def __init__(self): super().__init__() self.data_id = None self.owner_id = None self.size = None self.data_type = None self.version = None def check_required(self, settings, version): for field in ['data_id', 'owner_id', 'size', 'data_type', 'version']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u32() self.owner_id = stream.pid() self.size = stream.u32() self.data_type = stream.u16() self.version = stream.u16() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.data_id) stream.pid(self.owner_id) stream.u32(self.size) stream.u16(self.data_type) stream.u16(self.version) class DataStoreTouchObjectParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.lock_id = None self.access_password = None def check_required(self, settings, version): for field in ['data_id', 'lock_id', 'access_password']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.lock_id = stream.u32() self.access_password = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.lock_id) stream.u64(self.access_password) class MiiTubeSearchParam(common.Structure): def __init__(self): super().__init__() self.name = None self.page = 0 self.category = 255 self.gender = 2 self.country = None self.search_type = 0 self.result_option = 0 def check_required(self, settings, version): for field in ['name', 'country']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.name = stream.string() self.page = stream.u32() self.category = stream.u8() self.gender = stream.u8() self.country = stream.u8() self.search_type = stream.u8() self.result_option = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.name) stream.u32(self.page) stream.u8(self.category) stream.u8(self.gender) stream.u8(self.country) stream.u8(self.search_type) stream.u8(self.result_option) class MiiTubeMiiInfo(common.Structure): def __init__(self): super().__init__() self.meta_info = DataStoreMetaInfo() self.category = None self.ranking_type = None def check_required(self, settings, version): for field in ['category', 'ranking_type']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.meta_info = stream.extract(DataStoreMetaInfo) self.category = stream.u8() self.ranking_type = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.add(self.meta_info) stream.u8(self.category) stream.u8(self.ranking_type) class MiiTubeSearchResult(common.Structure): def __init__(self): super().__init__() self.result = None self.count = None self.page = None self.has_next = None def check_required(self, settings, version): for field in ['result', 'count', 'page', 'has_next']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.result = stream.list(MiiTubeMiiInfo) self.count = stream.u32() self.page = stream.u32() self.has_next = stream.bool() def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.result, stream.add) stream.u32(self.count) stream.u32(self.page) stream.bool(self.has_next) class DataStoreProtocolMiitopia3DS: METHOD_PREPARE_GET_OBJECT_V1 = 1 METHOD_PREPARE_POST_OBJECT_V1 = 2 METHOD_COMPLETE_POST_OBJECT_V1 = 3 METHOD_DELETE_OBJECT = 4 METHOD_DELETE_OBJECTS = 5 METHOD_CHANGE_META_V1 = 6 METHOD_CHANGE_METAS_V1 = 7 METHOD_GET_META = 8 METHOD_GET_METAS = 9 METHOD_PREPARE_UPDATE_OBJECT = 10 METHOD_COMPLETE_UPDATE_OBJECT = 11 METHOD_SEARCH_OBJECT = 12 METHOD_GET_NOTIFICATION_URL = 13 METHOD_GET_NEW_ARRIVED_NOTIFICATIONS_V1 = 14 METHOD_RATE_OBJECT = 15 METHOD_GET_RATING = 16 METHOD_GET_RATINGS = 17 METHOD_RESET_RATING = 18 METHOD_RESET_RATINGS = 19 METHOD_GET_SPECIFIC_META_V1 = 20 METHOD_POST_META_BINARY = 21 METHOD_TOUCH_OBJECT = 22 METHOD_GET_RATING_WITH_LOG = 23 METHOD_PREPARE_POST_OBJECT = 24 METHOD_PREPARE_GET_OBJECT = 25 METHOD_COMPLETE_POST_OBJECT = 26 METHOD_GET_NEW_ARRIVED_NOTIFICATIONS = 27 METHOD_GET_SPECIFIC_META = 28 METHOD_GET_PERSISTENCE_INFO = 29 METHOD_GET_PERSISTENCE_INFOS = 30 METHOD_PERPETUATE_OBJECT = 31 METHOD_UNPERPETUATE_OBJECT = 32 METHOD_PREPARE_GET_OBJECT_OR_META_BINARY = 33 METHOD_GET_PASSWORD_INFO = 34 METHOD_GET_PASSWORD_INFOS = 35 METHOD_GET_METAS_MULTIPLE_PARAM = 36 METHOD_COMPLETE_POST_OBJECTS = 37 METHOD_CHANGE_META = 38 METHOD_CHANGE_METAS = 39 METHOD_RATE_OBJECTS = 40 METHOD_POST_META_BINARY_WITH_DATA_ID = 41 METHOD_POST_META_BINARIES_WITH_DATA_ID = 42 METHOD_RATE_OBJECT_WITH_POSTING = 43 METHOD_RATE_OBJECTS_WITH_POSTING = 44 METHOD_GET_OBJECT_INFOS = 45 METHOD_SEARCH_OBJECT_LIGHT = 46 METHOD_SEARCH_MII = 47 PROTOCOL_ID = 0x73 class DataStoreClientMiitopia3DS(DataStoreProtocolMiitopia3DS): def __init__(self, client): self.settings = client.settings self.client = client async def prepare_get_object_v1(self, param): logger.info("DataStoreClientMiitopia3DS.prepare_get_object_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PREPARE_GET_OBJECT_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreReqGetInfoV1) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.prepare_get_object_v1 -> done") return info async def prepare_post_object_v1(self, param): logger.info("DataStoreClientMiitopia3DS.prepare_post_object_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PREPARE_POST_OBJECT_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreReqPostInfoV1) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.prepare_post_object_v1 -> done") return info async def complete_post_object_v1(self, param): logger.info("DataStoreClientMiitopia3DS.complete_post_object_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_COMPLETE_POST_OBJECT_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.complete_post_object_v1 -> done") async def delete_object(self, param): logger.info("DataStoreClientMiitopia3DS.delete_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.delete_object -> done") async def delete_objects(self, param, transactional): logger.info("DataStoreClientMiitopia3DS.delete_objects()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(param, stream.add) stream.bool(transactional) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_OBJECTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.delete_objects -> done") return results async def change_meta_v1(self, param): logger.info("DataStoreClientMiitopia3DS.change_meta_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CHANGE_META_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.change_meta_v1 -> done") async def change_metas_v1(self, data_ids, param, transactional): logger.info("DataStoreClientMiitopia3DS.change_metas_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) stream.list(param, stream.add) stream.bool(transactional) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CHANGE_METAS_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.change_metas_v1 -> done") return results async def get_meta(self, param): logger.info("DataStoreClientMiitopia3DS.get_meta()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_META, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreMetaInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.get_meta -> done") return info async def get_metas(self, data_ids, param): logger.info("DataStoreClientMiitopia3DS.get_metas()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_METAS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.info = stream.list(DataStoreMetaInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.get_metas -> done") return obj async def prepare_update_object(self, param): logger.info("DataStoreClientMiitopia3DS.prepare_update_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PREPARE_UPDATE_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreReqUpdateInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.prepare_update_object -> done") return info async def complete_update_object(self, param): logger.info("DataStoreClientMiitopia3DS.complete_update_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_COMPLETE_UPDATE_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.complete_update_object -> done") async def search_object(self, param): logger.info("DataStoreClientMiitopia3DS.search_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.extract(DataStoreSearchResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.search_object -> done") return result async def get_notification_url(self, param): logger.info("DataStoreClientMiitopia3DS.get_notification_url()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_NOTIFICATION_URL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreReqGetNotificationUrlInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.get_notification_url -> done") return info async def get_new_arrived_notifications_v1(self, param): logger.info("DataStoreClientMiitopia3DS.get_new_arrived_notifications_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_NEW_ARRIVED_NOTIFICATIONS_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.list(DataStoreNotificationV1) obj.has_next = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.get_new_arrived_notifications_v1 -> done") return obj async def rate_object(self, target, param, fetch_ratings): logger.info("DataStoreClientMiitopia3DS.rate_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) stream.add(param) stream.bool(fetch_ratings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RATE_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreRatingInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.rate_object -> done") return info async def get_rating(self, target, access_password): logger.info("DataStoreClientMiitopia3DS.get_rating()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) stream.u64(access_password) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RATING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) rating = stream.extract(DataStoreRatingInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.get_rating -> done") return rating async def get_ratings(self, data_ids, access_password): logger.info("DataStoreClientMiitopia3DS.get_ratings()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) stream.u64(access_password) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RATINGS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.ratings = stream.list(lambda: stream.list(DataStoreRatingInfoWithSlot)) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.get_ratings -> done") return obj async def reset_rating(self, target, update_password): logger.info("DataStoreClientMiitopia3DS.reset_rating()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) stream.u64(update_password) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RESET_RATING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.reset_rating -> done") async def reset_ratings(self, data_ids, transactional): logger.info("DataStoreClientMiitopia3DS.reset_ratings()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) stream.bool(transactional) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RESET_RATINGS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.reset_ratings -> done") return results async def get_specific_meta_v1(self, param): logger.info("DataStoreClientMiitopia3DS.get_specific_meta_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SPECIFIC_META_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) infos = stream.list(DataStoreSpecificMetaInfoV1) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.get_specific_meta_v1 -> done") return infos async def post_meta_binary(self, param): logger.info("DataStoreClientMiitopia3DS.post_meta_binary()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_POST_META_BINARY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) data_id = stream.u64() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.post_meta_binary -> done") return data_id async def touch_object(self, param): logger.info("DataStoreClientMiitopia3DS.touch_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_TOUCH_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.touch_object -> done") async def get_rating_with_log(self, target, access_password): logger.info("DataStoreClientMiitopia3DS.get_rating_with_log()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) stream.u64(access_password) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RATING_WITH_LOG, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.rating = stream.extract(DataStoreRatingInfo) obj.log = stream.extract(DataStoreRatingLog) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.get_rating_with_log -> done") return obj async def prepare_post_object(self, param): logger.info("DataStoreClientMiitopia3DS.prepare_post_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PREPARE_POST_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreReqPostInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.prepare_post_object -> done") return info async def prepare_get_object(self, param): logger.info("DataStoreClientMiitopia3DS.prepare_get_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PREPARE_GET_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreReqGetInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.prepare_get_object -> done") return info async def complete_post_object(self, param): logger.info("DataStoreClientMiitopia3DS.complete_post_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_COMPLETE_POST_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.complete_post_object -> done") async def get_new_arrived_notifications(self, param): logger.info("DataStoreClientMiitopia3DS.get_new_arrived_notifications()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_NEW_ARRIVED_NOTIFICATIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.list(DataStoreNotification) obj.has_next = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.get_new_arrived_notifications -> done") return obj async def get_specific_meta(self, param): logger.info("DataStoreClientMiitopia3DS.get_specific_meta()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SPECIFIC_META, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) infos = stream.list(DataStoreSpecificMetaInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.get_specific_meta -> done") return infos async def get_persistence_info(self, owner_id, slot_id): logger.info("DataStoreClientMiitopia3DS.get_persistence_info()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(owner_id) stream.u16(slot_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PERSISTENCE_INFO, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStorePersistenceInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.get_persistence_info -> done") return info async def get_persistence_infos(self, owner_id, slot_ids): logger.info("DataStoreClientMiitopia3DS.get_persistence_infos()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(owner_id) stream.list(slot_ids, stream.u16) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PERSISTENCE_INFOS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.infos = stream.list(DataStorePersistenceInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.get_persistence_infos -> done") return obj async def perpetuate_object(self, persistence_slot_id, data_id, delete_last_object): logger.info("DataStoreClientMiitopia3DS.perpetuate_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.u16(persistence_slot_id) stream.u64(data_id) stream.bool(delete_last_object) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PERPETUATE_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.perpetuate_object -> done") async def unperpetuate_object(self, persistence_slot_id, delete_last_object): logger.info("DataStoreClientMiitopia3DS.unperpetuate_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.u16(persistence_slot_id) stream.bool(delete_last_object) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UNPERPETUATE_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.unperpetuate_object -> done") async def prepare_get_object_or_meta_binary(self, param): logger.info("DataStoreClientMiitopia3DS.prepare_get_object_or_meta_binary()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PREPARE_GET_OBJECT_OR_META_BINARY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.get_info = stream.extract(DataStoreReqGetInfo) obj.additional_meta = stream.extract(DataStoreReqGetAdditionalMeta) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.prepare_get_object_or_meta_binary -> done") return obj async def get_password_info(self, data_id): logger.info("DataStoreClientMiitopia3DS.get_password_info()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(data_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PASSWORD_INFO, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStorePasswordInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.get_password_info -> done") return info async def get_password_infos(self, data_ids): logger.info("DataStoreClientMiitopia3DS.get_password_infos()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PASSWORD_INFOS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.infos = stream.list(DataStorePasswordInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.get_password_infos -> done") return obj async def get_metas_multiple_param(self, params): logger.info("DataStoreClientMiitopia3DS.get_metas_multiple_param()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(params, stream.add) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_METAS_MULTIPLE_PARAM, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.infos = stream.list(DataStoreMetaInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.get_metas_multiple_param -> done") return obj async def complete_post_objects(self, data_ids): logger.info("DataStoreClientMiitopia3DS.complete_post_objects()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_COMPLETE_POST_OBJECTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.complete_post_objects -> done") async def change_meta(self, param): logger.info("DataStoreClientMiitopia3DS.change_meta()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CHANGE_META, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.change_meta -> done") async def change_metas(self, data_ids, param, transactional): logger.info("DataStoreClientMiitopia3DS.change_metas()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) stream.list(param, stream.add) stream.bool(transactional) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CHANGE_METAS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.change_metas -> done") return results async def rate_objects(self, targets, param, transactional, fetch_ratings): logger.info("DataStoreClientMiitopia3DS.rate_objects()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(targets, stream.add) stream.list(param, stream.add) stream.bool(transactional) stream.bool(fetch_ratings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RATE_OBJECTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.infos = stream.list(DataStoreRatingInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.rate_objects -> done") return obj async def post_meta_binary_with_data_id(self, data_id, param): logger.info("DataStoreClientMiitopia3DS.post_meta_binary_with_data_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(data_id) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_POST_META_BINARY_WITH_DATA_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.post_meta_binary_with_data_id -> done") async def post_meta_binaries_with_data_id(self, data_ids, param, transactional): logger.info("DataStoreClientMiitopia3DS.post_meta_binaries_with_data_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) stream.list(param, stream.add) stream.bool(transactional) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_POST_META_BINARIES_WITH_DATA_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.post_meta_binaries_with_data_id -> done") return results async def rate_object_with_posting(self, target, rate_param, post_param, fetch_ratings): logger.info("DataStoreClientMiitopia3DS.rate_object_with_posting()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) stream.add(rate_param) stream.add(post_param) stream.bool(fetch_ratings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RATE_OBJECT_WITH_POSTING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreRatingInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.rate_object_with_posting -> done") return info async def rate_objects_with_posting(self, targets, rate_param, post_param, transactional, fetch_ratings): logger.info("DataStoreClientMiitopia3DS.rate_objects_with_posting()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(targets, stream.add) stream.list(rate_param, stream.add) stream.list(post_param, stream.add) stream.bool(transactional) stream.bool(fetch_ratings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RATE_OBJECTS_WITH_POSTING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.ratings = stream.list(DataStoreRatingInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.rate_objects_with_posting -> done") return obj async def get_object_infos(self, data_ids): logger.info("DataStoreClientMiitopia3DS.get_object_infos()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_OBJECT_INFOS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.infos = stream.list(DataStoreReqGetInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.get_object_infos -> done") return obj async def search_object_light(self, param): logger.info("DataStoreClientMiitopia3DS.search_object_light()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_OBJECT_LIGHT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.extract(DataStoreSearchResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.search_object_light -> done") return result async def search_mii(self, param): logger.info("DataStoreClientMiitopia3DS.search_mii()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_MII, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) search_result = stream.extract(MiiTubeSearchResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientMiitopia3DS.search_mii -> done") return search_result class DataStoreServerMiitopia3DS(DataStoreProtocolMiitopia3DS): def __init__(self): self.methods = { self.METHOD_PREPARE_GET_OBJECT_V1: self.handle_prepare_get_object_v1, self.METHOD_PREPARE_POST_OBJECT_V1: self.handle_prepare_post_object_v1, self.METHOD_COMPLETE_POST_OBJECT_V1: self.handle_complete_post_object_v1, self.METHOD_DELETE_OBJECT: self.handle_delete_object, self.METHOD_DELETE_OBJECTS: self.handle_delete_objects, self.METHOD_CHANGE_META_V1: self.handle_change_meta_v1, self.METHOD_CHANGE_METAS_V1: self.handle_change_metas_v1, self.METHOD_GET_META: self.handle_get_meta, self.METHOD_GET_METAS: self.handle_get_metas, self.METHOD_PREPARE_UPDATE_OBJECT: self.handle_prepare_update_object, self.METHOD_COMPLETE_UPDATE_OBJECT: self.handle_complete_update_object, self.METHOD_SEARCH_OBJECT: self.handle_search_object, self.METHOD_GET_NOTIFICATION_URL: self.handle_get_notification_url, self.METHOD_GET_NEW_ARRIVED_NOTIFICATIONS_V1: self.handle_get_new_arrived_notifications_v1, self.METHOD_RATE_OBJECT: self.handle_rate_object, self.METHOD_GET_RATING: self.handle_get_rating, self.METHOD_GET_RATINGS: self.handle_get_ratings, self.METHOD_RESET_RATING: self.handle_reset_rating, self.METHOD_RESET_RATINGS: self.handle_reset_ratings, self.METHOD_GET_SPECIFIC_META_V1: self.handle_get_specific_meta_v1, self.METHOD_POST_META_BINARY: self.handle_post_meta_binary, self.METHOD_TOUCH_OBJECT: self.handle_touch_object, self.METHOD_GET_RATING_WITH_LOG: self.handle_get_rating_with_log, self.METHOD_PREPARE_POST_OBJECT: self.handle_prepare_post_object, self.METHOD_PREPARE_GET_OBJECT: self.handle_prepare_get_object, self.METHOD_COMPLETE_POST_OBJECT: self.handle_complete_post_object, self.METHOD_GET_NEW_ARRIVED_NOTIFICATIONS: self.handle_get_new_arrived_notifications, self.METHOD_GET_SPECIFIC_META: self.handle_get_specific_meta, self.METHOD_GET_PERSISTENCE_INFO: self.handle_get_persistence_info, self.METHOD_GET_PERSISTENCE_INFOS: self.handle_get_persistence_infos, self.METHOD_PERPETUATE_OBJECT: self.handle_perpetuate_object, self.METHOD_UNPERPETUATE_OBJECT: self.handle_unperpetuate_object, self.METHOD_PREPARE_GET_OBJECT_OR_META_BINARY: self.handle_prepare_get_object_or_meta_binary, self.METHOD_GET_PASSWORD_INFO: self.handle_get_password_info, self.METHOD_GET_PASSWORD_INFOS: self.handle_get_password_infos, self.METHOD_GET_METAS_MULTIPLE_PARAM: self.handle_get_metas_multiple_param, self.METHOD_COMPLETE_POST_OBJECTS: self.handle_complete_post_objects, self.METHOD_CHANGE_META: self.handle_change_meta, self.METHOD_CHANGE_METAS: self.handle_change_metas, self.METHOD_RATE_OBJECTS: self.handle_rate_objects, self.METHOD_POST_META_BINARY_WITH_DATA_ID: self.handle_post_meta_binary_with_data_id, self.METHOD_POST_META_BINARIES_WITH_DATA_ID: self.handle_post_meta_binaries_with_data_id, self.METHOD_RATE_OBJECT_WITH_POSTING: self.handle_rate_object_with_posting, self.METHOD_RATE_OBJECTS_WITH_POSTING: self.handle_rate_objects_with_posting, self.METHOD_GET_OBJECT_INFOS: self.handle_get_object_infos, self.METHOD_SEARCH_OBJECT_LIGHT: self.handle_search_object_light, self.METHOD_SEARCH_MII: self.handle_search_mii, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on DataStoreServerMiitopia3DS: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_prepare_get_object_v1(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.prepare_get_object_v1()") #--- request --- param = input.extract(DataStorePrepareGetParamV1) response = await self.prepare_get_object_v1(client, param) #--- response --- if not isinstance(response, DataStoreReqGetInfoV1): raise RuntimeError("Expected DataStoreReqGetInfoV1, got %s" %response.__class__.__name__) output.add(response) async def handle_prepare_post_object_v1(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.prepare_post_object_v1()") #--- request --- param = input.extract(DataStorePreparePostParamV1) response = await self.prepare_post_object_v1(client, param) #--- response --- if not isinstance(response, DataStoreReqPostInfoV1): raise RuntimeError("Expected DataStoreReqPostInfoV1, got %s" %response.__class__.__name__) output.add(response) async def handle_complete_post_object_v1(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.complete_post_object_v1()") #--- request --- param = input.extract(DataStoreCompletePostParamV1) await self.complete_post_object_v1(client, param) async def handle_delete_object(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.delete_object()") #--- request --- param = input.extract(DataStoreDeleteParam) await self.delete_object(client, param) async def handle_delete_objects(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.delete_objects()") #--- request --- param = input.list(DataStoreDeleteParam) transactional = input.bool() response = await self.delete_objects(client, param, transactional) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.result) async def handle_change_meta_v1(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.change_meta_v1()") #--- request --- param = input.extract(DataStoreChangeMetaParamV1) await self.change_meta_v1(client, param) async def handle_change_metas_v1(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.change_metas_v1()") #--- request --- data_ids = input.list(input.u64) param = input.list(DataStoreChangeMetaParamV1) transactional = input.bool() response = await self.change_metas_v1(client, data_ids, param, transactional) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.result) async def handle_get_meta(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.get_meta()") #--- request --- param = input.extract(DataStoreGetMetaParam) response = await self.get_meta(client, param) #--- response --- if not isinstance(response, DataStoreMetaInfo): raise RuntimeError("Expected DataStoreMetaInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_metas(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.get_metas()") #--- request --- data_ids = input.list(input.u64) param = input.extract(DataStoreGetMetaParam) response = await self.get_metas(client, data_ids, param) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['info', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.info, output.add) output.list(response.results, output.result) async def handle_prepare_update_object(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.prepare_update_object()") #--- request --- param = input.extract(DataStorePrepareUpdateParam) response = await self.prepare_update_object(client, param) #--- response --- if not isinstance(response, DataStoreReqUpdateInfo): raise RuntimeError("Expected DataStoreReqUpdateInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_complete_update_object(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.complete_update_object()") #--- request --- param = input.extract(DataStoreCompleteUpdateParam) await self.complete_update_object(client, param) async def handle_search_object(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.search_object()") #--- request --- param = input.extract(DataStoreSearchParam) response = await self.search_object(client, param) #--- response --- if not isinstance(response, DataStoreSearchResult): raise RuntimeError("Expected DataStoreSearchResult, got %s" %response.__class__.__name__) output.add(response) async def handle_get_notification_url(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.get_notification_url()") #--- request --- param = input.extract(DataStoreGetNotificationUrlParam) response = await self.get_notification_url(client, param) #--- response --- if not isinstance(response, DataStoreReqGetNotificationUrlInfo): raise RuntimeError("Expected DataStoreReqGetNotificationUrlInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_new_arrived_notifications_v1(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.get_new_arrived_notifications_v1()") #--- request --- param = input.extract(DataStoreGetNewArrivedNotificationsParam) response = await self.get_new_arrived_notifications_v1(client, param) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'has_next']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.result, output.add) output.bool(response.has_next) async def handle_rate_object(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.rate_object()") #--- request --- target = input.extract(DataStoreRatingTarget) param = input.extract(DataStoreRateObjectParam) fetch_ratings = input.bool() response = await self.rate_object(client, target, param, fetch_ratings) #--- response --- if not isinstance(response, DataStoreRatingInfo): raise RuntimeError("Expected DataStoreRatingInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_rating(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.get_rating()") #--- request --- target = input.extract(DataStoreRatingTarget) access_password = input.u64() response = await self.get_rating(client, target, access_password) #--- response --- if not isinstance(response, DataStoreRatingInfo): raise RuntimeError("Expected DataStoreRatingInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_ratings(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.get_ratings()") #--- request --- data_ids = input.list(input.u64) access_password = input.u64() response = await self.get_ratings(client, data_ids, access_password) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['ratings', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.ratings, lambda x: output.list(x, output.add)) output.list(response.results, output.result) async def handle_reset_rating(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.reset_rating()") #--- request --- target = input.extract(DataStoreRatingTarget) update_password = input.u64() await self.reset_rating(client, target, update_password) async def handle_reset_ratings(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.reset_ratings()") #--- request --- data_ids = input.list(input.u64) transactional = input.bool() response = await self.reset_ratings(client, data_ids, transactional) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.result) async def handle_get_specific_meta_v1(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.get_specific_meta_v1()") #--- request --- param = input.extract(DataStoreGetSpecificMetaParamV1) response = await self.get_specific_meta_v1(client, param) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_post_meta_binary(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.post_meta_binary()") #--- request --- param = input.extract(DataStorePreparePostParam) response = await self.post_meta_binary(client, param) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u64(response) async def handle_touch_object(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.touch_object()") #--- request --- param = input.extract(DataStoreTouchObjectParam) await self.touch_object(client, param) async def handle_get_rating_with_log(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.get_rating_with_log()") #--- request --- target = input.extract(DataStoreRatingTarget) access_password = input.u64() response = await self.get_rating_with_log(client, target, access_password) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['rating', 'log']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.add(response.rating) output.add(response.log) async def handle_prepare_post_object(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.prepare_post_object()") #--- request --- param = input.extract(DataStorePreparePostParam) response = await self.prepare_post_object(client, param) #--- response --- if not isinstance(response, DataStoreReqPostInfo): raise RuntimeError("Expected DataStoreReqPostInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_prepare_get_object(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.prepare_get_object()") #--- request --- param = input.extract(DataStorePrepareGetParam) response = await self.prepare_get_object(client, param) #--- response --- if not isinstance(response, DataStoreReqGetInfo): raise RuntimeError("Expected DataStoreReqGetInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_complete_post_object(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.complete_post_object()") #--- request --- param = input.extract(DataStoreCompletePostParam) await self.complete_post_object(client, param) async def handle_get_new_arrived_notifications(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.get_new_arrived_notifications()") #--- request --- param = input.extract(DataStoreGetNewArrivedNotificationsParam) response = await self.get_new_arrived_notifications(client, param) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'has_next']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.result, output.add) output.bool(response.has_next) async def handle_get_specific_meta(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.get_specific_meta()") #--- request --- param = input.extract(DataStoreGetSpecificMetaParam) response = await self.get_specific_meta(client, param) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_persistence_info(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.get_persistence_info()") #--- request --- owner_id = input.pid() slot_id = input.u16() response = await self.get_persistence_info(client, owner_id, slot_id) #--- response --- if not isinstance(response, DataStorePersistenceInfo): raise RuntimeError("Expected DataStorePersistenceInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_persistence_infos(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.get_persistence_infos()") #--- request --- owner_id = input.pid() slot_ids = input.list(input.u16) response = await self.get_persistence_infos(client, owner_id, slot_ids) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['infos', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.infos, output.add) output.list(response.results, output.result) async def handle_perpetuate_object(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.perpetuate_object()") #--- request --- persistence_slot_id = input.u16() data_id = input.u64() delete_last_object = input.bool() await self.perpetuate_object(client, persistence_slot_id, data_id, delete_last_object) async def handle_unperpetuate_object(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.unperpetuate_object()") #--- request --- persistence_slot_id = input.u16() delete_last_object = input.bool() await self.unperpetuate_object(client, persistence_slot_id, delete_last_object) async def handle_prepare_get_object_or_meta_binary(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.prepare_get_object_or_meta_binary()") #--- request --- param = input.extract(DataStorePrepareGetParam) response = await self.prepare_get_object_or_meta_binary(client, param) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['get_info', 'additional_meta']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.add(response.get_info) output.add(response.additional_meta) async def handle_get_password_info(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.get_password_info()") #--- request --- data_id = input.u64() response = await self.get_password_info(client, data_id) #--- response --- if not isinstance(response, DataStorePasswordInfo): raise RuntimeError("Expected DataStorePasswordInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_password_infos(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.get_password_infos()") #--- request --- data_ids = input.list(input.u64) response = await self.get_password_infos(client, data_ids) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['infos', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.infos, output.add) output.list(response.results, output.result) async def handle_get_metas_multiple_param(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.get_metas_multiple_param()") #--- request --- params = input.list(DataStoreGetMetaParam) response = await self.get_metas_multiple_param(client, params) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['infos', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.infos, output.add) output.list(response.results, output.result) async def handle_complete_post_objects(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.complete_post_objects()") #--- request --- data_ids = input.list(input.u64) await self.complete_post_objects(client, data_ids) async def handle_change_meta(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.change_meta()") #--- request --- param = input.extract(DataStoreChangeMetaParam) await self.change_meta(client, param) async def handle_change_metas(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.change_metas()") #--- request --- data_ids = input.list(input.u64) param = input.list(DataStoreChangeMetaParam) transactional = input.bool() response = await self.change_metas(client, data_ids, param, transactional) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.result) async def handle_rate_objects(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.rate_objects()") #--- request --- targets = input.list(DataStoreRatingTarget) param = input.list(DataStoreRateObjectParam) transactional = input.bool() fetch_ratings = input.bool() response = await self.rate_objects(client, targets, param, transactional, fetch_ratings) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['infos', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.infos, output.add) output.list(response.results, output.result) async def handle_post_meta_binary_with_data_id(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.post_meta_binary_with_data_id()") #--- request --- data_id = input.u64() param = input.extract(DataStorePreparePostParam) await self.post_meta_binary_with_data_id(client, data_id, param) async def handle_post_meta_binaries_with_data_id(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.post_meta_binaries_with_data_id()") #--- request --- data_ids = input.list(input.u64) param = input.list(DataStorePreparePostParam) transactional = input.bool() response = await self.post_meta_binaries_with_data_id(client, data_ids, param, transactional) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.result) async def handle_rate_object_with_posting(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.rate_object_with_posting()") #--- request --- target = input.extract(DataStoreRatingTarget) rate_param = input.extract(DataStoreRateObjectParam) post_param = input.extract(DataStorePreparePostParam) fetch_ratings = input.bool() response = await self.rate_object_with_posting(client, target, rate_param, post_param, fetch_ratings) #--- response --- if not isinstance(response, DataStoreRatingInfo): raise RuntimeError("Expected DataStoreRatingInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_rate_objects_with_posting(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.rate_objects_with_posting()") #--- request --- targets = input.list(DataStoreRatingTarget) rate_param = input.list(DataStoreRateObjectParam) post_param = input.list(DataStorePreparePostParam) transactional = input.bool() fetch_ratings = input.bool() response = await self.rate_objects_with_posting(client, targets, rate_param, post_param, transactional, fetch_ratings) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['ratings', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.ratings, output.add) output.list(response.results, output.result) async def handle_get_object_infos(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.get_object_infos()") #--- request --- data_ids = input.list(input.u64) response = await self.get_object_infos(client, data_ids) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['infos', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.infos, output.add) output.list(response.results, output.result) async def handle_search_object_light(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.search_object_light()") #--- request --- param = input.extract(DataStoreSearchParam) response = await self.search_object_light(client, param) #--- response --- if not isinstance(response, DataStoreSearchResult): raise RuntimeError("Expected DataStoreSearchResult, got %s" %response.__class__.__name__) output.add(response) async def handle_search_mii(self, client, input, output): logger.info("DataStoreServerMiitopia3DS.search_mii()") #--- request --- param = input.extract(MiiTubeSearchParam) response = await self.search_mii(client, param) #--- response --- if not isinstance(response, MiiTubeSearchResult): raise RuntimeError("Expected MiiTubeSearchResult, got %s" %response.__class__.__name__) output.add(response) async def prepare_get_object_v1(self, *args): logger.warning("DataStoreServerMiitopia3DS.prepare_get_object_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def prepare_post_object_v1(self, *args): logger.warning("DataStoreServerMiitopia3DS.prepare_post_object_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def complete_post_object_v1(self, *args): logger.warning("DataStoreServerMiitopia3DS.complete_post_object_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def delete_object(self, *args): logger.warning("DataStoreServerMiitopia3DS.delete_object not implemented") raise common.RMCError("Core::NotImplemented") async def delete_objects(self, *args): logger.warning("DataStoreServerMiitopia3DS.delete_objects not implemented") raise common.RMCError("Core::NotImplemented") async def change_meta_v1(self, *args): logger.warning("DataStoreServerMiitopia3DS.change_meta_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def change_metas_v1(self, *args): logger.warning("DataStoreServerMiitopia3DS.change_metas_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def get_meta(self, *args): logger.warning("DataStoreServerMiitopia3DS.get_meta not implemented") raise common.RMCError("Core::NotImplemented") async def get_metas(self, *args): logger.warning("DataStoreServerMiitopia3DS.get_metas not implemented") raise common.RMCError("Core::NotImplemented") async def prepare_update_object(self, *args): logger.warning("DataStoreServerMiitopia3DS.prepare_update_object not implemented") raise common.RMCError("Core::NotImplemented") async def complete_update_object(self, *args): logger.warning("DataStoreServerMiitopia3DS.complete_update_object not implemented") raise common.RMCError("Core::NotImplemented") async def search_object(self, *args): logger.warning("DataStoreServerMiitopia3DS.search_object not implemented") raise common.RMCError("Core::NotImplemented") async def get_notification_url(self, *args): logger.warning("DataStoreServerMiitopia3DS.get_notification_url not implemented") raise common.RMCError("Core::NotImplemented") async def get_new_arrived_notifications_v1(self, *args): logger.warning("DataStoreServerMiitopia3DS.get_new_arrived_notifications_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def rate_object(self, *args): logger.warning("DataStoreServerMiitopia3DS.rate_object not implemented") raise common.RMCError("Core::NotImplemented") async def get_rating(self, *args): logger.warning("DataStoreServerMiitopia3DS.get_rating not implemented") raise common.RMCError("Core::NotImplemented") async def get_ratings(self, *args): logger.warning("DataStoreServerMiitopia3DS.get_ratings not implemented") raise common.RMCError("Core::NotImplemented") async def reset_rating(self, *args): logger.warning("DataStoreServerMiitopia3DS.reset_rating not implemented") raise common.RMCError("Core::NotImplemented") async def reset_ratings(self, *args): logger.warning("DataStoreServerMiitopia3DS.reset_ratings not implemented") raise common.RMCError("Core::NotImplemented") async def get_specific_meta_v1(self, *args): logger.warning("DataStoreServerMiitopia3DS.get_specific_meta_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def post_meta_binary(self, *args): logger.warning("DataStoreServerMiitopia3DS.post_meta_binary not implemented") raise common.RMCError("Core::NotImplemented") async def touch_object(self, *args): logger.warning("DataStoreServerMiitopia3DS.touch_object not implemented") raise common.RMCError("Core::NotImplemented") async def get_rating_with_log(self, *args): logger.warning("DataStoreServerMiitopia3DS.get_rating_with_log not implemented") raise common.RMCError("Core::NotImplemented") async def prepare_post_object(self, *args): logger.warning("DataStoreServerMiitopia3DS.prepare_post_object not implemented") raise common.RMCError("Core::NotImplemented") async def prepare_get_object(self, *args): logger.warning("DataStoreServerMiitopia3DS.prepare_get_object not implemented") raise common.RMCError("Core::NotImplemented") async def complete_post_object(self, *args): logger.warning("DataStoreServerMiitopia3DS.complete_post_object not implemented") raise common.RMCError("Core::NotImplemented") async def get_new_arrived_notifications(self, *args): logger.warning("DataStoreServerMiitopia3DS.get_new_arrived_notifications not implemented") raise common.RMCError("Core::NotImplemented") async def get_specific_meta(self, *args): logger.warning("DataStoreServerMiitopia3DS.get_specific_meta not implemented") raise common.RMCError("Core::NotImplemented") async def get_persistence_info(self, *args): logger.warning("DataStoreServerMiitopia3DS.get_persistence_info not implemented") raise common.RMCError("Core::NotImplemented") async def get_persistence_infos(self, *args): logger.warning("DataStoreServerMiitopia3DS.get_persistence_infos not implemented") raise common.RMCError("Core::NotImplemented") async def perpetuate_object(self, *args): logger.warning("DataStoreServerMiitopia3DS.perpetuate_object not implemented") raise common.RMCError("Core::NotImplemented") async def unperpetuate_object(self, *args): logger.warning("DataStoreServerMiitopia3DS.unperpetuate_object not implemented") raise common.RMCError("Core::NotImplemented") async def prepare_get_object_or_meta_binary(self, *args): logger.warning("DataStoreServerMiitopia3DS.prepare_get_object_or_meta_binary not implemented") raise common.RMCError("Core::NotImplemented") async def get_password_info(self, *args): logger.warning("DataStoreServerMiitopia3DS.get_password_info not implemented") raise common.RMCError("Core::NotImplemented") async def get_password_infos(self, *args): logger.warning("DataStoreServerMiitopia3DS.get_password_infos not implemented") raise common.RMCError("Core::NotImplemented") async def get_metas_multiple_param(self, *args): logger.warning("DataStoreServerMiitopia3DS.get_metas_multiple_param not implemented") raise common.RMCError("Core::NotImplemented") async def complete_post_objects(self, *args): logger.warning("DataStoreServerMiitopia3DS.complete_post_objects not implemented") raise common.RMCError("Core::NotImplemented") async def change_meta(self, *args): logger.warning("DataStoreServerMiitopia3DS.change_meta not implemented") raise common.RMCError("Core::NotImplemented") async def change_metas(self, *args): logger.warning("DataStoreServerMiitopia3DS.change_metas not implemented") raise common.RMCError("Core::NotImplemented") async def rate_objects(self, *args): logger.warning("DataStoreServerMiitopia3DS.rate_objects not implemented") raise common.RMCError("Core::NotImplemented") async def post_meta_binary_with_data_id(self, *args): logger.warning("DataStoreServerMiitopia3DS.post_meta_binary_with_data_id not implemented") raise common.RMCError("Core::NotImplemented") async def post_meta_binaries_with_data_id(self, *args): logger.warning("DataStoreServerMiitopia3DS.post_meta_binaries_with_data_id not implemented") raise common.RMCError("Core::NotImplemented") async def rate_object_with_posting(self, *args): logger.warning("DataStoreServerMiitopia3DS.rate_object_with_posting not implemented") raise common.RMCError("Core::NotImplemented") async def rate_objects_with_posting(self, *args): logger.warning("DataStoreServerMiitopia3DS.rate_objects_with_posting not implemented") raise common.RMCError("Core::NotImplemented") async def get_object_infos(self, *args): logger.warning("DataStoreServerMiitopia3DS.get_object_infos not implemented") raise common.RMCError("Core::NotImplemented") async def search_object_light(self, *args): logger.warning("DataStoreServerMiitopia3DS.search_object_light not implemented") raise common.RMCError("Core::NotImplemented") async def search_mii(self, *args): logger.warning("DataStoreServerMiitopia3DS.search_mii not implemented") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/datastore_smm.py ================================================ # This file was generated automatically by generate_protocols.py from nintendo.nex import notification, rmc, common, streams import logging logger = logging.getLogger(__name__) class DataStoreChangeMetaCompareParam(common.Structure): def __init__(self): super().__init__() self.comparison_flag = None self.name = None self.permission = DataStorePermission() self.delete_permission = DataStorePermission() self.period = None self.meta_binary = None self.tags = None self.referred_count = None self.data_type = None self.status = None def check_required(self, settings, version): for field in ['comparison_flag', 'name', 'period', 'meta_binary', 'tags', 'referred_count', 'data_type', 'status']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.comparison_flag = stream.u32() self.name = stream.string() self.permission = stream.extract(DataStorePermission) self.delete_permission = stream.extract(DataStorePermission) self.period = stream.u16() self.meta_binary = stream.qbuffer() self.tags = stream.list(stream.string) self.referred_count = stream.u32() self.data_type = stream.u16() self.status = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.comparison_flag) stream.string(self.name) stream.add(self.permission) stream.add(self.delete_permission) stream.u16(self.period) stream.qbuffer(self.meta_binary) stream.list(self.tags, stream.string) stream.u32(self.referred_count) stream.u16(self.data_type) stream.u8(self.status) class DataStoreChangeMetaParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.modifies_flag = None self.name = None self.permission = DataStorePermission() self.delete_permission = DataStorePermission() self.period = None self.meta_binary = None self.tags = None self.update_password = None self.referred_count = None self.data_type = None self.status = None self.compare_param = DataStoreChangeMetaCompareParam() self.persistence_target = DataStorePersistenceTarget() def check_required(self, settings, version): for field in ['data_id', 'modifies_flag', 'name', 'period', 'meta_binary', 'tags', 'update_password', 'referred_count', 'data_type', 'status']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.modifies_flag = stream.u32() self.name = stream.string() self.permission = stream.extract(DataStorePermission) self.delete_permission = stream.extract(DataStorePermission) self.period = stream.u16() self.meta_binary = stream.qbuffer() self.tags = stream.list(stream.string) self.update_password = stream.u64() self.referred_count = stream.u32() self.data_type = stream.u16() self.status = stream.u8() self.compare_param = stream.extract(DataStoreChangeMetaCompareParam) self.persistence_target = stream.extract(DataStorePersistenceTarget) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.modifies_flag) stream.string(self.name) stream.add(self.permission) stream.add(self.delete_permission) stream.u16(self.period) stream.qbuffer(self.meta_binary) stream.list(self.tags, stream.string) stream.u64(self.update_password) stream.u32(self.referred_count) stream.u16(self.data_type) stream.u8(self.status) stream.add(self.compare_param) stream.add(self.persistence_target) class DataStoreChangeMetaParamV1(common.Structure): def __init__(self): super().__init__() self.data_id = None self.modifies_flag = None self.name = None self.permission = DataStorePermission() self.delete_permission = DataStorePermission() self.period = None self.meta_binary = None self.tags = None self.update_password = None def check_required(self, settings, version): for field in ['data_id', 'modifies_flag', 'name', 'period', 'meta_binary', 'tags', 'update_password']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.modifies_flag = stream.u32() self.name = stream.string() self.permission = stream.extract(DataStorePermission) self.delete_permission = stream.extract(DataStorePermission) self.period = stream.u16() self.meta_binary = stream.qbuffer() self.tags = stream.list(stream.string) self.update_password = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.modifies_flag) stream.string(self.name) stream.add(self.permission) stream.add(self.delete_permission) stream.u16(self.period) stream.qbuffer(self.meta_binary) stream.list(self.tags, stream.string) stream.u64(self.update_password) class DataStoreCompletePostParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.success = None def check_required(self, settings, version): for field in ['data_id', 'success']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.success = stream.bool() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.bool(self.success) class DataStoreCompletePostParamV1(common.Structure): def __init__(self): super().__init__() self.data_id = None self.success = None def check_required(self, settings, version): for field in ['data_id', 'success']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u32() self.success = stream.bool() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.data_id) stream.bool(self.success) class DataStoreCompleteUpdateParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.version = None self.success = None def check_required(self, settings, version): for field in ['data_id', 'version', 'success']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.version = stream.u32() self.success = stream.bool() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.version) stream.bool(self.success) class DataStoreDeleteParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.update_password = None def check_required(self, settings, version): for field in ['data_id', 'update_password']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.update_password = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u64(self.update_password) class DataStoreGetMetaParam(common.Structure): def __init__(self): super().__init__() self.data_id = 0 self.persistence_target = DataStorePersistenceTarget() self.result_option = 0 self.access_password = 0 def check_required(self, settings, version): pass def load(self, stream, version): self.data_id = stream.u64() self.persistence_target = stream.extract(DataStorePersistenceTarget) self.result_option = stream.u8() self.access_password = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.add(self.persistence_target) stream.u8(self.result_option) stream.u64(self.access_password) class DataStoreGetNewArrivedNotificationsParam(common.Structure): def __init__(self): super().__init__() self.last_notification_id = None self.limit = None def check_required(self, settings, version): for field in ['last_notification_id', 'limit']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.last_notification_id = stream.u64() self.limit = stream.u16() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.last_notification_id) stream.u16(self.limit) class DataStoreGetNotificationUrlParam(common.Structure): def __init__(self): super().__init__() self.previous_url = None def check_required(self, settings, version): for field in ['previous_url']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.previous_url = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.previous_url) class DataStoreGetSpecificMetaParam(common.Structure): def __init__(self): super().__init__() self.data_ids = None def check_required(self, settings, version): for field in ['data_ids']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_ids = stream.list(stream.u64) def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.data_ids, stream.u64) class DataStoreGetSpecificMetaParamV1(common.Structure): def __init__(self): super().__init__() self.data_ids = None def check_required(self, settings, version): for field in ['data_ids']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_ids = stream.list(stream.u32) def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.data_ids, stream.u32) class DataStoreKeyValue(common.Structure): def __init__(self): super().__init__() self.key = None self.value = None def check_required(self, settings, version): for field in ['key', 'value']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.key = stream.string() self.value = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.key) stream.string(self.value) class DataStoreMetaInfo(common.Structure): def __init__(self): super().__init__() self.data_id = None self.owner_id = None self.size = None self.name = None self.data_type = None self.meta_binary = None self.permission = DataStorePermission() self.delete_permission = DataStorePermission() self.create_time = None self.update_time = None self.period = None self.status = None self.referred_count = None self.refer_data_id = None self.flag = None self.referred_time = None self.expire_time = None self.tags = None self.ratings = None def check_required(self, settings, version): for field in ['data_id', 'owner_id', 'size', 'name', 'data_type', 'meta_binary', 'create_time', 'update_time', 'period', 'status', 'referred_count', 'refer_data_id', 'flag', 'referred_time', 'expire_time', 'tags', 'ratings']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.owner_id = stream.pid() self.size = stream.u32() self.name = stream.string() self.data_type = stream.u16() self.meta_binary = stream.qbuffer() self.permission = stream.extract(DataStorePermission) self.delete_permission = stream.extract(DataStorePermission) self.create_time = stream.datetime() self.update_time = stream.datetime() self.period = stream.u16() self.status = stream.u8() self.referred_count = stream.u32() self.refer_data_id = stream.u32() self.flag = stream.u32() self.referred_time = stream.datetime() self.expire_time = stream.datetime() self.tags = stream.list(stream.string) self.ratings = stream.list(DataStoreRatingInfoWithSlot) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.pid(self.owner_id) stream.u32(self.size) stream.string(self.name) stream.u16(self.data_type) stream.qbuffer(self.meta_binary) stream.add(self.permission) stream.add(self.delete_permission) stream.datetime(self.create_time) stream.datetime(self.update_time) stream.u16(self.period) stream.u8(self.status) stream.u32(self.referred_count) stream.u32(self.refer_data_id) stream.u32(self.flag) stream.datetime(self.referred_time) stream.datetime(self.expire_time) stream.list(self.tags, stream.string) stream.list(self.ratings, stream.add) class DataStoreNotification(common.Structure): def __init__(self): super().__init__() self.notification_id = None self.data_id = None def check_required(self, settings, version): for field in ['notification_id', 'data_id']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.notification_id = stream.u64() self.data_id = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.notification_id) stream.u64(self.data_id) class DataStoreNotificationV1(common.Structure): def __init__(self): super().__init__() self.notification_id = None self.data_id = None def check_required(self, settings, version): for field in ['notification_id', 'data_id']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.notification_id = stream.u64() self.data_id = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.notification_id) stream.u32(self.data_id) class DataStorePasswordInfo(common.Structure): def __init__(self): super().__init__() self.data_id = None self.access_password = None self.update_password = None def check_required(self, settings, version): for field in ['data_id', 'access_password', 'update_password']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.access_password = stream.u64() self.update_password = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u64(self.access_password) stream.u64(self.update_password) class DataStorePermission(common.Structure): def __init__(self): super().__init__() self.permission = 3 self.recipients = [] def check_required(self, settings, version): pass def load(self, stream, version): self.permission = stream.u8() self.recipients = stream.list(stream.pid) def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.permission) stream.list(self.recipients, stream.pid) class DataStorePersistenceInfo(common.Structure): def __init__(self): super().__init__() self.owner_id = None self.slot_id = None self.data_id = None def check_required(self, settings, version): for field in ['owner_id', 'slot_id', 'data_id']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.owner_id = stream.pid() self.slot_id = stream.u16() self.data_id = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.owner_id) stream.u16(self.slot_id) stream.u64(self.data_id) class DataStorePersistenceInitParam(common.Structure): def __init__(self): super().__init__() self.persistence_id = 65535 self.delete_last_object = True def check_required(self, settings, version): pass def load(self, stream, version): self.persistence_id = stream.u16() self.delete_last_object = stream.bool() def save(self, stream, version): self.check_required(stream.settings, version) stream.u16(self.persistence_id) stream.bool(self.delete_last_object) class DataStorePersistenceTarget(common.Structure): def __init__(self): super().__init__() self.owner_id = 0 self.persistence_id = 65535 def check_required(self, settings, version): pass def load(self, stream, version): self.owner_id = stream.pid() self.persistence_id = stream.u16() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.owner_id) stream.u16(self.persistence_id) class DataStorePrepareGetParam(common.Structure): def __init__(self): super().__init__() self.data_id = 0 self.lock_id = 0 self.persistence_target = DataStorePersistenceTarget() self.access_password = 0 self.extra_data = [] def check_required(self, settings, version): if settings["nex.version"] >= 30500: pass def load(self, stream, version): self.data_id = stream.u64() self.lock_id = stream.u32() self.persistence_target = stream.extract(DataStorePersistenceTarget) self.access_password = stream.u64() if stream.settings["nex.version"] >= 30500: self.extra_data = stream.list(stream.string) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.lock_id) stream.add(self.persistence_target) stream.u64(self.access_password) if stream.settings["nex.version"] >= 30500: stream.list(self.extra_data, stream.string) class DataStorePrepareGetParamV1(common.Structure): def __init__(self): super().__init__() self.data_id = None self.lock_id = 0 def check_required(self, settings, version): for field in ['data_id']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u32() self.lock_id = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.data_id) stream.u32(self.lock_id) class DataStorePreparePostParam(common.Structure): def __init__(self): super().__init__() self.size = None self.name = None self.data_type = None self.meta_binary = None self.permission = DataStorePermission() self.delete_permission = DataStorePermission() self.flag = None self.period = None self.refer_data_id = 0 self.tags = [] self.rating_init_param = [] self.persistence_init_param = DataStorePersistenceInitParam() self.extra_data = None def check_required(self, settings, version): for field in ['size', 'name', 'data_type', 'meta_binary', 'flag', 'period']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) if settings["nex.version"] >= 30500: for field in ['extra_data']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.size = stream.u32() self.name = stream.string() self.data_type = stream.u16() self.meta_binary = stream.qbuffer() self.permission = stream.extract(DataStorePermission) self.delete_permission = stream.extract(DataStorePermission) self.flag = stream.u32() self.period = stream.u16() self.refer_data_id = stream.u32() self.tags = stream.list(stream.string) self.rating_init_param = stream.list(DataStoreRatingInitParamWithSlot) self.persistence_init_param = stream.extract(DataStorePersistenceInitParam) if stream.settings["nex.version"] >= 30500: self.extra_data = stream.list(stream.string) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.size) stream.string(self.name) stream.u16(self.data_type) stream.qbuffer(self.meta_binary) stream.add(self.permission) stream.add(self.delete_permission) stream.u32(self.flag) stream.u16(self.period) stream.u32(self.refer_data_id) stream.list(self.tags, stream.string) stream.list(self.rating_init_param, stream.add) stream.add(self.persistence_init_param) if stream.settings["nex.version"] >= 30500: stream.list(self.extra_data, stream.string) class DataStorePreparePostParamV1(common.Structure): def __init__(self): super().__init__() self.size = None self.name = None self.data_type = 0 self.meta_binary = b"" self.permission = DataStorePermission() self.delete_permission = DataStorePermission() self.flag = None self.period = None self.refer_data_id = 0 self.tags = None self.rating_init_param = None def check_required(self, settings, version): for field in ['size', 'name', 'flag', 'period', 'tags', 'rating_init_param']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.size = stream.u32() self.name = stream.string() self.data_type = stream.u16() self.meta_binary = stream.qbuffer() self.permission = stream.extract(DataStorePermission) self.delete_permission = stream.extract(DataStorePermission) self.flag = stream.u32() self.period = stream.u16() self.refer_data_id = stream.u32() self.tags = stream.list(stream.string) self.rating_init_param = stream.list(DataStoreRatingInitParamWithSlot) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.size) stream.string(self.name) stream.u16(self.data_type) stream.qbuffer(self.meta_binary) stream.add(self.permission) stream.add(self.delete_permission) stream.u32(self.flag) stream.u16(self.period) stream.u32(self.refer_data_id) stream.list(self.tags, stream.string) stream.list(self.rating_init_param, stream.add) class DataStorePrepareUpdateParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.size = None self.update_password = None self.extra_data = None def check_required(self, settings, version): for field in ['data_id', 'size', 'update_password', 'extra_data']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.size = stream.u32() self.update_password = stream.u64() self.extra_data = stream.list(stream.string) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.size) stream.u64(self.update_password) stream.list(self.extra_data, stream.string) class DataStoreRateObjectParam(common.Structure): def __init__(self): super().__init__() self.rating_value = None self.access_password = None def check_required(self, settings, version): for field in ['rating_value', 'access_password']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.rating_value = stream.s32() self.access_password = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.s32(self.rating_value) stream.u64(self.access_password) class DataStoreRatingInfo(common.Structure): def __init__(self): super().__init__() self.total_value = None self.count = None self.initial_value = None def check_required(self, settings, version): for field in ['total_value', 'count', 'initial_value']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.total_value = stream.s64() self.count = stream.u32() self.initial_value = stream.s64() def save(self, stream, version): self.check_required(stream.settings, version) stream.s64(self.total_value) stream.u32(self.count) stream.s64(self.initial_value) class DataStoreRatingInfoWithSlot(common.Structure): def __init__(self): super().__init__() self.slot = None self.info = DataStoreRatingInfo() def check_required(self, settings, version): for field in ['slot']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.slot = stream.u8() self.info = stream.extract(DataStoreRatingInfo) def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.slot) stream.add(self.info) class DataStoreRatingInitParam(common.Structure): def __init__(self): super().__init__() self.flag = None self.internal_flag = None self.lock_type = None self.initial_value = None self.range_min = None self.range_max = None self.period_hour = None self.period_duration = None def check_required(self, settings, version): for field in ['flag', 'internal_flag', 'lock_type', 'initial_value', 'range_min', 'range_max', 'period_hour', 'period_duration']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.flag = stream.u8() self.internal_flag = stream.u8() self.lock_type = stream.u8() self.initial_value = stream.s64() self.range_min = stream.s32() self.range_max = stream.s32() self.period_hour = stream.s8() self.period_duration = stream.s16() def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.flag) stream.u8(self.internal_flag) stream.u8(self.lock_type) stream.s64(self.initial_value) stream.s32(self.range_min) stream.s32(self.range_max) stream.s8(self.period_hour) stream.s16(self.period_duration) class DataStoreRatingInitParamWithSlot(common.Structure): def __init__(self): super().__init__() self.slot = None self.param = DataStoreRatingInitParam() def check_required(self, settings, version): for field in ['slot']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.slot = stream.s8() self.param = stream.extract(DataStoreRatingInitParam) def save(self, stream, version): self.check_required(stream.settings, version) stream.s8(self.slot) stream.add(self.param) class DataStoreRatingLog(common.Structure): def __init__(self): super().__init__() self.is_rated = None self.pid = None self.rating_value = None self.lock_expiration_time = None def check_required(self, settings, version): for field in ['is_rated', 'pid', 'rating_value', 'lock_expiration_time']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.is_rated = stream.bool() self.pid = stream.pid() self.rating_value = stream.s32() self.lock_expiration_time = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.bool(self.is_rated) stream.pid(self.pid) stream.s32(self.rating_value) stream.datetime(self.lock_expiration_time) class DataStoreRatingTarget(common.Structure): def __init__(self): super().__init__() self.data_id = None self.slot = None def check_required(self, settings, version): for field in ['data_id', 'slot']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.slot = stream.s8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.s8(self.slot) class DataStoreReqGetAdditionalMeta(common.Structure): def __init__(self): super().__init__() self.owner_id = None self.data_type = None self.version = None self.meta_binary = None def check_required(self, settings, version): for field in ['owner_id', 'data_type', 'version', 'meta_binary']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.owner_id = stream.pid() self.data_type = stream.u16() self.version = stream.u16() self.meta_binary = stream.qbuffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.owner_id) stream.u16(self.data_type) stream.u16(self.version) stream.qbuffer(self.meta_binary) class DataStoreReqGetInfo(common.Structure): def __init__(self): super().__init__() self.url = None self.headers = None self.size = None self.root_ca_cert = None self.data_id = None def check_required(self, settings, version): for field in ['url', 'headers', 'size', 'root_ca_cert']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) if settings["nex.version"] >= 30500: for field in ['data_id']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.url = stream.string() self.headers = stream.list(DataStoreKeyValue) self.size = stream.u32() self.root_ca_cert = stream.buffer() if stream.settings["nex.version"] >= 30500: self.data_id = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.url) stream.list(self.headers, stream.add) stream.u32(self.size) stream.buffer(self.root_ca_cert) if stream.settings["nex.version"] >= 30500: stream.u64(self.data_id) class DataStoreReqGetInfoV1(common.Structure): def __init__(self): super().__init__() self.url = None self.headers = None self.size = None self.root_ca_cert = None def check_required(self, settings, version): for field in ['url', 'headers', 'size', 'root_ca_cert']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.url = stream.string() self.headers = stream.list(DataStoreKeyValue) self.size = stream.u32() self.root_ca_cert = stream.buffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.url) stream.list(self.headers, stream.add) stream.u32(self.size) stream.buffer(self.root_ca_cert) class DataStoreReqGetNotificationUrlInfo(common.Structure): def __init__(self): super().__init__() self.url = None self.key = None self.query = None self.root_ca_cert = None def check_required(self, settings, version): for field in ['url', 'key', 'query', 'root_ca_cert']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.url = stream.string() self.key = stream.string() self.query = stream.string() self.root_ca_cert = stream.buffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.url) stream.string(self.key) stream.string(self.query) stream.buffer(self.root_ca_cert) class DataStoreReqPostInfo(common.Structure): def __init__(self): super().__init__() self.data_id = None self.url = None self.headers = None self.form = None self.root_ca_cert = None def check_required(self, settings, version): for field in ['data_id', 'url', 'headers', 'form', 'root_ca_cert']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.url = stream.string() self.headers = stream.list(DataStoreKeyValue) self.form = stream.list(DataStoreKeyValue) self.root_ca_cert = stream.buffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.string(self.url) stream.list(self.headers, stream.add) stream.list(self.form, stream.add) stream.buffer(self.root_ca_cert) class DataStoreReqPostInfoV1(common.Structure): def __init__(self): super().__init__() self.data_id = None self.url = None self.headers = None self.form = None self.root_ca_cert = None def check_required(self, settings, version): for field in ['data_id', 'url', 'headers', 'form', 'root_ca_cert']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u32() self.url = stream.string() self.headers = stream.list(DataStoreKeyValue) self.form = stream.list(DataStoreKeyValue) self.root_ca_cert = stream.buffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.data_id) stream.string(self.url) stream.list(self.headers, stream.add) stream.list(self.form, stream.add) stream.buffer(self.root_ca_cert) class DataStoreReqUpdateInfo(common.Structure): def __init__(self): super().__init__() self.version = None self.url = None self.headers = None self.form = None self.root_ca_cert = None def check_required(self, settings, version): for field in ['version', 'url', 'headers', 'form', 'root_ca_cert']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.version = stream.u32() self.url = stream.string() self.headers = stream.list(DataStoreKeyValue) self.form = stream.list(DataStoreKeyValue) self.root_ca_cert = stream.buffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.version) stream.string(self.url) stream.list(self.headers, stream.add) stream.list(self.form, stream.add) stream.buffer(self.root_ca_cert) class DataStoreSearchParam(common.Structure): def __init__(self): super().__init__() self.search_target = 1 self.owner_ids = [] self.owner_type = 0 self.destination_ids = [] self.data_type = 65535 self.created_after = common.DateTime(671076024059) self.created_before = common.DateTime(671076024059) self.updated_after = common.DateTime(671076024059) self.updated_before = common.DateTime(671076024059) self.refer_data_id = 0 self.tags = [] self.result_order_column = 0 self.result_order = 0 self.result_range = common.ResultRange() self.result_option = 0 self.minimal_rating_frequency = 0 self.use_cache = False self.total_count_enabled = True self.data_types = [] def check_required(self, settings, version): pass def load(self, stream, version): self.search_target = stream.u8() self.owner_ids = stream.list(stream.pid) self.owner_type = stream.u8() self.destination_ids = stream.list(stream.u64) self.data_type = stream.u16() self.created_after = stream.datetime() self.created_before = stream.datetime() self.updated_after = stream.datetime() self.updated_before = stream.datetime() self.refer_data_id = stream.u32() self.tags = stream.list(stream.string) self.result_order_column = stream.u8() self.result_order = stream.u8() self.result_range = stream.extract(common.ResultRange) self.result_option = stream.u8() self.minimal_rating_frequency = stream.u32() self.use_cache = stream.bool() self.total_count_enabled = stream.bool() self.data_types = stream.list(stream.u16) def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.search_target) stream.list(self.owner_ids, stream.pid) stream.u8(self.owner_type) stream.list(self.destination_ids, stream.u64) stream.u16(self.data_type) stream.datetime(self.created_after) stream.datetime(self.created_before) stream.datetime(self.updated_after) stream.datetime(self.updated_before) stream.u32(self.refer_data_id) stream.list(self.tags, stream.string) stream.u8(self.result_order_column) stream.u8(self.result_order) stream.add(self.result_range) stream.u8(self.result_option) stream.u32(self.minimal_rating_frequency) stream.bool(self.use_cache) stream.bool(self.total_count_enabled) stream.list(self.data_types, stream.u16) class DataStoreSearchResult(common.Structure): def __init__(self): super().__init__() self.total_count = None self.result = None self.total_count_type = None def check_required(self, settings, version): for field in ['total_count', 'result', 'total_count_type']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.total_count = stream.u32() self.result = stream.list(DataStoreMetaInfo) self.total_count_type = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.total_count) stream.list(self.result, stream.add) stream.u8(self.total_count_type) class DataStoreSpecificMetaInfo(common.Structure): def __init__(self): super().__init__() self.data_id = None self.owner_id = None self.size = None self.data_type = None self.version = None def check_required(self, settings, version): for field in ['data_id', 'owner_id', 'size', 'data_type', 'version']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.owner_id = stream.pid() self.size = stream.u32() self.data_type = stream.u16() self.version = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.pid(self.owner_id) stream.u32(self.size) stream.u16(self.data_type) stream.u32(self.version) class DataStoreSpecificMetaInfoV1(common.Structure): def __init__(self): super().__init__() self.data_id = None self.owner_id = None self.size = None self.data_type = None self.version = None def check_required(self, settings, version): for field in ['data_id', 'owner_id', 'size', 'data_type', 'version']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u32() self.owner_id = stream.pid() self.size = stream.u32() self.data_type = stream.u16() self.version = stream.u16() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.data_id) stream.pid(self.owner_id) stream.u32(self.size) stream.u16(self.data_type) stream.u16(self.version) class DataStoreTouchObjectParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.lock_id = None self.access_password = None def check_required(self, settings, version): for field in ['data_id', 'lock_id', 'access_password']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.lock_id = stream.u32() self.access_password = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.lock_id) stream.u64(self.access_password) class DataStoreProtocolSMM: METHOD_PREPARE_GET_OBJECT_V1 = 1 METHOD_PREPARE_POST_OBJECT_V1 = 2 METHOD_COMPLETE_POST_OBJECT_V1 = 3 METHOD_DELETE_OBJECT = 4 METHOD_DELETE_OBJECTS = 5 METHOD_CHANGE_META_V1 = 6 METHOD_CHANGE_METAS_V1 = 7 METHOD_GET_META = 8 METHOD_GET_METAS = 9 METHOD_PREPARE_UPDATE_OBJECT = 10 METHOD_COMPLETE_UPDATE_OBJECT = 11 METHOD_SEARCH_OBJECT = 12 METHOD_GET_NOTIFICATION_URL = 13 METHOD_GET_NEW_ARRIVED_NOTIFICATIONS_V1 = 14 METHOD_RATE_OBJECT = 15 METHOD_GET_RATING = 16 METHOD_GET_RATINGS = 17 METHOD_RESET_RATING = 18 METHOD_RESET_RATINGS = 19 METHOD_GET_SPECIFIC_META_V1 = 20 METHOD_POST_META_BINARY = 21 METHOD_TOUCH_OBJECT = 22 METHOD_GET_RATING_WITH_LOG = 23 METHOD_PREPARE_POST_OBJECT = 24 METHOD_PREPARE_GET_OBJECT = 25 METHOD_COMPLETE_POST_OBJECT = 26 METHOD_GET_NEW_ARRIVED_NOTIFICATIONS = 27 METHOD_GET_SPECIFIC_META = 28 METHOD_GET_PERSISTENCE_INFO = 29 METHOD_GET_PERSISTENCE_INFOS = 30 METHOD_PERPETUATE_OBJECT = 31 METHOD_UNPERPETUATE_OBJECT = 32 METHOD_PREPARE_GET_OBJECT_OR_META_BINARY = 33 METHOD_GET_PASSWORD_INFO = 34 METHOD_GET_PASSWORD_INFOS = 35 METHOD_GET_METAS_MULTIPLE_PARAM = 36 METHOD_COMPLETE_POST_OBJECTS = 37 METHOD_CHANGE_META = 38 METHOD_CHANGE_METAS = 39 METHOD_RATE_OBJECTS = 40 METHOD_POST_META_BINARY_WITH_DATA_ID = 41 METHOD_POST_META_BINARIES_WITH_DATA_ID = 42 METHOD_RATE_OBJECT_WITH_POSTING = 43 METHOD_RATE_OBJECTS_WITH_POSTING = 44 METHOD_GET_OBJECT_INFOS = 45 METHOD_SEARCH_OBJECT_LIGHT = 46 METHOD_GET_APPLICATION_CONFIG = 61 METHOD_GET_APPLICATION_CONFIG_STRING = 74 PROTOCOL_ID = 0x73 class DataStoreClientSMM(DataStoreProtocolSMM): def __init__(self, client): self.settings = client.settings self.client = client async def prepare_get_object_v1(self, param): logger.info("DataStoreClientSMM.prepare_get_object_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PREPARE_GET_OBJECT_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreReqGetInfoV1) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.prepare_get_object_v1 -> done") return info async def prepare_post_object_v1(self, param): logger.info("DataStoreClientSMM.prepare_post_object_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PREPARE_POST_OBJECT_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreReqPostInfoV1) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.prepare_post_object_v1 -> done") return info async def complete_post_object_v1(self, param): logger.info("DataStoreClientSMM.complete_post_object_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_COMPLETE_POST_OBJECT_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.complete_post_object_v1 -> done") async def delete_object(self, param): logger.info("DataStoreClientSMM.delete_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.delete_object -> done") async def delete_objects(self, param, transactional): logger.info("DataStoreClientSMM.delete_objects()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(param, stream.add) stream.bool(transactional) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_OBJECTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.delete_objects -> done") return results async def change_meta_v1(self, param): logger.info("DataStoreClientSMM.change_meta_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CHANGE_META_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.change_meta_v1 -> done") async def change_metas_v1(self, data_ids, param, transactional): logger.info("DataStoreClientSMM.change_metas_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) stream.list(param, stream.add) stream.bool(transactional) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CHANGE_METAS_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.change_metas_v1 -> done") return results async def get_meta(self, param): logger.info("DataStoreClientSMM.get_meta()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_META, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreMetaInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.get_meta -> done") return info async def get_metas(self, data_ids, param): logger.info("DataStoreClientSMM.get_metas()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_METAS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.info = stream.list(DataStoreMetaInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.get_metas -> done") return obj async def prepare_update_object(self, param): logger.info("DataStoreClientSMM.prepare_update_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PREPARE_UPDATE_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreReqUpdateInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.prepare_update_object -> done") return info async def complete_update_object(self, param): logger.info("DataStoreClientSMM.complete_update_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_COMPLETE_UPDATE_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.complete_update_object -> done") async def search_object(self, param): logger.info("DataStoreClientSMM.search_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.extract(DataStoreSearchResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.search_object -> done") return result async def get_notification_url(self, param): logger.info("DataStoreClientSMM.get_notification_url()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_NOTIFICATION_URL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreReqGetNotificationUrlInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.get_notification_url -> done") return info async def get_new_arrived_notifications_v1(self, param): logger.info("DataStoreClientSMM.get_new_arrived_notifications_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_NEW_ARRIVED_NOTIFICATIONS_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.list(DataStoreNotificationV1) obj.has_next = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.get_new_arrived_notifications_v1 -> done") return obj async def rate_object(self, target, param, fetch_ratings): logger.info("DataStoreClientSMM.rate_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) stream.add(param) stream.bool(fetch_ratings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RATE_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreRatingInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.rate_object -> done") return info async def get_rating(self, target, access_password): logger.info("DataStoreClientSMM.get_rating()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) stream.u64(access_password) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RATING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) rating = stream.extract(DataStoreRatingInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.get_rating -> done") return rating async def get_ratings(self, data_ids, access_password): logger.info("DataStoreClientSMM.get_ratings()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) stream.u64(access_password) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RATINGS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.ratings = stream.list(lambda: stream.list(DataStoreRatingInfoWithSlot)) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.get_ratings -> done") return obj async def reset_rating(self, target, update_password): logger.info("DataStoreClientSMM.reset_rating()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) stream.u64(update_password) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RESET_RATING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.reset_rating -> done") async def reset_ratings(self, data_ids, transactional): logger.info("DataStoreClientSMM.reset_ratings()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) stream.bool(transactional) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RESET_RATINGS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.reset_ratings -> done") return results async def get_specific_meta_v1(self, param): logger.info("DataStoreClientSMM.get_specific_meta_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SPECIFIC_META_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) infos = stream.list(DataStoreSpecificMetaInfoV1) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.get_specific_meta_v1 -> done") return infos async def post_meta_binary(self, param): logger.info("DataStoreClientSMM.post_meta_binary()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_POST_META_BINARY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) data_id = stream.u64() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.post_meta_binary -> done") return data_id async def touch_object(self, param): logger.info("DataStoreClientSMM.touch_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_TOUCH_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.touch_object -> done") async def get_rating_with_log(self, target, access_password): logger.info("DataStoreClientSMM.get_rating_with_log()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) stream.u64(access_password) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RATING_WITH_LOG, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.rating = stream.extract(DataStoreRatingInfo) obj.log = stream.extract(DataStoreRatingLog) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.get_rating_with_log -> done") return obj async def prepare_post_object(self, param): logger.info("DataStoreClientSMM.prepare_post_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PREPARE_POST_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreReqPostInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.prepare_post_object -> done") return info async def prepare_get_object(self, param): logger.info("DataStoreClientSMM.prepare_get_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PREPARE_GET_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreReqGetInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.prepare_get_object -> done") return info async def complete_post_object(self, param): logger.info("DataStoreClientSMM.complete_post_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_COMPLETE_POST_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.complete_post_object -> done") async def get_new_arrived_notifications(self, param): logger.info("DataStoreClientSMM.get_new_arrived_notifications()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_NEW_ARRIVED_NOTIFICATIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.list(DataStoreNotification) obj.has_next = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.get_new_arrived_notifications -> done") return obj async def get_specific_meta(self, param): logger.info("DataStoreClientSMM.get_specific_meta()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SPECIFIC_META, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) infos = stream.list(DataStoreSpecificMetaInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.get_specific_meta -> done") return infos async def get_persistence_info(self, owner_id, slot_id): logger.info("DataStoreClientSMM.get_persistence_info()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(owner_id) stream.u16(slot_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PERSISTENCE_INFO, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStorePersistenceInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.get_persistence_info -> done") return info async def get_persistence_infos(self, owner_id, slot_ids): logger.info("DataStoreClientSMM.get_persistence_infos()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(owner_id) stream.list(slot_ids, stream.u16) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PERSISTENCE_INFOS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.infos = stream.list(DataStorePersistenceInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.get_persistence_infos -> done") return obj async def perpetuate_object(self, persistence_slot_id, data_id, delete_last_object): logger.info("DataStoreClientSMM.perpetuate_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.u16(persistence_slot_id) stream.u64(data_id) stream.bool(delete_last_object) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PERPETUATE_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.perpetuate_object -> done") async def unperpetuate_object(self, persistence_slot_id, delete_last_object): logger.info("DataStoreClientSMM.unperpetuate_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.u16(persistence_slot_id) stream.bool(delete_last_object) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UNPERPETUATE_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.unperpetuate_object -> done") async def prepare_get_object_or_meta_binary(self, param): logger.info("DataStoreClientSMM.prepare_get_object_or_meta_binary()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PREPARE_GET_OBJECT_OR_META_BINARY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.get_info = stream.extract(DataStoreReqGetInfo) obj.additional_meta = stream.extract(DataStoreReqGetAdditionalMeta) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.prepare_get_object_or_meta_binary -> done") return obj async def get_password_info(self, data_id): logger.info("DataStoreClientSMM.get_password_info()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(data_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PASSWORD_INFO, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStorePasswordInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.get_password_info -> done") return info async def get_password_infos(self, data_ids): logger.info("DataStoreClientSMM.get_password_infos()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PASSWORD_INFOS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.infos = stream.list(DataStorePasswordInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.get_password_infos -> done") return obj async def get_metas_multiple_param(self, params): logger.info("DataStoreClientSMM.get_metas_multiple_param()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(params, stream.add) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_METAS_MULTIPLE_PARAM, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.infos = stream.list(DataStoreMetaInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.get_metas_multiple_param -> done") return obj async def complete_post_objects(self, data_ids): logger.info("DataStoreClientSMM.complete_post_objects()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_COMPLETE_POST_OBJECTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.complete_post_objects -> done") async def change_meta(self, param): logger.info("DataStoreClientSMM.change_meta()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CHANGE_META, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.change_meta -> done") async def change_metas(self, data_ids, param, transactional): logger.info("DataStoreClientSMM.change_metas()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) stream.list(param, stream.add) stream.bool(transactional) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CHANGE_METAS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.change_metas -> done") return results async def rate_objects(self, targets, param, transactional, fetch_ratings): logger.info("DataStoreClientSMM.rate_objects()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(targets, stream.add) stream.list(param, stream.add) stream.bool(transactional) stream.bool(fetch_ratings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RATE_OBJECTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.infos = stream.list(DataStoreRatingInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.rate_objects -> done") return obj async def post_meta_binary_with_data_id(self, data_id, param): logger.info("DataStoreClientSMM.post_meta_binary_with_data_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(data_id) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_POST_META_BINARY_WITH_DATA_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.post_meta_binary_with_data_id -> done") async def post_meta_binaries_with_data_id(self, data_ids, param, transactional): logger.info("DataStoreClientSMM.post_meta_binaries_with_data_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) stream.list(param, stream.add) stream.bool(transactional) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_POST_META_BINARIES_WITH_DATA_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.post_meta_binaries_with_data_id -> done") return results async def rate_object_with_posting(self, target, rate_param, post_param, fetch_ratings): logger.info("DataStoreClientSMM.rate_object_with_posting()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) stream.add(rate_param) stream.add(post_param) stream.bool(fetch_ratings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RATE_OBJECT_WITH_POSTING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreRatingInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.rate_object_with_posting -> done") return info async def rate_objects_with_posting(self, targets, rate_param, post_param, transactional, fetch_ratings): logger.info("DataStoreClientSMM.rate_objects_with_posting()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(targets, stream.add) stream.list(rate_param, stream.add) stream.list(post_param, stream.add) stream.bool(transactional) stream.bool(fetch_ratings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RATE_OBJECTS_WITH_POSTING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.ratings = stream.list(DataStoreRatingInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.rate_objects_with_posting -> done") return obj async def get_object_infos(self, data_ids): logger.info("DataStoreClientSMM.get_object_infos()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_OBJECT_INFOS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.infos = stream.list(DataStoreReqGetInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.get_object_infos -> done") return obj async def search_object_light(self, param): logger.info("DataStoreClientSMM.search_object_light()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_OBJECT_LIGHT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.extract(DataStoreSearchResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.search_object_light -> done") return result async def get_application_config(self, id): logger.info("DataStoreClientSMM.get_application_config()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_APPLICATION_CONFIG, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) config = stream.list(stream.u32) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.get_application_config -> done") return config async def get_application_config_string(self, id): logger.info("DataStoreClientSMM.get_application_config_string()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_APPLICATION_CONFIG_STRING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) config = stream.list(stream.string) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM.get_application_config_string -> done") return config class DataStoreServerSMM(DataStoreProtocolSMM): def __init__(self): self.methods = { self.METHOD_PREPARE_GET_OBJECT_V1: self.handle_prepare_get_object_v1, self.METHOD_PREPARE_POST_OBJECT_V1: self.handle_prepare_post_object_v1, self.METHOD_COMPLETE_POST_OBJECT_V1: self.handle_complete_post_object_v1, self.METHOD_DELETE_OBJECT: self.handle_delete_object, self.METHOD_DELETE_OBJECTS: self.handle_delete_objects, self.METHOD_CHANGE_META_V1: self.handle_change_meta_v1, self.METHOD_CHANGE_METAS_V1: self.handle_change_metas_v1, self.METHOD_GET_META: self.handle_get_meta, self.METHOD_GET_METAS: self.handle_get_metas, self.METHOD_PREPARE_UPDATE_OBJECT: self.handle_prepare_update_object, self.METHOD_COMPLETE_UPDATE_OBJECT: self.handle_complete_update_object, self.METHOD_SEARCH_OBJECT: self.handle_search_object, self.METHOD_GET_NOTIFICATION_URL: self.handle_get_notification_url, self.METHOD_GET_NEW_ARRIVED_NOTIFICATIONS_V1: self.handle_get_new_arrived_notifications_v1, self.METHOD_RATE_OBJECT: self.handle_rate_object, self.METHOD_GET_RATING: self.handle_get_rating, self.METHOD_GET_RATINGS: self.handle_get_ratings, self.METHOD_RESET_RATING: self.handle_reset_rating, self.METHOD_RESET_RATINGS: self.handle_reset_ratings, self.METHOD_GET_SPECIFIC_META_V1: self.handle_get_specific_meta_v1, self.METHOD_POST_META_BINARY: self.handle_post_meta_binary, self.METHOD_TOUCH_OBJECT: self.handle_touch_object, self.METHOD_GET_RATING_WITH_LOG: self.handle_get_rating_with_log, self.METHOD_PREPARE_POST_OBJECT: self.handle_prepare_post_object, self.METHOD_PREPARE_GET_OBJECT: self.handle_prepare_get_object, self.METHOD_COMPLETE_POST_OBJECT: self.handle_complete_post_object, self.METHOD_GET_NEW_ARRIVED_NOTIFICATIONS: self.handle_get_new_arrived_notifications, self.METHOD_GET_SPECIFIC_META: self.handle_get_specific_meta, self.METHOD_GET_PERSISTENCE_INFO: self.handle_get_persistence_info, self.METHOD_GET_PERSISTENCE_INFOS: self.handle_get_persistence_infos, self.METHOD_PERPETUATE_OBJECT: self.handle_perpetuate_object, self.METHOD_UNPERPETUATE_OBJECT: self.handle_unperpetuate_object, self.METHOD_PREPARE_GET_OBJECT_OR_META_BINARY: self.handle_prepare_get_object_or_meta_binary, self.METHOD_GET_PASSWORD_INFO: self.handle_get_password_info, self.METHOD_GET_PASSWORD_INFOS: self.handle_get_password_infos, self.METHOD_GET_METAS_MULTIPLE_PARAM: self.handle_get_metas_multiple_param, self.METHOD_COMPLETE_POST_OBJECTS: self.handle_complete_post_objects, self.METHOD_CHANGE_META: self.handle_change_meta, self.METHOD_CHANGE_METAS: self.handle_change_metas, self.METHOD_RATE_OBJECTS: self.handle_rate_objects, self.METHOD_POST_META_BINARY_WITH_DATA_ID: self.handle_post_meta_binary_with_data_id, self.METHOD_POST_META_BINARIES_WITH_DATA_ID: self.handle_post_meta_binaries_with_data_id, self.METHOD_RATE_OBJECT_WITH_POSTING: self.handle_rate_object_with_posting, self.METHOD_RATE_OBJECTS_WITH_POSTING: self.handle_rate_objects_with_posting, self.METHOD_GET_OBJECT_INFOS: self.handle_get_object_infos, self.METHOD_SEARCH_OBJECT_LIGHT: self.handle_search_object_light, self.METHOD_GET_APPLICATION_CONFIG: self.handle_get_application_config, self.METHOD_GET_APPLICATION_CONFIG_STRING: self.handle_get_application_config_string, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on DataStoreServerSMM: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_prepare_get_object_v1(self, client, input, output): logger.info("DataStoreServerSMM.prepare_get_object_v1()") #--- request --- param = input.extract(DataStorePrepareGetParamV1) response = await self.prepare_get_object_v1(client, param) #--- response --- if not isinstance(response, DataStoreReqGetInfoV1): raise RuntimeError("Expected DataStoreReqGetInfoV1, got %s" %response.__class__.__name__) output.add(response) async def handle_prepare_post_object_v1(self, client, input, output): logger.info("DataStoreServerSMM.prepare_post_object_v1()") #--- request --- param = input.extract(DataStorePreparePostParamV1) response = await self.prepare_post_object_v1(client, param) #--- response --- if not isinstance(response, DataStoreReqPostInfoV1): raise RuntimeError("Expected DataStoreReqPostInfoV1, got %s" %response.__class__.__name__) output.add(response) async def handle_complete_post_object_v1(self, client, input, output): logger.info("DataStoreServerSMM.complete_post_object_v1()") #--- request --- param = input.extract(DataStoreCompletePostParamV1) await self.complete_post_object_v1(client, param) async def handle_delete_object(self, client, input, output): logger.info("DataStoreServerSMM.delete_object()") #--- request --- param = input.extract(DataStoreDeleteParam) await self.delete_object(client, param) async def handle_delete_objects(self, client, input, output): logger.info("DataStoreServerSMM.delete_objects()") #--- request --- param = input.list(DataStoreDeleteParam) transactional = input.bool() response = await self.delete_objects(client, param, transactional) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.result) async def handle_change_meta_v1(self, client, input, output): logger.info("DataStoreServerSMM.change_meta_v1()") #--- request --- param = input.extract(DataStoreChangeMetaParamV1) await self.change_meta_v1(client, param) async def handle_change_metas_v1(self, client, input, output): logger.info("DataStoreServerSMM.change_metas_v1()") #--- request --- data_ids = input.list(input.u64) param = input.list(DataStoreChangeMetaParamV1) transactional = input.bool() response = await self.change_metas_v1(client, data_ids, param, transactional) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.result) async def handle_get_meta(self, client, input, output): logger.info("DataStoreServerSMM.get_meta()") #--- request --- param = input.extract(DataStoreGetMetaParam) response = await self.get_meta(client, param) #--- response --- if not isinstance(response, DataStoreMetaInfo): raise RuntimeError("Expected DataStoreMetaInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_metas(self, client, input, output): logger.info("DataStoreServerSMM.get_metas()") #--- request --- data_ids = input.list(input.u64) param = input.extract(DataStoreGetMetaParam) response = await self.get_metas(client, data_ids, param) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['info', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.info, output.add) output.list(response.results, output.result) async def handle_prepare_update_object(self, client, input, output): logger.info("DataStoreServerSMM.prepare_update_object()") #--- request --- param = input.extract(DataStorePrepareUpdateParam) response = await self.prepare_update_object(client, param) #--- response --- if not isinstance(response, DataStoreReqUpdateInfo): raise RuntimeError("Expected DataStoreReqUpdateInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_complete_update_object(self, client, input, output): logger.info("DataStoreServerSMM.complete_update_object()") #--- request --- param = input.extract(DataStoreCompleteUpdateParam) await self.complete_update_object(client, param) async def handle_search_object(self, client, input, output): logger.info("DataStoreServerSMM.search_object()") #--- request --- param = input.extract(DataStoreSearchParam) response = await self.search_object(client, param) #--- response --- if not isinstance(response, DataStoreSearchResult): raise RuntimeError("Expected DataStoreSearchResult, got %s" %response.__class__.__name__) output.add(response) async def handle_get_notification_url(self, client, input, output): logger.info("DataStoreServerSMM.get_notification_url()") #--- request --- param = input.extract(DataStoreGetNotificationUrlParam) response = await self.get_notification_url(client, param) #--- response --- if not isinstance(response, DataStoreReqGetNotificationUrlInfo): raise RuntimeError("Expected DataStoreReqGetNotificationUrlInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_new_arrived_notifications_v1(self, client, input, output): logger.info("DataStoreServerSMM.get_new_arrived_notifications_v1()") #--- request --- param = input.extract(DataStoreGetNewArrivedNotificationsParam) response = await self.get_new_arrived_notifications_v1(client, param) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'has_next']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.result, output.add) output.bool(response.has_next) async def handle_rate_object(self, client, input, output): logger.info("DataStoreServerSMM.rate_object()") #--- request --- target = input.extract(DataStoreRatingTarget) param = input.extract(DataStoreRateObjectParam) fetch_ratings = input.bool() response = await self.rate_object(client, target, param, fetch_ratings) #--- response --- if not isinstance(response, DataStoreRatingInfo): raise RuntimeError("Expected DataStoreRatingInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_rating(self, client, input, output): logger.info("DataStoreServerSMM.get_rating()") #--- request --- target = input.extract(DataStoreRatingTarget) access_password = input.u64() response = await self.get_rating(client, target, access_password) #--- response --- if not isinstance(response, DataStoreRatingInfo): raise RuntimeError("Expected DataStoreRatingInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_ratings(self, client, input, output): logger.info("DataStoreServerSMM.get_ratings()") #--- request --- data_ids = input.list(input.u64) access_password = input.u64() response = await self.get_ratings(client, data_ids, access_password) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['ratings', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.ratings, lambda x: output.list(x, output.add)) output.list(response.results, output.result) async def handle_reset_rating(self, client, input, output): logger.info("DataStoreServerSMM.reset_rating()") #--- request --- target = input.extract(DataStoreRatingTarget) update_password = input.u64() await self.reset_rating(client, target, update_password) async def handle_reset_ratings(self, client, input, output): logger.info("DataStoreServerSMM.reset_ratings()") #--- request --- data_ids = input.list(input.u64) transactional = input.bool() response = await self.reset_ratings(client, data_ids, transactional) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.result) async def handle_get_specific_meta_v1(self, client, input, output): logger.info("DataStoreServerSMM.get_specific_meta_v1()") #--- request --- param = input.extract(DataStoreGetSpecificMetaParamV1) response = await self.get_specific_meta_v1(client, param) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_post_meta_binary(self, client, input, output): logger.info("DataStoreServerSMM.post_meta_binary()") #--- request --- param = input.extract(DataStorePreparePostParam) response = await self.post_meta_binary(client, param) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u64(response) async def handle_touch_object(self, client, input, output): logger.info("DataStoreServerSMM.touch_object()") #--- request --- param = input.extract(DataStoreTouchObjectParam) await self.touch_object(client, param) async def handle_get_rating_with_log(self, client, input, output): logger.info("DataStoreServerSMM.get_rating_with_log()") #--- request --- target = input.extract(DataStoreRatingTarget) access_password = input.u64() response = await self.get_rating_with_log(client, target, access_password) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['rating', 'log']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.add(response.rating) output.add(response.log) async def handle_prepare_post_object(self, client, input, output): logger.info("DataStoreServerSMM.prepare_post_object()") #--- request --- param = input.extract(DataStorePreparePostParam) response = await self.prepare_post_object(client, param) #--- response --- if not isinstance(response, DataStoreReqPostInfo): raise RuntimeError("Expected DataStoreReqPostInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_prepare_get_object(self, client, input, output): logger.info("DataStoreServerSMM.prepare_get_object()") #--- request --- param = input.extract(DataStorePrepareGetParam) response = await self.prepare_get_object(client, param) #--- response --- if not isinstance(response, DataStoreReqGetInfo): raise RuntimeError("Expected DataStoreReqGetInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_complete_post_object(self, client, input, output): logger.info("DataStoreServerSMM.complete_post_object()") #--- request --- param = input.extract(DataStoreCompletePostParam) await self.complete_post_object(client, param) async def handle_get_new_arrived_notifications(self, client, input, output): logger.info("DataStoreServerSMM.get_new_arrived_notifications()") #--- request --- param = input.extract(DataStoreGetNewArrivedNotificationsParam) response = await self.get_new_arrived_notifications(client, param) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'has_next']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.result, output.add) output.bool(response.has_next) async def handle_get_specific_meta(self, client, input, output): logger.info("DataStoreServerSMM.get_specific_meta()") #--- request --- param = input.extract(DataStoreGetSpecificMetaParam) response = await self.get_specific_meta(client, param) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_persistence_info(self, client, input, output): logger.info("DataStoreServerSMM.get_persistence_info()") #--- request --- owner_id = input.pid() slot_id = input.u16() response = await self.get_persistence_info(client, owner_id, slot_id) #--- response --- if not isinstance(response, DataStorePersistenceInfo): raise RuntimeError("Expected DataStorePersistenceInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_persistence_infos(self, client, input, output): logger.info("DataStoreServerSMM.get_persistence_infos()") #--- request --- owner_id = input.pid() slot_ids = input.list(input.u16) response = await self.get_persistence_infos(client, owner_id, slot_ids) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['infos', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.infos, output.add) output.list(response.results, output.result) async def handle_perpetuate_object(self, client, input, output): logger.info("DataStoreServerSMM.perpetuate_object()") #--- request --- persistence_slot_id = input.u16() data_id = input.u64() delete_last_object = input.bool() await self.perpetuate_object(client, persistence_slot_id, data_id, delete_last_object) async def handle_unperpetuate_object(self, client, input, output): logger.info("DataStoreServerSMM.unperpetuate_object()") #--- request --- persistence_slot_id = input.u16() delete_last_object = input.bool() await self.unperpetuate_object(client, persistence_slot_id, delete_last_object) async def handle_prepare_get_object_or_meta_binary(self, client, input, output): logger.info("DataStoreServerSMM.prepare_get_object_or_meta_binary()") #--- request --- param = input.extract(DataStorePrepareGetParam) response = await self.prepare_get_object_or_meta_binary(client, param) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['get_info', 'additional_meta']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.add(response.get_info) output.add(response.additional_meta) async def handle_get_password_info(self, client, input, output): logger.info("DataStoreServerSMM.get_password_info()") #--- request --- data_id = input.u64() response = await self.get_password_info(client, data_id) #--- response --- if not isinstance(response, DataStorePasswordInfo): raise RuntimeError("Expected DataStorePasswordInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_password_infos(self, client, input, output): logger.info("DataStoreServerSMM.get_password_infos()") #--- request --- data_ids = input.list(input.u64) response = await self.get_password_infos(client, data_ids) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['infos', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.infos, output.add) output.list(response.results, output.result) async def handle_get_metas_multiple_param(self, client, input, output): logger.info("DataStoreServerSMM.get_metas_multiple_param()") #--- request --- params = input.list(DataStoreGetMetaParam) response = await self.get_metas_multiple_param(client, params) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['infos', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.infos, output.add) output.list(response.results, output.result) async def handle_complete_post_objects(self, client, input, output): logger.info("DataStoreServerSMM.complete_post_objects()") #--- request --- data_ids = input.list(input.u64) await self.complete_post_objects(client, data_ids) async def handle_change_meta(self, client, input, output): logger.info("DataStoreServerSMM.change_meta()") #--- request --- param = input.extract(DataStoreChangeMetaParam) await self.change_meta(client, param) async def handle_change_metas(self, client, input, output): logger.info("DataStoreServerSMM.change_metas()") #--- request --- data_ids = input.list(input.u64) param = input.list(DataStoreChangeMetaParam) transactional = input.bool() response = await self.change_metas(client, data_ids, param, transactional) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.result) async def handle_rate_objects(self, client, input, output): logger.info("DataStoreServerSMM.rate_objects()") #--- request --- targets = input.list(DataStoreRatingTarget) param = input.list(DataStoreRateObjectParam) transactional = input.bool() fetch_ratings = input.bool() response = await self.rate_objects(client, targets, param, transactional, fetch_ratings) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['infos', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.infos, output.add) output.list(response.results, output.result) async def handle_post_meta_binary_with_data_id(self, client, input, output): logger.info("DataStoreServerSMM.post_meta_binary_with_data_id()") #--- request --- data_id = input.u64() param = input.extract(DataStorePreparePostParam) await self.post_meta_binary_with_data_id(client, data_id, param) async def handle_post_meta_binaries_with_data_id(self, client, input, output): logger.info("DataStoreServerSMM.post_meta_binaries_with_data_id()") #--- request --- data_ids = input.list(input.u64) param = input.list(DataStorePreparePostParam) transactional = input.bool() response = await self.post_meta_binaries_with_data_id(client, data_ids, param, transactional) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.result) async def handle_rate_object_with_posting(self, client, input, output): logger.info("DataStoreServerSMM.rate_object_with_posting()") #--- request --- target = input.extract(DataStoreRatingTarget) rate_param = input.extract(DataStoreRateObjectParam) post_param = input.extract(DataStorePreparePostParam) fetch_ratings = input.bool() response = await self.rate_object_with_posting(client, target, rate_param, post_param, fetch_ratings) #--- response --- if not isinstance(response, DataStoreRatingInfo): raise RuntimeError("Expected DataStoreRatingInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_rate_objects_with_posting(self, client, input, output): logger.info("DataStoreServerSMM.rate_objects_with_posting()") #--- request --- targets = input.list(DataStoreRatingTarget) rate_param = input.list(DataStoreRateObjectParam) post_param = input.list(DataStorePreparePostParam) transactional = input.bool() fetch_ratings = input.bool() response = await self.rate_objects_with_posting(client, targets, rate_param, post_param, transactional, fetch_ratings) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['ratings', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.ratings, output.add) output.list(response.results, output.result) async def handle_get_object_infos(self, client, input, output): logger.info("DataStoreServerSMM.get_object_infos()") #--- request --- data_ids = input.list(input.u64) response = await self.get_object_infos(client, data_ids) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['infos', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.infos, output.add) output.list(response.results, output.result) async def handle_search_object_light(self, client, input, output): logger.info("DataStoreServerSMM.search_object_light()") #--- request --- param = input.extract(DataStoreSearchParam) response = await self.search_object_light(client, param) #--- response --- if not isinstance(response, DataStoreSearchResult): raise RuntimeError("Expected DataStoreSearchResult, got %s" %response.__class__.__name__) output.add(response) async def handle_get_application_config(self, client, input, output): logger.info("DataStoreServerSMM.get_application_config()") #--- request --- id = input.u32() response = await self.get_application_config(client, id) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.u32) async def handle_get_application_config_string(self, client, input, output): logger.info("DataStoreServerSMM.get_application_config_string()") #--- request --- id = input.u32() response = await self.get_application_config_string(client, id) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.string) async def prepare_get_object_v1(self, *args): logger.warning("DataStoreServerSMM.prepare_get_object_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def prepare_post_object_v1(self, *args): logger.warning("DataStoreServerSMM.prepare_post_object_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def complete_post_object_v1(self, *args): logger.warning("DataStoreServerSMM.complete_post_object_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def delete_object(self, *args): logger.warning("DataStoreServerSMM.delete_object not implemented") raise common.RMCError("Core::NotImplemented") async def delete_objects(self, *args): logger.warning("DataStoreServerSMM.delete_objects not implemented") raise common.RMCError("Core::NotImplemented") async def change_meta_v1(self, *args): logger.warning("DataStoreServerSMM.change_meta_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def change_metas_v1(self, *args): logger.warning("DataStoreServerSMM.change_metas_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def get_meta(self, *args): logger.warning("DataStoreServerSMM.get_meta not implemented") raise common.RMCError("Core::NotImplemented") async def get_metas(self, *args): logger.warning("DataStoreServerSMM.get_metas not implemented") raise common.RMCError("Core::NotImplemented") async def prepare_update_object(self, *args): logger.warning("DataStoreServerSMM.prepare_update_object not implemented") raise common.RMCError("Core::NotImplemented") async def complete_update_object(self, *args): logger.warning("DataStoreServerSMM.complete_update_object not implemented") raise common.RMCError("Core::NotImplemented") async def search_object(self, *args): logger.warning("DataStoreServerSMM.search_object not implemented") raise common.RMCError("Core::NotImplemented") async def get_notification_url(self, *args): logger.warning("DataStoreServerSMM.get_notification_url not implemented") raise common.RMCError("Core::NotImplemented") async def get_new_arrived_notifications_v1(self, *args): logger.warning("DataStoreServerSMM.get_new_arrived_notifications_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def rate_object(self, *args): logger.warning("DataStoreServerSMM.rate_object not implemented") raise common.RMCError("Core::NotImplemented") async def get_rating(self, *args): logger.warning("DataStoreServerSMM.get_rating not implemented") raise common.RMCError("Core::NotImplemented") async def get_ratings(self, *args): logger.warning("DataStoreServerSMM.get_ratings not implemented") raise common.RMCError("Core::NotImplemented") async def reset_rating(self, *args): logger.warning("DataStoreServerSMM.reset_rating not implemented") raise common.RMCError("Core::NotImplemented") async def reset_ratings(self, *args): logger.warning("DataStoreServerSMM.reset_ratings not implemented") raise common.RMCError("Core::NotImplemented") async def get_specific_meta_v1(self, *args): logger.warning("DataStoreServerSMM.get_specific_meta_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def post_meta_binary(self, *args): logger.warning("DataStoreServerSMM.post_meta_binary not implemented") raise common.RMCError("Core::NotImplemented") async def touch_object(self, *args): logger.warning("DataStoreServerSMM.touch_object not implemented") raise common.RMCError("Core::NotImplemented") async def get_rating_with_log(self, *args): logger.warning("DataStoreServerSMM.get_rating_with_log not implemented") raise common.RMCError("Core::NotImplemented") async def prepare_post_object(self, *args): logger.warning("DataStoreServerSMM.prepare_post_object not implemented") raise common.RMCError("Core::NotImplemented") async def prepare_get_object(self, *args): logger.warning("DataStoreServerSMM.prepare_get_object not implemented") raise common.RMCError("Core::NotImplemented") async def complete_post_object(self, *args): logger.warning("DataStoreServerSMM.complete_post_object not implemented") raise common.RMCError("Core::NotImplemented") async def get_new_arrived_notifications(self, *args): logger.warning("DataStoreServerSMM.get_new_arrived_notifications not implemented") raise common.RMCError("Core::NotImplemented") async def get_specific_meta(self, *args): logger.warning("DataStoreServerSMM.get_specific_meta not implemented") raise common.RMCError("Core::NotImplemented") async def get_persistence_info(self, *args): logger.warning("DataStoreServerSMM.get_persistence_info not implemented") raise common.RMCError("Core::NotImplemented") async def get_persistence_infos(self, *args): logger.warning("DataStoreServerSMM.get_persistence_infos not implemented") raise common.RMCError("Core::NotImplemented") async def perpetuate_object(self, *args): logger.warning("DataStoreServerSMM.perpetuate_object not implemented") raise common.RMCError("Core::NotImplemented") async def unperpetuate_object(self, *args): logger.warning("DataStoreServerSMM.unperpetuate_object not implemented") raise common.RMCError("Core::NotImplemented") async def prepare_get_object_or_meta_binary(self, *args): logger.warning("DataStoreServerSMM.prepare_get_object_or_meta_binary not implemented") raise common.RMCError("Core::NotImplemented") async def get_password_info(self, *args): logger.warning("DataStoreServerSMM.get_password_info not implemented") raise common.RMCError("Core::NotImplemented") async def get_password_infos(self, *args): logger.warning("DataStoreServerSMM.get_password_infos not implemented") raise common.RMCError("Core::NotImplemented") async def get_metas_multiple_param(self, *args): logger.warning("DataStoreServerSMM.get_metas_multiple_param not implemented") raise common.RMCError("Core::NotImplemented") async def complete_post_objects(self, *args): logger.warning("DataStoreServerSMM.complete_post_objects not implemented") raise common.RMCError("Core::NotImplemented") async def change_meta(self, *args): logger.warning("DataStoreServerSMM.change_meta not implemented") raise common.RMCError("Core::NotImplemented") async def change_metas(self, *args): logger.warning("DataStoreServerSMM.change_metas not implemented") raise common.RMCError("Core::NotImplemented") async def rate_objects(self, *args): logger.warning("DataStoreServerSMM.rate_objects not implemented") raise common.RMCError("Core::NotImplemented") async def post_meta_binary_with_data_id(self, *args): logger.warning("DataStoreServerSMM.post_meta_binary_with_data_id not implemented") raise common.RMCError("Core::NotImplemented") async def post_meta_binaries_with_data_id(self, *args): logger.warning("DataStoreServerSMM.post_meta_binaries_with_data_id not implemented") raise common.RMCError("Core::NotImplemented") async def rate_object_with_posting(self, *args): logger.warning("DataStoreServerSMM.rate_object_with_posting not implemented") raise common.RMCError("Core::NotImplemented") async def rate_objects_with_posting(self, *args): logger.warning("DataStoreServerSMM.rate_objects_with_posting not implemented") raise common.RMCError("Core::NotImplemented") async def get_object_infos(self, *args): logger.warning("DataStoreServerSMM.get_object_infos not implemented") raise common.RMCError("Core::NotImplemented") async def search_object_light(self, *args): logger.warning("DataStoreServerSMM.search_object_light not implemented") raise common.RMCError("Core::NotImplemented") async def get_application_config(self, *args): logger.warning("DataStoreServerSMM.get_application_config not implemented") raise common.RMCError("Core::NotImplemented") async def get_application_config_string(self, *args): logger.warning("DataStoreServerSMM.get_application_config_string not implemented") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/datastore_smm2.py ================================================ # This file was generated automatically by generate_protocols.py from nintendo.nex import notification, rmc, common, streams import logging logger = logging.getLogger(__name__) class ClearCondition: NORMAL = 0 COLLECT_COINS = 4116396131 KILL_SKIPSQUEAKS = 4042480826 class CourseDifficulty: EASY = 0 STANDARD = 1 EXPERT = 2 SUPER_EXPERT = 3 class CourseTag: NONE = 0 STANDARD = 1 PUZZLE_SOLVING = 2 SPEEDRUN = 3 AUTOSCROLL = 4 AUTO_MARIO = 5 SHORT_AND_SWEET = 6 MULTIPLAYER_VS = 7 THEMED = 8 MUSIC = 9 class CourseTheme: GROUND = 0 UNDERGROUND = 1 CASTLE = 2 AIRSHIP = 3 UNDERWATER = 4 GHOST_HOUSE = 5 SNOW = 6 DESERT = 7 SKY = 8 FOREST = 9 class GameStyle: SMB1 = 0 SMB3 = 1 SMW = 2 NSMBU = 3 SM3DW = 4 class MultiplayerStatsKeys: MULTIPLAYER_SCORE = 0 VERSUS_PLAYS = 2 VERSUS_WINS = 3 COOP_PLAYS = 10 COOP_WINS = 11 class PlayStatsKeys: PLAYS = 0 CLEARS = 1 ATTEMPTS = 2 DEATHS = 3 class CourseOption: PLAY_STATS = 1 RATINGS = 2 TIME_STATS = 4 COMMENT_STATS = 8 UNK9 = 16 UNK10 = 32 UNK8 = 64 ONE_SCREEN_THUMBNAIL = 128 ENTIRE_THUMBNAIL = 256 ALL = 511 class EventCourseOption: UNK3 = 1 GET_INFO = 2 BEST_TIME = 8 ONE_SCREEN_THUMBNAIL = 16 ENTIRE_THUMBNAIL = 32 UNK1 = 64 MEDAL_TIME = 256 GHOST = 512 ALL = 1023 class UserOption: PLAY_STATS = 1 MAKER_STATS = 2 UNK2 = 4 ENDLESS_MODE = 8 MULTIPLAYER_STATS = 16 BADGE_INFO = 32 UNK8 = 64 UNK9 = 128 UNK1 = 512 UNK7 = 1024 UNK11 = 4096 UNK13 = 8192 UNK15 = 32768 ALL = 65535 class DataStoreChangeMetaCompareParam(common.Structure): def __init__(self): super().__init__() self.comparison_flag = None self.name = None self.permission = DataStorePermission() self.delete_permission = DataStorePermission() self.period = None self.meta_binary = None self.tags = None self.referred_count = None self.data_type = None self.status = None def check_required(self, settings, version): for field in ['comparison_flag', 'name', 'period', 'meta_binary', 'tags', 'referred_count', 'data_type', 'status']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.comparison_flag = stream.u32() self.name = stream.string() self.permission = stream.extract(DataStorePermission) self.delete_permission = stream.extract(DataStorePermission) self.period = stream.u16() self.meta_binary = stream.qbuffer() self.tags = stream.list(stream.string) self.referred_count = stream.u32() self.data_type = stream.u16() self.status = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.comparison_flag) stream.string(self.name) stream.add(self.permission) stream.add(self.delete_permission) stream.u16(self.period) stream.qbuffer(self.meta_binary) stream.list(self.tags, stream.string) stream.u32(self.referred_count) stream.u16(self.data_type) stream.u8(self.status) class DataStoreChangeMetaParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.modifies_flag = None self.name = None self.permission = DataStorePermission() self.delete_permission = DataStorePermission() self.period = None self.meta_binary = None self.tags = None self.update_password = None self.referred_count = None self.data_type = None self.status = None self.compare_param = DataStoreChangeMetaCompareParam() self.persistence_target = DataStorePersistenceTarget() def check_required(self, settings, version): for field in ['data_id', 'modifies_flag', 'name', 'period', 'meta_binary', 'tags', 'update_password', 'referred_count', 'data_type', 'status']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.modifies_flag = stream.u32() self.name = stream.string() self.permission = stream.extract(DataStorePermission) self.delete_permission = stream.extract(DataStorePermission) self.period = stream.u16() self.meta_binary = stream.qbuffer() self.tags = stream.list(stream.string) self.update_password = stream.u64() self.referred_count = stream.u32() self.data_type = stream.u16() self.status = stream.u8() self.compare_param = stream.extract(DataStoreChangeMetaCompareParam) self.persistence_target = stream.extract(DataStorePersistenceTarget) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.modifies_flag) stream.string(self.name) stream.add(self.permission) stream.add(self.delete_permission) stream.u16(self.period) stream.qbuffer(self.meta_binary) stream.list(self.tags, stream.string) stream.u64(self.update_password) stream.u32(self.referred_count) stream.u16(self.data_type) stream.u8(self.status) stream.add(self.compare_param) stream.add(self.persistence_target) class DataStoreChangeMetaParamV1(common.Structure): def __init__(self): super().__init__() self.data_id = None self.modifies_flag = None self.name = None self.permission = DataStorePermission() self.delete_permission = DataStorePermission() self.period = None self.meta_binary = None self.tags = None self.update_password = None def check_required(self, settings, version): for field in ['data_id', 'modifies_flag', 'name', 'period', 'meta_binary', 'tags', 'update_password']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.modifies_flag = stream.u32() self.name = stream.string() self.permission = stream.extract(DataStorePermission) self.delete_permission = stream.extract(DataStorePermission) self.period = stream.u16() self.meta_binary = stream.qbuffer() self.tags = stream.list(stream.string) self.update_password = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.modifies_flag) stream.string(self.name) stream.add(self.permission) stream.add(self.delete_permission) stream.u16(self.period) stream.qbuffer(self.meta_binary) stream.list(self.tags, stream.string) stream.u64(self.update_password) class DataStoreCompletePostParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.success = None def check_required(self, settings, version): for field in ['data_id', 'success']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.success = stream.bool() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.bool(self.success) class DataStoreCompletePostParamV1(common.Structure): def __init__(self): super().__init__() self.data_id = None self.success = None def check_required(self, settings, version): for field in ['data_id', 'success']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u32() self.success = stream.bool() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.data_id) stream.bool(self.success) class DataStoreCompleteUpdateParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.version = None self.success = None def check_required(self, settings, version): for field in ['data_id', 'version', 'success']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.version = stream.u32() self.success = stream.bool() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.version) stream.bool(self.success) class DataStoreDeleteParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.update_password = None def check_required(self, settings, version): for field in ['data_id', 'update_password']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.update_password = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u64(self.update_password) class DataStoreGetMetaParam(common.Structure): def __init__(self): super().__init__() self.data_id = 0 self.persistence_target = DataStorePersistenceTarget() self.result_option = 0 self.access_password = 0 def check_required(self, settings, version): pass def load(self, stream, version): self.data_id = stream.u64() self.persistence_target = stream.extract(DataStorePersistenceTarget) self.result_option = stream.u8() self.access_password = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.add(self.persistence_target) stream.u8(self.result_option) stream.u64(self.access_password) class DataStoreGetNewArrivedNotificationsParam(common.Structure): def __init__(self): super().__init__() self.last_notification_id = None self.limit = None def check_required(self, settings, version): for field in ['last_notification_id', 'limit']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.last_notification_id = stream.u64() self.limit = stream.u16() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.last_notification_id) stream.u16(self.limit) class DataStoreGetNotificationUrlParam(common.Structure): def __init__(self): super().__init__() self.previous_url = None def check_required(self, settings, version): for field in ['previous_url']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.previous_url = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.previous_url) class DataStoreGetSpecificMetaParam(common.Structure): def __init__(self): super().__init__() self.data_ids = None def check_required(self, settings, version): for field in ['data_ids']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_ids = stream.list(stream.u64) def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.data_ids, stream.u64) class DataStoreGetSpecificMetaParamV1(common.Structure): def __init__(self): super().__init__() self.data_ids = None def check_required(self, settings, version): for field in ['data_ids']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_ids = stream.list(stream.u32) def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.data_ids, stream.u32) class DataStoreKeyValue(common.Structure): def __init__(self): super().__init__() self.key = None self.value = None def check_required(self, settings, version): for field in ['key', 'value']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.key = stream.string() self.value = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.key) stream.string(self.value) class DataStoreMetaInfo(common.Structure): def __init__(self): super().__init__() self.data_id = None self.owner_id = None self.size = None self.name = None self.data_type = None self.meta_binary = None self.permission = DataStorePermission() self.delete_permission = DataStorePermission() self.create_time = None self.update_time = None self.period = None self.status = None self.referred_count = None self.refer_data_id = None self.flag = None self.referred_time = None self.expire_time = None self.tags = None self.ratings = None def check_required(self, settings, version): for field in ['data_id', 'owner_id', 'size', 'name', 'data_type', 'meta_binary', 'create_time', 'update_time', 'period', 'status', 'referred_count', 'refer_data_id', 'flag', 'referred_time', 'expire_time', 'tags', 'ratings']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.owner_id = stream.pid() self.size = stream.u32() self.name = stream.string() self.data_type = stream.u16() self.meta_binary = stream.qbuffer() self.permission = stream.extract(DataStorePermission) self.delete_permission = stream.extract(DataStorePermission) self.create_time = stream.datetime() self.update_time = stream.datetime() self.period = stream.u16() self.status = stream.u8() self.referred_count = stream.u32() self.refer_data_id = stream.u32() self.flag = stream.u32() self.referred_time = stream.datetime() self.expire_time = stream.datetime() self.tags = stream.list(stream.string) self.ratings = stream.list(DataStoreRatingInfoWithSlot) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.pid(self.owner_id) stream.u32(self.size) stream.string(self.name) stream.u16(self.data_type) stream.qbuffer(self.meta_binary) stream.add(self.permission) stream.add(self.delete_permission) stream.datetime(self.create_time) stream.datetime(self.update_time) stream.u16(self.period) stream.u8(self.status) stream.u32(self.referred_count) stream.u32(self.refer_data_id) stream.u32(self.flag) stream.datetime(self.referred_time) stream.datetime(self.expire_time) stream.list(self.tags, stream.string) stream.list(self.ratings, stream.add) class DataStoreNotification(common.Structure): def __init__(self): super().__init__() self.notification_id = None self.data_id = None def check_required(self, settings, version): for field in ['notification_id', 'data_id']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.notification_id = stream.u64() self.data_id = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.notification_id) stream.u64(self.data_id) class DataStoreNotificationV1(common.Structure): def __init__(self): super().__init__() self.notification_id = None self.data_id = None def check_required(self, settings, version): for field in ['notification_id', 'data_id']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.notification_id = stream.u64() self.data_id = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.notification_id) stream.u32(self.data_id) class DataStorePasswordInfo(common.Structure): def __init__(self): super().__init__() self.data_id = None self.access_password = None self.update_password = None def check_required(self, settings, version): for field in ['data_id', 'access_password', 'update_password']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.access_password = stream.u64() self.update_password = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u64(self.access_password) stream.u64(self.update_password) class DataStorePermission(common.Structure): def __init__(self): super().__init__() self.permission = 3 self.recipients = [] def check_required(self, settings, version): pass def load(self, stream, version): self.permission = stream.u8() self.recipients = stream.list(stream.pid) def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.permission) stream.list(self.recipients, stream.pid) class DataStorePersistenceInfo(common.Structure): def __init__(self): super().__init__() self.owner_id = None self.slot_id = None self.data_id = None def check_required(self, settings, version): for field in ['owner_id', 'slot_id', 'data_id']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.owner_id = stream.pid() self.slot_id = stream.u16() self.data_id = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.owner_id) stream.u16(self.slot_id) stream.u64(self.data_id) class DataStorePersistenceInitParam(common.Structure): def __init__(self): super().__init__() self.persistence_id = 65535 self.delete_last_object = True def check_required(self, settings, version): pass def load(self, stream, version): self.persistence_id = stream.u16() self.delete_last_object = stream.bool() def save(self, stream, version): self.check_required(stream.settings, version) stream.u16(self.persistence_id) stream.bool(self.delete_last_object) class DataStorePersistenceTarget(common.Structure): def __init__(self): super().__init__() self.owner_id = 0 self.persistence_id = 65535 def check_required(self, settings, version): pass def load(self, stream, version): self.owner_id = stream.pid() self.persistence_id = stream.u16() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.owner_id) stream.u16(self.persistence_id) class DataStorePrepareGetParam(common.Structure): def __init__(self): super().__init__() self.data_id = 0 self.lock_id = 0 self.persistence_target = DataStorePersistenceTarget() self.access_password = 0 self.extra_data = [] def check_required(self, settings, version): if settings["nex.version"] >= 30500: pass def load(self, stream, version): self.data_id = stream.u64() self.lock_id = stream.u32() self.persistence_target = stream.extract(DataStorePersistenceTarget) self.access_password = stream.u64() if stream.settings["nex.version"] >= 30500: self.extra_data = stream.list(stream.string) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.lock_id) stream.add(self.persistence_target) stream.u64(self.access_password) if stream.settings["nex.version"] >= 30500: stream.list(self.extra_data, stream.string) class DataStorePrepareGetParamV1(common.Structure): def __init__(self): super().__init__() self.data_id = None self.lock_id = 0 def check_required(self, settings, version): for field in ['data_id']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u32() self.lock_id = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.data_id) stream.u32(self.lock_id) class DataStorePreparePostParam(common.Structure): def __init__(self): super().__init__() self.size = None self.name = None self.data_type = None self.meta_binary = None self.permission = DataStorePermission() self.delete_permission = DataStorePermission() self.flag = None self.period = None self.refer_data_id = 0 self.tags = [] self.rating_init_param = [] self.persistence_init_param = DataStorePersistenceInitParam() self.extra_data = None def check_required(self, settings, version): for field in ['size', 'name', 'data_type', 'meta_binary', 'flag', 'period']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) if settings["nex.version"] >= 30500: for field in ['extra_data']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.size = stream.u32() self.name = stream.string() self.data_type = stream.u16() self.meta_binary = stream.qbuffer() self.permission = stream.extract(DataStorePermission) self.delete_permission = stream.extract(DataStorePermission) self.flag = stream.u32() self.period = stream.u16() self.refer_data_id = stream.u32() self.tags = stream.list(stream.string) self.rating_init_param = stream.list(DataStoreRatingInitParamWithSlot) self.persistence_init_param = stream.extract(DataStorePersistenceInitParam) if stream.settings["nex.version"] >= 30500: self.extra_data = stream.list(stream.string) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.size) stream.string(self.name) stream.u16(self.data_type) stream.qbuffer(self.meta_binary) stream.add(self.permission) stream.add(self.delete_permission) stream.u32(self.flag) stream.u16(self.period) stream.u32(self.refer_data_id) stream.list(self.tags, stream.string) stream.list(self.rating_init_param, stream.add) stream.add(self.persistence_init_param) if stream.settings["nex.version"] >= 30500: stream.list(self.extra_data, stream.string) class DataStorePreparePostParamV1(common.Structure): def __init__(self): super().__init__() self.size = None self.name = None self.data_type = 0 self.meta_binary = b"" self.permission = DataStorePermission() self.delete_permission = DataStorePermission() self.flag = None self.period = None self.refer_data_id = 0 self.tags = None self.rating_init_param = None def check_required(self, settings, version): for field in ['size', 'name', 'flag', 'period', 'tags', 'rating_init_param']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.size = stream.u32() self.name = stream.string() self.data_type = stream.u16() self.meta_binary = stream.qbuffer() self.permission = stream.extract(DataStorePermission) self.delete_permission = stream.extract(DataStorePermission) self.flag = stream.u32() self.period = stream.u16() self.refer_data_id = stream.u32() self.tags = stream.list(stream.string) self.rating_init_param = stream.list(DataStoreRatingInitParamWithSlot) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.size) stream.string(self.name) stream.u16(self.data_type) stream.qbuffer(self.meta_binary) stream.add(self.permission) stream.add(self.delete_permission) stream.u32(self.flag) stream.u16(self.period) stream.u32(self.refer_data_id) stream.list(self.tags, stream.string) stream.list(self.rating_init_param, stream.add) class DataStorePrepareUpdateParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.size = None self.update_password = None self.extra_data = None def check_required(self, settings, version): for field in ['data_id', 'size', 'update_password', 'extra_data']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.size = stream.u32() self.update_password = stream.u64() self.extra_data = stream.list(stream.string) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.size) stream.u64(self.update_password) stream.list(self.extra_data, stream.string) class DataStoreRateObjectParam(common.Structure): def __init__(self): super().__init__() self.rating_value = None self.access_password = None def check_required(self, settings, version): for field in ['rating_value', 'access_password']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.rating_value = stream.s32() self.access_password = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.s32(self.rating_value) stream.u64(self.access_password) class DataStoreRatingInfo(common.Structure): def __init__(self): super().__init__() self.total_value = None self.count = None self.initial_value = None def check_required(self, settings, version): for field in ['total_value', 'count', 'initial_value']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.total_value = stream.s64() self.count = stream.u32() self.initial_value = stream.s64() def save(self, stream, version): self.check_required(stream.settings, version) stream.s64(self.total_value) stream.u32(self.count) stream.s64(self.initial_value) class DataStoreRatingInfoWithSlot(common.Structure): def __init__(self): super().__init__() self.slot = None self.info = DataStoreRatingInfo() def check_required(self, settings, version): for field in ['slot']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.slot = stream.u8() self.info = stream.extract(DataStoreRatingInfo) def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.slot) stream.add(self.info) class DataStoreRatingInitParam(common.Structure): def __init__(self): super().__init__() self.flag = None self.internal_flag = None self.lock_type = None self.initial_value = None self.range_min = None self.range_max = None self.period_hour = None self.period_duration = None def check_required(self, settings, version): for field in ['flag', 'internal_flag', 'lock_type', 'initial_value', 'range_min', 'range_max', 'period_hour', 'period_duration']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.flag = stream.u8() self.internal_flag = stream.u8() self.lock_type = stream.u8() self.initial_value = stream.s64() self.range_min = stream.s32() self.range_max = stream.s32() self.period_hour = stream.s8() self.period_duration = stream.s16() def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.flag) stream.u8(self.internal_flag) stream.u8(self.lock_type) stream.s64(self.initial_value) stream.s32(self.range_min) stream.s32(self.range_max) stream.s8(self.period_hour) stream.s16(self.period_duration) class DataStoreRatingInitParamWithSlot(common.Structure): def __init__(self): super().__init__() self.slot = None self.param = DataStoreRatingInitParam() def check_required(self, settings, version): for field in ['slot']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.slot = stream.s8() self.param = stream.extract(DataStoreRatingInitParam) def save(self, stream, version): self.check_required(stream.settings, version) stream.s8(self.slot) stream.add(self.param) class DataStoreRatingLog(common.Structure): def __init__(self): super().__init__() self.is_rated = None self.pid = None self.rating_value = None self.lock_expiration_time = None def check_required(self, settings, version): for field in ['is_rated', 'pid', 'rating_value', 'lock_expiration_time']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.is_rated = stream.bool() self.pid = stream.pid() self.rating_value = stream.s32() self.lock_expiration_time = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.bool(self.is_rated) stream.pid(self.pid) stream.s32(self.rating_value) stream.datetime(self.lock_expiration_time) class DataStoreRatingTarget(common.Structure): def __init__(self): super().__init__() self.data_id = None self.slot = None def check_required(self, settings, version): for field in ['data_id', 'slot']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.slot = stream.s8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.s8(self.slot) class DataStoreReqGetAdditionalMeta(common.Structure): def __init__(self): super().__init__() self.owner_id = None self.data_type = None self.version = None self.meta_binary = None def check_required(self, settings, version): for field in ['owner_id', 'data_type', 'version', 'meta_binary']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.owner_id = stream.pid() self.data_type = stream.u16() self.version = stream.u16() self.meta_binary = stream.qbuffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.owner_id) stream.u16(self.data_type) stream.u16(self.version) stream.qbuffer(self.meta_binary) class DataStoreReqGetInfo(common.Structure): def __init__(self): super().__init__() self.url = None self.headers = None self.size = None self.root_ca_cert = None self.data_id = None def check_required(self, settings, version): for field in ['url', 'headers', 'size', 'root_ca_cert']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) if settings["nex.version"] >= 30500: for field in ['data_id']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.url = stream.string() self.headers = stream.list(DataStoreKeyValue) self.size = stream.u32() self.root_ca_cert = stream.buffer() if stream.settings["nex.version"] >= 30500: self.data_id = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.url) stream.list(self.headers, stream.add) stream.u32(self.size) stream.buffer(self.root_ca_cert) if stream.settings["nex.version"] >= 30500: stream.u64(self.data_id) class DataStoreReqGetInfoV1(common.Structure): def __init__(self): super().__init__() self.url = None self.headers = None self.size = None self.root_ca_cert = None def check_required(self, settings, version): for field in ['url', 'headers', 'size', 'root_ca_cert']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.url = stream.string() self.headers = stream.list(DataStoreKeyValue) self.size = stream.u32() self.root_ca_cert = stream.buffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.url) stream.list(self.headers, stream.add) stream.u32(self.size) stream.buffer(self.root_ca_cert) class DataStoreReqGetNotificationUrlInfo(common.Structure): def __init__(self): super().__init__() self.url = None self.key = None self.query = None self.root_ca_cert = None def check_required(self, settings, version): for field in ['url', 'key', 'query', 'root_ca_cert']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.url = stream.string() self.key = stream.string() self.query = stream.string() self.root_ca_cert = stream.buffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.url) stream.string(self.key) stream.string(self.query) stream.buffer(self.root_ca_cert) class DataStoreReqPostInfo(common.Structure): def __init__(self): super().__init__() self.data_id = None self.url = None self.headers = None self.form = None self.root_ca_cert = None def check_required(self, settings, version): for field in ['data_id', 'url', 'headers', 'form', 'root_ca_cert']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.url = stream.string() self.headers = stream.list(DataStoreKeyValue) self.form = stream.list(DataStoreKeyValue) self.root_ca_cert = stream.buffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.string(self.url) stream.list(self.headers, stream.add) stream.list(self.form, stream.add) stream.buffer(self.root_ca_cert) class DataStoreReqPostInfoV1(common.Structure): def __init__(self): super().__init__() self.data_id = None self.url = None self.headers = None self.form = None self.root_ca_cert = None def check_required(self, settings, version): for field in ['data_id', 'url', 'headers', 'form', 'root_ca_cert']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u32() self.url = stream.string() self.headers = stream.list(DataStoreKeyValue) self.form = stream.list(DataStoreKeyValue) self.root_ca_cert = stream.buffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.data_id) stream.string(self.url) stream.list(self.headers, stream.add) stream.list(self.form, stream.add) stream.buffer(self.root_ca_cert) class DataStoreReqUpdateInfo(common.Structure): def __init__(self): super().__init__() self.version = None self.url = None self.headers = None self.form = None self.root_ca_cert = None def check_required(self, settings, version): for field in ['version', 'url', 'headers', 'form', 'root_ca_cert']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.version = stream.u32() self.url = stream.string() self.headers = stream.list(DataStoreKeyValue) self.form = stream.list(DataStoreKeyValue) self.root_ca_cert = stream.buffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.version) stream.string(self.url) stream.list(self.headers, stream.add) stream.list(self.form, stream.add) stream.buffer(self.root_ca_cert) class DataStoreSearchParam(common.Structure): def __init__(self): super().__init__() self.search_target = 1 self.owner_ids = [] self.owner_type = 0 self.destination_ids = [] self.data_type = 65535 self.created_after = common.DateTime(671076024059) self.created_before = common.DateTime(671076024059) self.updated_after = common.DateTime(671076024059) self.updated_before = common.DateTime(671076024059) self.refer_data_id = 0 self.tags = [] self.result_order_column = 0 self.result_order = 0 self.result_range = common.ResultRange() self.result_option = 0 self.minimal_rating_frequency = 0 self.use_cache = False self.total_count_enabled = True self.data_types = [] def check_required(self, settings, version): pass def load(self, stream, version): self.search_target = stream.u8() self.owner_ids = stream.list(stream.pid) self.owner_type = stream.u8() self.destination_ids = stream.list(stream.u64) self.data_type = stream.u16() self.created_after = stream.datetime() self.created_before = stream.datetime() self.updated_after = stream.datetime() self.updated_before = stream.datetime() self.refer_data_id = stream.u32() self.tags = stream.list(stream.string) self.result_order_column = stream.u8() self.result_order = stream.u8() self.result_range = stream.extract(common.ResultRange) self.result_option = stream.u8() self.minimal_rating_frequency = stream.u32() self.use_cache = stream.bool() self.total_count_enabled = stream.bool() self.data_types = stream.list(stream.u16) def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.search_target) stream.list(self.owner_ids, stream.pid) stream.u8(self.owner_type) stream.list(self.destination_ids, stream.u64) stream.u16(self.data_type) stream.datetime(self.created_after) stream.datetime(self.created_before) stream.datetime(self.updated_after) stream.datetime(self.updated_before) stream.u32(self.refer_data_id) stream.list(self.tags, stream.string) stream.u8(self.result_order_column) stream.u8(self.result_order) stream.add(self.result_range) stream.u8(self.result_option) stream.u32(self.minimal_rating_frequency) stream.bool(self.use_cache) stream.bool(self.total_count_enabled) stream.list(self.data_types, stream.u16) class DataStoreSearchResult(common.Structure): def __init__(self): super().__init__() self.total_count = None self.result = None self.total_count_type = None def check_required(self, settings, version): for field in ['total_count', 'result', 'total_count_type']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.total_count = stream.u32() self.result = stream.list(DataStoreMetaInfo) self.total_count_type = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.total_count) stream.list(self.result, stream.add) stream.u8(self.total_count_type) class DataStoreSpecificMetaInfo(common.Structure): def __init__(self): super().__init__() self.data_id = None self.owner_id = None self.size = None self.data_type = None self.version = None def check_required(self, settings, version): for field in ['data_id', 'owner_id', 'size', 'data_type', 'version']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.owner_id = stream.pid() self.size = stream.u32() self.data_type = stream.u16() self.version = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.pid(self.owner_id) stream.u32(self.size) stream.u16(self.data_type) stream.u32(self.version) class DataStoreSpecificMetaInfoV1(common.Structure): def __init__(self): super().__init__() self.data_id = None self.owner_id = None self.size = None self.data_type = None self.version = None def check_required(self, settings, version): for field in ['data_id', 'owner_id', 'size', 'data_type', 'version']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u32() self.owner_id = stream.pid() self.size = stream.u32() self.data_type = stream.u16() self.version = stream.u16() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.data_id) stream.pid(self.owner_id) stream.u32(self.size) stream.u16(self.data_type) stream.u16(self.version) class DataStoreTouchObjectParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.lock_id = None self.access_password = None def check_required(self, settings, version): for field in ['data_id', 'lock_id', 'access_password']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.lock_id = stream.u32() self.access_password = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.lock_id) stream.u64(self.access_password) class GetCoursesParam(common.Structure): def __init__(self): super().__init__() self.data_ids = None self.option = 0 def check_required(self, settings, version): for field in ['data_ids']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_ids = stream.list(stream.u64) self.option = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.data_ids, stream.u64) stream.u32(self.option) class GetCoursesEventParam(common.Structure): def __init__(self): super().__init__() def check_required(self, settings, version): pass def load(self, stream, version): pass def save(self, stream, version): self.check_required(stream.settings, version) class SearchCommentsInOrderParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.range = common.ResultRange() def check_required(self, settings, version): for field in ['data_id']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.range = stream.extract(common.ResultRange) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.add(self.range) class GetEventCourseGhostParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.time = None self.count = None def check_required(self, settings, version): for field in ['data_id', 'time', 'count']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.time = stream.u32() self.count = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.time) stream.u8(self.count) class GetEventCourseHistogramParam(common.Structure): def __init__(self): super().__init__() self.data_id = None def check_required(self, settings, version): for field in ['data_id']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) class GetUserOrCourseParam(common.Structure): def __init__(self): super().__init__() self.code = None self.user_option = 0 self.course_option = 0 def check_required(self, settings, version): for field in ['code']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.code = stream.string() self.user_option = stream.u32() self.course_option = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.code) stream.u32(self.user_option) stream.u32(self.course_option) class GetUsersParam(common.Structure): def __init__(self): super().__init__() self.pids = None self.option = 0 def check_required(self, settings, version): for field in ['pids']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pids = stream.list(stream.pid) self.option = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.pids, stream.pid) stream.u32(self.option) class RegisterUserParam(common.Structure): def __init__(self): super().__init__() self.name = None self.unk1 = UnknownStruct1() self.unk2 = None self.language = None self.country = None self.device_id = None def check_required(self, settings, version): for field in ['name', 'unk2', 'language', 'country', 'device_id']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.name = stream.string() self.unk1 = stream.extract(UnknownStruct1) self.unk2 = stream.qbuffer() self.language = stream.u8() self.country = stream.string() self.device_id = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.name) stream.add(self.unk1) stream.qbuffer(self.unk2) stream.u8(self.language) stream.string(self.country) stream.string(self.device_id) class SearchCoursesPostedByParam(common.Structure): def __init__(self): super().__init__() self.option = 0 self.range = common.ResultRange() self.pids = None def check_required(self, settings, version): for field in ['pids']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.option = stream.u32() self.range = stream.extract(common.ResultRange) self.pids = stream.list(stream.u64) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.option) stream.add(self.range) stream.list(self.pids, stream.u64) class SearchCoursesPositiveRatedByParam(common.Structure): def __init__(self): super().__init__() self.option = 0 self.count = None self.pid = None def check_required(self, settings, version): for field in ['count', 'pid']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.option = stream.u32() self.count = stream.u32() self.pid = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.option) stream.u32(self.count) stream.u64(self.pid) class SearchCoursesPlayedByParam(common.Structure): def __init__(self): super().__init__() self.option = 0 self.count = None self.pid = None def check_required(self, settings, version): for field in ['count', 'pid']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.option = stream.u32() self.count = stream.u32() self.pid = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.option) stream.u32(self.count) stream.u64(self.pid) class SearchCoursesEndlessModeParam(common.Structure): def __init__(self): super().__init__() self.option = 0 self.count = None self.difficulty = None def check_required(self, settings, version): for field in ['count', 'difficulty']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.option = stream.u32() self.count = stream.u32() self.difficulty = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.option) stream.u32(self.count) stream.u8(self.difficulty) class SearchCoursesFirstClearParam(common.Structure): def __init__(self): super().__init__() self.pid = None self.option = 0 self.range = common.ResultRange() def check_required(self, settings, version): for field in ['pid']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.u64() self.option = stream.u32() self.range = stream.extract(common.ResultRange) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.pid) stream.u32(self.option) stream.add(self.range) class SearchCoursesBestTimeParam(common.Structure): def __init__(self): super().__init__() self.pid = None self.option = 0 self.range = common.ResultRange() def check_required(self, settings, version): for field in ['pid']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.u64() self.option = stream.u32() self.range = stream.extract(common.ResultRange) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.pid) stream.u32(self.option) stream.add(self.range) class SearchCoursesEventParam(common.Structure): def __init__(self): super().__init__() self.option = 0 def check_required(self, settings, version): pass def load(self, stream, version): self.option = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.option) class SearchCoursesLatestParam(common.Structure): def __init__(self): super().__init__() self.option = 0 self.range = common.ResultRange() def check_required(self, settings, version): pass def load(self, stream, version): self.option = stream.u32() self.range = stream.extract(common.ResultRange) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.option) stream.add(self.range) class SearchUsersPlayedCourseParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.option = 0 self.count = None def check_required(self, settings, version): for field in ['data_id', 'count']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.option = stream.u32() self.count = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.option) stream.u32(self.count) class SearchUsersClearedCourseParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.option = 0 self.count = None def check_required(self, settings, version): for field in ['data_id', 'count']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.option = stream.u32() self.count = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.option) stream.u32(self.count) class SearchUsersPositiveRatedCourseParam(common.Structure): def __init__(self): super().__init__() self.data_id = None self.option = 0 self.count = None def check_required(self, settings, version): for field in ['data_id', 'count']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.option = stream.u32() self.count = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.option) stream.u32(self.count) class SearchCoursesPointRankingParam(common.Structure): def __init__(self): super().__init__() self.option = 0 self.range = common.ResultRange() self.difficulty = None self.reject_regions = [] def check_required(self, settings, version): for field in ['difficulty']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.option = stream.u32() self.range = stream.extract(common.ResultRange) self.difficulty = stream.u8() self.reject_regions = stream.list(stream.u8) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.option) stream.add(self.range) stream.u8(self.difficulty) stream.list(self.reject_regions, stream.u8) class SearchUsersUserPointParam(common.Structure): def __init__(self): super().__init__() self.option = 0 self.buffer = None self.range = common.ResultRange() def check_required(self, settings, version): for field in ['buffer']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.option = stream.u32() self.buffer = stream.buffer() self.range = stream.extract(common.ResultRange) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.option) stream.buffer(self.buffer) stream.add(self.range) class SyncUserProfileParam(common.Structure): def __init__(self): super().__init__() self.username = None self.unk1 = UnknownStruct1() self.unk2 = None self.unk3 = None self.country = None self.unk4 = None self.unk5 = None self.unk_guid = None self.unk6 = None def check_required(self, settings, version): for field in ['username', 'unk2', 'unk3', 'country', 'unk4', 'unk5', 'unk_guid', 'unk6']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.username = stream.string() self.unk1 = stream.extract(UnknownStruct1) self.unk2 = stream.qbuffer() self.unk3 = stream.u8() self.country = stream.string() self.unk4 = stream.bool() self.unk5 = stream.bool() self.unk_guid = stream.string() self.unk6 = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.username) stream.add(self.unk1) stream.qbuffer(self.unk2) stream.u8(self.unk3) stream.string(self.country) stream.bool(self.unk4) stream.bool(self.unk5) stream.string(self.unk_guid) stream.u32(self.unk6) class GetWorldMapParam(common.Structure): def __init__(self): super().__init__() self.ids = None self.option = 0 def check_required(self, settings, version): for field in ['ids']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.ids = stream.list(stream.string) self.option = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.ids, stream.string) stream.u32(self.option) class SearchWorldMapPickUpParam(common.Structure): def __init__(self): super().__init__() self.count = None def check_required(self, settings, version): for field in ['count']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.count = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.count) class SearchWorldMapPlayedByParam(common.Structure): def __init__(self): super().__init__() self.unk1 = None self.unk2 = None def check_required(self, settings, version): for field in ['unk1', 'unk2']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.unk1 = stream.u32() self.unk2 = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.unk1) stream.u32(self.unk2) class BadgeInfo(common.Structure): def __init__(self): super().__init__() self.unk1 = None self.unk2 = None def check_required(self, settings, version): for field in ['unk1', 'unk2']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.unk1 = stream.u16() self.unk2 = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u16(self.unk1) stream.u8(self.unk2) class CommentInfo(common.Structure): def __init__(self): super().__init__() self.unk1 = None self.unk2 = None self.unk3 = None self.unk4 = None self.unk5 = None self.unk6 = None self.unk7 = None self.unk8 = None self.unk9 = None self.unk10 = None self.unk11 = None self.unk12 = None self.unk13 = None self.unk14 = None self.unk15 = None self.picture = CommentPictureReqGetInfoWithoutHeaders() self.unk16 = None self.unk17 = None def check_required(self, settings, version): for field in ['unk1', 'unk2', 'unk3', 'unk4', 'unk5', 'unk6', 'unk7', 'unk8', 'unk9', 'unk10', 'unk11', 'unk12', 'unk13', 'unk14', 'unk15', 'unk16', 'unk17']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.unk1 = stream.u64() self.unk2 = stream.string() self.unk3 = stream.u8() self.unk4 = stream.u8() self.unk5 = stream.u64() self.unk6 = stream.u16() self.unk7 = stream.u16() self.unk8 = stream.u8() self.unk9 = stream.u8() self.unk10 = stream.u16() self.unk11 = stream.bool() self.unk12 = stream.bool() self.unk13 = stream.datetime() self.unk14 = stream.qbuffer() self.unk15 = stream.string() self.picture = stream.extract(CommentPictureReqGetInfoWithoutHeaders) self.unk16 = stream.u16() self.unk17 = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.unk1) stream.string(self.unk2) stream.u8(self.unk3) stream.u8(self.unk4) stream.u64(self.unk5) stream.u16(self.unk6) stream.u16(self.unk7) stream.u8(self.unk8) stream.u8(self.unk9) stream.u16(self.unk10) stream.bool(self.unk11) stream.bool(self.unk12) stream.datetime(self.unk13) stream.qbuffer(self.unk14) stream.string(self.unk15) stream.add(self.picture) stream.u16(self.unk16) stream.u8(self.unk17) class DeathPositionInfo(common.Structure): def __init__(self): super().__init__() self.data_id = None self.x = None self.y = None self.is_subworld = None def check_required(self, settings, version): for field in ['data_id', 'x', 'y', 'is_subworld']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.x = stream.u16() self.y = stream.u16() self.is_subworld = stream.bool() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u16(self.x) stream.u16(self.y) stream.bool(self.is_subworld) class CommentPictureReqGetInfoWithoutHeaders(common.Structure): def __init__(self): super().__init__() self.url = None self.data_type = None self.unk1 = None self.unk2 = None self.filename = None def check_required(self, settings, version): for field in ['url', 'data_type', 'unk1', 'unk2', 'filename']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.url = stream.string() self.data_type = stream.u8() self.unk1 = stream.u32() self.unk2 = stream.buffer() self.filename = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.url) stream.u8(self.data_type) stream.u32(self.unk1) stream.buffer(self.unk2) stream.string(self.filename) class CourseInfo(common.Structure): def __init__(self): super().__init__() self.data_id = None self.code = None self.owner_id = None self.name = None self.description = None self.game_style = None self.course_theme = None self.upload_time = None self.difficulty = None self.tag1 = None self.tag2 = None self.unk1 = None self.clear_condition = None self.clear_condition_magnitude = None self.unk2 = None self.unk3 = None self.play_stats = None self.ratings = None self.unk4 = None self.time_stats = CourseTimeStats() self.comment_stats = None self.unk9 = None self.unk10 = None self.unk11 = None self.unk12 = None self.one_screen_thumbnail = RelationObjectReqGetInfo() self.entire_thumbnail = RelationObjectReqGetInfo() def check_required(self, settings, version): for field in ['data_id', 'code', 'owner_id', 'name', 'description', 'game_style', 'course_theme', 'upload_time', 'difficulty', 'tag1', 'tag2', 'unk1', 'clear_condition', 'clear_condition_magnitude', 'unk2', 'unk3', 'play_stats', 'ratings', 'unk4', 'comment_stats', 'unk9', 'unk10', 'unk11', 'unk12']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.code = stream.string() self.owner_id = stream.pid() self.name = stream.string() self.description = stream.string() self.game_style = stream.u8() self.course_theme = stream.u8() self.upload_time = stream.datetime() self.difficulty = stream.u8() self.tag1 = stream.u8() self.tag2 = stream.u8() self.unk1 = stream.u8() self.clear_condition = stream.u32() self.clear_condition_magnitude = stream.u16() self.unk2 = stream.u16() self.unk3 = stream.qbuffer() self.play_stats = stream.map(stream.u8, stream.u32) self.ratings = stream.map(stream.u8, stream.u32) self.unk4 = stream.map(stream.u8, stream.u32) self.time_stats = stream.extract(CourseTimeStats) self.comment_stats = stream.map(stream.u8, stream.u32) self.unk9 = stream.u8() self.unk10 = stream.u8() self.unk11 = stream.u8() self.unk12 = stream.u8() self.one_screen_thumbnail = stream.extract(RelationObjectReqGetInfo) self.entire_thumbnail = stream.extract(RelationObjectReqGetInfo) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.string(self.code) stream.pid(self.owner_id) stream.string(self.name) stream.string(self.description) stream.u8(self.game_style) stream.u8(self.course_theme) stream.datetime(self.upload_time) stream.u8(self.difficulty) stream.u8(self.tag1) stream.u8(self.tag2) stream.u8(self.unk1) stream.u32(self.clear_condition) stream.u16(self.clear_condition_magnitude) stream.u16(self.unk2) stream.qbuffer(self.unk3) stream.map(self.play_stats, stream.u8, stream.u32) stream.map(self.ratings, stream.u8, stream.u32) stream.map(self.unk4, stream.u8, stream.u32) stream.add(self.time_stats) stream.map(self.comment_stats, stream.u8, stream.u32) stream.u8(self.unk9) stream.u8(self.unk10) stream.u8(self.unk11) stream.u8(self.unk12) stream.add(self.one_screen_thumbnail) stream.add(self.entire_thumbnail) class WorldMapInfo(common.Structure): def __init__(self): super().__init__() self.id = None self.owner_id = None self.unk1 = None self.thumbnail = RelationObjectReqGetInfo() self.worlds = None self.levels = None self.unk2 = None self.unk3 = None self.data_ids = None self.unk4 = None self.unk5 = None self.unk6 = None self.unk7 = None def check_required(self, settings, version): for field in ['id', 'owner_id', 'unk1', 'worlds', 'levels', 'unk2', 'unk3', 'data_ids', 'unk4', 'unk5', 'unk6', 'unk7']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.id = stream.string() self.owner_id = stream.pid() self.unk1 = stream.qbuffer() self.thumbnail = stream.extract(RelationObjectReqGetInfo) self.worlds = stream.u8() self.levels = stream.u8() self.unk2 = stream.u8() self.unk3 = stream.datetime() self.data_ids = stream.list(stream.u64) self.unk4 = stream.map(stream.u8, stream.u32) self.unk5 = stream.u32() self.unk6 = stream.u8() self.unk7 = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.id) stream.pid(self.owner_id) stream.qbuffer(self.unk1) stream.add(self.thumbnail) stream.u8(self.worlds) stream.u8(self.levels) stream.u8(self.unk2) stream.datetime(self.unk3) stream.list(self.data_ids, stream.u64) stream.map(self.unk4, stream.u8, stream.u32) stream.u32(self.unk5) stream.u8(self.unk6) stream.u8(self.unk7) class CourseTimeStats(common.Structure): def __init__(self): super().__init__() self.first_completion = None self.world_record_holder = None self.world_record = None self.upload_time = None def check_required(self, settings, version): for field in ['first_completion', 'world_record_holder', 'world_record', 'upload_time']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.first_completion = stream.pid() self.world_record_holder = stream.pid() self.world_record = stream.u32() self.upload_time = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.first_completion) stream.pid(self.world_record_holder) stream.u32(self.world_record) stream.u32(self.upload_time) class EventCourseGhostInfo(common.Structure): def __init__(self): super().__init__() self.replay_file = RelationObjectReqGetInfo() self.time = None self.pid = None def check_required(self, settings, version): for field in ['time', 'pid']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.replay_file = stream.extract(RelationObjectReqGetInfo) self.time = stream.u32() self.pid = stream.pid() def save(self, stream, version): self.check_required(stream.settings, version) stream.add(self.replay_file) stream.u32(self.time) stream.pid(self.pid) class EventCourseHistogram(common.Structure): def __init__(self): super().__init__() self.data_id = None self.unk1 = None self.unk2 = None self.unk3 = None self.values = None self.medals = None self.unk4 = None def check_required(self, settings, version): for field in ['data_id', 'unk1', 'unk2', 'unk3', 'values', 'medals', 'unk4']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.unk1 = stream.u32() self.unk2 = stream.u32() self.unk3 = stream.u32() self.values = stream.list(stream.u32) self.medals = stream.map(stream.u8, stream.u32) self.unk4 = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.u32(self.unk1) stream.u32(self.unk2) stream.u32(self.unk3) stream.list(self.values, stream.u32) stream.map(self.medals, stream.u8, stream.u32) stream.u32(self.unk4) class EventCourseInfo(common.Structure): def __init__(self): super().__init__() self.data_id = None self.name = None self.description = None self.game_style = None self.course_theme = None self.unk1 = None self.unk2 = None self.upload_time = None self.get_info = DataStoreReqGetInfo() self.unk3 = None self.unk4 = UnknownStruct6() self.unk5 = None self.one_screen_thumbnail = EventCourseThumbnail() self.entire_thumbnail = EventCourseThumbnail() self.end_time = None self.unk6 = None self.unk7 = None self.unk8 = None self.unk9 = None self.best_time = None self.unk10 = None self.medal_time = None self.personal_ghost = RelationObjectReqGetInfo() def max_version(self, settings): version = 0 version = 1 return version def check_required(self, settings, version): for field in ['data_id', 'name', 'description', 'game_style', 'course_theme', 'unk1', 'unk2', 'upload_time', 'unk3', 'unk5']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) if version >= 1: for field in ['end_time', 'unk6', 'unk7', 'unk8', 'unk9', 'best_time', 'unk10', 'medal_time']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data_id = stream.u64() self.name = stream.string() self.description = stream.string() self.game_style = stream.u8() self.course_theme = stream.u8() self.unk1 = stream.bool() self.unk2 = stream.bool() self.upload_time = stream.datetime() self.get_info = stream.extract(DataStoreReqGetInfo) self.unk3 = stream.map(stream.u8, stream.u32) self.unk4 = stream.extract(UnknownStruct6) self.unk5 = stream.u8() self.one_screen_thumbnail = stream.extract(EventCourseThumbnail) self.entire_thumbnail = stream.extract(EventCourseThumbnail) if version >= 1: self.end_time = stream.datetime() self.unk6 = stream.u8() self.unk7 = stream.u32() self.unk8 = stream.u16() self.unk9 = stream.u16() self.best_time = stream.u32() self.unk10 = stream.u32() self.medal_time = stream.u32() self.personal_ghost = stream.extract(RelationObjectReqGetInfo) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.data_id) stream.string(self.name) stream.string(self.description) stream.u8(self.game_style) stream.u8(self.course_theme) stream.bool(self.unk1) stream.bool(self.unk2) stream.datetime(self.upload_time) stream.add(self.get_info) stream.map(self.unk3, stream.u8, stream.u32) stream.add(self.unk4) stream.u8(self.unk5) stream.add(self.one_screen_thumbnail) stream.add(self.entire_thumbnail) if version >= 1: stream.datetime(self.end_time) stream.u8(self.unk6) stream.u32(self.unk7) stream.u16(self.unk8) stream.u16(self.unk9) stream.u32(self.best_time) stream.u32(self.unk10) stream.u32(self.medal_time) stream.add(self.personal_ghost) class EventCourseStatusInfo(common.Structure): def __init__(self): super().__init__() self.unk1 = None self.unk2 = None self.unk3 = None def check_required(self, settings, version): for field in ['unk1', 'unk2', 'unk3']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.unk1 = stream.u64() self.unk2 = stream.bool() self.unk3 = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.unk1) stream.bool(self.unk2) stream.datetime(self.unk3) class EventCourseThumbnail(common.Structure): def __init__(self): super().__init__() self.url = None self.headers = None self.filesize = None self.root_ca_cert = None self.filename = None def check_required(self, settings, version): for field in ['url', 'headers', 'filesize', 'root_ca_cert', 'filename']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.url = stream.string() self.headers = stream.list(DataStoreKeyValue) self.filesize = stream.u32() self.root_ca_cert = stream.buffer() self.filename = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.url) stream.list(self.headers, stream.add) stream.u32(self.filesize) stream.buffer(self.root_ca_cert) stream.string(self.filename) class RelationObjectReqGetInfo(common.Structure): def __init__(self): super().__init__() self.url = None self.data_type = None self.size = None self.unk = None self.filename = None def check_required(self, settings, version): for field in ['url', 'data_type', 'size', 'unk', 'filename']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.url = stream.string() self.data_type = stream.u8() self.size = stream.u32() self.unk = stream.buffer() self.filename = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.url) stream.u8(self.data_type) stream.u32(self.size) stream.buffer(self.unk) stream.string(self.filename) class ReqGetInfoHeadersInfo(common.Structure): def __init__(self): super().__init__() self.headers = None self.expiration = None def check_required(self, settings, version): for field in ['headers', 'expiration']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.headers = stream.list(DataStoreKeyValue) self.expiration = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.headers, stream.add) stream.u32(self.expiration) class SyncUserProfileResult(common.Structure): def __init__(self): super().__init__() self.pid = None self.username = None self.unk1 = UnknownStruct1() self.unk2 = None self.unk3 = None self.country = None self.unk4 = None self.unk5 = None self.unk6 = None def check_required(self, settings, version): for field in ['pid', 'username', 'unk2', 'unk3', 'country', 'unk4', 'unk5', 'unk6']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.u64() self.username = stream.string() self.unk1 = stream.extract(UnknownStruct1) self.unk2 = stream.qbuffer() self.unk3 = stream.u8() self.country = stream.string() self.unk4 = stream.u8() self.unk5 = stream.bool() self.unk6 = stream.bool() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.pid) stream.string(self.username) stream.add(self.unk1) stream.qbuffer(self.unk2) stream.u8(self.unk3) stream.string(self.country) stream.u8(self.unk4) stream.bool(self.unk5) stream.bool(self.unk6) class UserInfo(common.Structure): def __init__(self): super().__init__() self.pid = None self.code = None self.name = None self.unk1 = UnknownStruct1() self.unk2 = None self.country = None self.region = None self.last_active = None self.unk3 = None self.unk4 = None self.unk5 = None self.play_stats = None self.maker_stats = None self.endless_challenge_high_scores = None self.multiplayer_stats = None self.unk7 = None self.badges = None self.unk8 = None self.unk9 = None self.unk10 = None self.unk11 = None self.unk12 = None self.unk13 = UnknownStruct3() self.unk14 = None self.unk15 = None self.unk16 = None def max_version(self, settings): version = 0 version = 1 version = 2 version = 3 return version def check_required(self, settings, version): for field in ['pid', 'code', 'name', 'unk2', 'country', 'region', 'last_active', 'unk3', 'unk4', 'unk5', 'play_stats', 'maker_stats', 'endless_challenge_high_scores', 'multiplayer_stats', 'unk7', 'badges', 'unk8', 'unk9']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) if version >= 1: for field in ['unk10', 'unk11', 'unk12']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) if version >= 2: pass if version >= 3: for field in ['unk14', 'unk15', 'unk16']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.code = stream.string() self.name = stream.string() self.unk1 = stream.extract(UnknownStruct1) self.unk2 = stream.qbuffer() self.country = stream.string() self.region = stream.u8() self.last_active = stream.datetime() self.unk3 = stream.bool() self.unk4 = stream.bool() self.unk5 = stream.bool() self.play_stats = stream.map(stream.u8, stream.u32) self.maker_stats = stream.map(stream.u8, stream.u32) self.endless_challenge_high_scores = stream.map(stream.u8, stream.u32) self.multiplayer_stats = stream.map(stream.u8, stream.u32) self.unk7 = stream.map(stream.u8, stream.u32) self.badges = stream.list(BadgeInfo) self.unk8 = stream.map(stream.u8, stream.u32) self.unk9 = stream.map(stream.u8, stream.u32) if version >= 1: self.unk10 = stream.bool() self.unk11 = stream.datetime() self.unk12 = stream.bool() if version >= 2: self.unk13 = stream.extract(UnknownStruct3) if version >= 3: self.unk14 = stream.string() self.unk15 = stream.map(stream.u8, stream.u32) self.unk16 = stream.bool() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.string(self.code) stream.string(self.name) stream.add(self.unk1) stream.qbuffer(self.unk2) stream.string(self.country) stream.u8(self.region) stream.datetime(self.last_active) stream.bool(self.unk3) stream.bool(self.unk4) stream.bool(self.unk5) stream.map(self.play_stats, stream.u8, stream.u32) stream.map(self.maker_stats, stream.u8, stream.u32) stream.map(self.endless_challenge_high_scores, stream.u8, stream.u32) stream.map(self.multiplayer_stats, stream.u8, stream.u32) stream.map(self.unk7, stream.u8, stream.u32) stream.list(self.badges, stream.add) stream.map(self.unk8, stream.u8, stream.u32) stream.map(self.unk9, stream.u8, stream.u32) if version >= 1: stream.bool(self.unk10) stream.datetime(self.unk11) stream.bool(self.unk12) if version >= 2: stream.add(self.unk13) if version >= 3: stream.string(self.unk14) stream.map(self.unk15, stream.u8, stream.u32) stream.bool(self.unk16) class UnknownStruct1(common.Structure): def __init__(self): super().__init__() self.unk1 = None self.unk2 = None self.unk3 = None self.unk4 = None def check_required(self, settings, version): for field in ['unk1', 'unk2', 'unk3', 'unk4']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.unk1 = stream.u16() self.unk2 = stream.u16() self.unk3 = stream.u16() self.unk4 = stream.u16() def save(self, stream, version): self.check_required(stream.settings, version) stream.u16(self.unk1) stream.u16(self.unk2) stream.u16(self.unk3) stream.u16(self.unk4) class UnknownStruct3(common.Structure): def __init__(self): super().__init__() self.unk1 = None self.unk2 = None def check_required(self, settings, version): for field in ['unk1', 'unk2']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.unk1 = stream.bool() self.unk2 = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.bool(self.unk1) stream.datetime(self.unk2) class UnknownStruct6(common.Structure): def __init__(self): super().__init__() self.unk1 = None self.unk2 = None def check_required(self, settings, version): for field in ['unk1', 'unk2']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.unk1 = stream.u64() self.unk2 = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.unk1) stream.u32(self.unk2) class DataStoreProtocolSMM2: METHOD_PREPARE_GET_OBJECT_V1 = 1 METHOD_PREPARE_POST_OBJECT_V1 = 2 METHOD_COMPLETE_POST_OBJECT_V1 = 3 METHOD_DELETE_OBJECT = 4 METHOD_DELETE_OBJECTS = 5 METHOD_CHANGE_META_V1 = 6 METHOD_CHANGE_METAS_V1 = 7 METHOD_GET_META = 8 METHOD_GET_METAS = 9 METHOD_PREPARE_UPDATE_OBJECT = 10 METHOD_COMPLETE_UPDATE_OBJECT = 11 METHOD_SEARCH_OBJECT = 12 METHOD_GET_NOTIFICATION_URL = 13 METHOD_GET_NEW_ARRIVED_NOTIFICATIONS_V1 = 14 METHOD_RATE_OBJECT = 15 METHOD_GET_RATING = 16 METHOD_GET_RATINGS = 17 METHOD_RESET_RATING = 18 METHOD_RESET_RATINGS = 19 METHOD_GET_SPECIFIC_META_V1 = 20 METHOD_POST_META_BINARY = 21 METHOD_TOUCH_OBJECT = 22 METHOD_GET_RATING_WITH_LOG = 23 METHOD_PREPARE_POST_OBJECT = 24 METHOD_PREPARE_GET_OBJECT = 25 METHOD_COMPLETE_POST_OBJECT = 26 METHOD_GET_NEW_ARRIVED_NOTIFICATIONS = 27 METHOD_GET_SPECIFIC_META = 28 METHOD_GET_PERSISTENCE_INFO = 29 METHOD_GET_PERSISTENCE_INFOS = 30 METHOD_PERPETUATE_OBJECT = 31 METHOD_UNPERPETUATE_OBJECT = 32 METHOD_PREPARE_GET_OBJECT_OR_META_BINARY = 33 METHOD_GET_PASSWORD_INFO = 34 METHOD_GET_PASSWORD_INFOS = 35 METHOD_GET_METAS_MULTIPLE_PARAM = 36 METHOD_COMPLETE_POST_OBJECTS = 37 METHOD_CHANGE_META = 38 METHOD_CHANGE_METAS = 39 METHOD_RATE_OBJECTS = 40 METHOD_POST_META_BINARY_WITH_DATA_ID = 41 METHOD_POST_META_BINARIES_WITH_DATA_ID = 42 METHOD_RATE_OBJECT_WITH_POSTING = 43 METHOD_RATE_OBJECTS_WITH_POSTING = 44 METHOD_GET_OBJECT_INFOS = 45 METHOD_SEARCH_OBJECT_LIGHT = 46 METHOD_REGISTER_USER = 47 METHOD_GET_USERS = 48 METHOD_SYNC_USER_PROFILE = 49 METHOD_SEARCH_USERS_USER_POINT = 50 METHOD_SEARCH_USERS_PLAYED_COURSE = 53 METHOD_SEARCH_USERS_CLEARED_COURSE = 54 METHOD_SEARCH_USERS_POSITIVE_RATED_COURSE = 55 METHOD_UPDATE_LAST_LOGIN_TIME = 59 METHOD_GET_USERNAME_NG_TYPE = 65 METHOD_GET_COURSES = 70 METHOD_SEARCH_COURSES_POINT_RANKING = 71 METHOD_SEARCH_COURSES_LATEST = 73 METHOD_SEARCH_COURSES_POSTED_BY = 74 METHOD_SEARCH_COURSES_POSITIVE_RATED_BY = 75 METHOD_SEARCH_COURSES_PLAYED_BY = 76 METHOD_SEARCH_COURSES_ENDLESS_MODE = 79 METHOD_SEARCH_COURSES_FIRST_CLEAR = 80 METHOD_SEARCH_COURSES_BEST_TIME = 81 METHOD_GET_COURSES_EVENT = 85 METHOD_SEARCH_COURSES_EVENT = 86 METHOD_SEARCH_COMMENTS_IN_ORDER = 94 METHOD_SEARCH_COMMENTS = 95 METHOD_GET_DEATH_POSITIONS = 103 METHOD_GET_USER_OR_COURSE = 131 METHOD_GET_REQ_GET_INFO_HEADERS_INFO = 134 METHOD_GET_EVENT_COURSE_STAMP = 153 METHOD_GET_EVENT_COURSE_STATUS = 154 METHOD_GET_EVENT_COURSE_HISTOGRAM = 156 METHOD_GET_EVENT_COURSE_GHOST = 157 METHOD_GET_WORLD_MAP = 160 METHOD_SEARCH_WORLD_MAP_PICK_UP = 162 PROTOCOL_ID = 0x73 class DataStoreClientSMM2(DataStoreProtocolSMM2): def __init__(self, client): self.settings = client.settings self.client = client async def prepare_get_object_v1(self, param): logger.info("DataStoreClientSMM2.prepare_get_object_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PREPARE_GET_OBJECT_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreReqGetInfoV1) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.prepare_get_object_v1 -> done") return info async def prepare_post_object_v1(self, param): logger.info("DataStoreClientSMM2.prepare_post_object_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PREPARE_POST_OBJECT_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreReqPostInfoV1) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.prepare_post_object_v1 -> done") return info async def complete_post_object_v1(self, param): logger.info("DataStoreClientSMM2.complete_post_object_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_COMPLETE_POST_OBJECT_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.complete_post_object_v1 -> done") async def delete_object(self, param): logger.info("DataStoreClientSMM2.delete_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.delete_object -> done") async def delete_objects(self, param, transactional): logger.info("DataStoreClientSMM2.delete_objects()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(param, stream.add) stream.bool(transactional) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_OBJECTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.delete_objects -> done") return results async def change_meta_v1(self, param): logger.info("DataStoreClientSMM2.change_meta_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CHANGE_META_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.change_meta_v1 -> done") async def change_metas_v1(self, data_ids, param, transactional): logger.info("DataStoreClientSMM2.change_metas_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) stream.list(param, stream.add) stream.bool(transactional) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CHANGE_METAS_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.change_metas_v1 -> done") return results async def get_meta(self, param): logger.info("DataStoreClientSMM2.get_meta()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_META, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreMetaInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.get_meta -> done") return info async def get_metas(self, data_ids, param): logger.info("DataStoreClientSMM2.get_metas()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_METAS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.info = stream.list(DataStoreMetaInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.get_metas -> done") return obj async def prepare_update_object(self, param): logger.info("DataStoreClientSMM2.prepare_update_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PREPARE_UPDATE_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreReqUpdateInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.prepare_update_object -> done") return info async def complete_update_object(self, param): logger.info("DataStoreClientSMM2.complete_update_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_COMPLETE_UPDATE_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.complete_update_object -> done") async def search_object(self, param): logger.info("DataStoreClientSMM2.search_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.extract(DataStoreSearchResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.search_object -> done") return result async def get_notification_url(self, param): logger.info("DataStoreClientSMM2.get_notification_url()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_NOTIFICATION_URL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreReqGetNotificationUrlInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.get_notification_url -> done") return info async def get_new_arrived_notifications_v1(self, param): logger.info("DataStoreClientSMM2.get_new_arrived_notifications_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_NEW_ARRIVED_NOTIFICATIONS_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.list(DataStoreNotificationV1) obj.has_next = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.get_new_arrived_notifications_v1 -> done") return obj async def rate_object(self, target, param, fetch_ratings): logger.info("DataStoreClientSMM2.rate_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) stream.add(param) stream.bool(fetch_ratings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RATE_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreRatingInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.rate_object -> done") return info async def get_rating(self, target, access_password): logger.info("DataStoreClientSMM2.get_rating()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) stream.u64(access_password) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RATING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) rating = stream.extract(DataStoreRatingInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.get_rating -> done") return rating async def get_ratings(self, data_ids, access_password): logger.info("DataStoreClientSMM2.get_ratings()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) stream.u64(access_password) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RATINGS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.ratings = stream.list(lambda: stream.list(DataStoreRatingInfoWithSlot)) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.get_ratings -> done") return obj async def reset_rating(self, target, update_password): logger.info("DataStoreClientSMM2.reset_rating()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) stream.u64(update_password) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RESET_RATING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.reset_rating -> done") async def reset_ratings(self, data_ids, transactional): logger.info("DataStoreClientSMM2.reset_ratings()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) stream.bool(transactional) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RESET_RATINGS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.reset_ratings -> done") return results async def get_specific_meta_v1(self, param): logger.info("DataStoreClientSMM2.get_specific_meta_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SPECIFIC_META_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) infos = stream.list(DataStoreSpecificMetaInfoV1) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.get_specific_meta_v1 -> done") return infos async def post_meta_binary(self, param): logger.info("DataStoreClientSMM2.post_meta_binary()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_POST_META_BINARY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) data_id = stream.u64() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.post_meta_binary -> done") return data_id async def touch_object(self, param): logger.info("DataStoreClientSMM2.touch_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_TOUCH_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.touch_object -> done") async def get_rating_with_log(self, target, access_password): logger.info("DataStoreClientSMM2.get_rating_with_log()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) stream.u64(access_password) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RATING_WITH_LOG, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.rating = stream.extract(DataStoreRatingInfo) obj.log = stream.extract(DataStoreRatingLog) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.get_rating_with_log -> done") return obj async def prepare_post_object(self, param): logger.info("DataStoreClientSMM2.prepare_post_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PREPARE_POST_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreReqPostInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.prepare_post_object -> done") return info async def prepare_get_object(self, param): logger.info("DataStoreClientSMM2.prepare_get_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PREPARE_GET_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreReqGetInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.prepare_get_object -> done") return info async def complete_post_object(self, param): logger.info("DataStoreClientSMM2.complete_post_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_COMPLETE_POST_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.complete_post_object -> done") async def get_new_arrived_notifications(self, param): logger.info("DataStoreClientSMM2.get_new_arrived_notifications()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_NEW_ARRIVED_NOTIFICATIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.list(DataStoreNotification) obj.has_next = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.get_new_arrived_notifications -> done") return obj async def get_specific_meta(self, param): logger.info("DataStoreClientSMM2.get_specific_meta()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SPECIFIC_META, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) infos = stream.list(DataStoreSpecificMetaInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.get_specific_meta -> done") return infos async def get_persistence_info(self, owner_id, slot_id): logger.info("DataStoreClientSMM2.get_persistence_info()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(owner_id) stream.u16(slot_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PERSISTENCE_INFO, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStorePersistenceInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.get_persistence_info -> done") return info async def get_persistence_infos(self, owner_id, slot_ids): logger.info("DataStoreClientSMM2.get_persistence_infos()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(owner_id) stream.list(slot_ids, stream.u16) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PERSISTENCE_INFOS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.infos = stream.list(DataStorePersistenceInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.get_persistence_infos -> done") return obj async def perpetuate_object(self, persistence_slot_id, data_id, delete_last_object): logger.info("DataStoreClientSMM2.perpetuate_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.u16(persistence_slot_id) stream.u64(data_id) stream.bool(delete_last_object) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PERPETUATE_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.perpetuate_object -> done") async def unperpetuate_object(self, persistence_slot_id, delete_last_object): logger.info("DataStoreClientSMM2.unperpetuate_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.u16(persistence_slot_id) stream.bool(delete_last_object) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UNPERPETUATE_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.unperpetuate_object -> done") async def prepare_get_object_or_meta_binary(self, param): logger.info("DataStoreClientSMM2.prepare_get_object_or_meta_binary()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PREPARE_GET_OBJECT_OR_META_BINARY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.get_info = stream.extract(DataStoreReqGetInfo) obj.additional_meta = stream.extract(DataStoreReqGetAdditionalMeta) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.prepare_get_object_or_meta_binary -> done") return obj async def get_password_info(self, data_id): logger.info("DataStoreClientSMM2.get_password_info()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(data_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PASSWORD_INFO, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStorePasswordInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.get_password_info -> done") return info async def get_password_infos(self, data_ids): logger.info("DataStoreClientSMM2.get_password_infos()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PASSWORD_INFOS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.infos = stream.list(DataStorePasswordInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.get_password_infos -> done") return obj async def get_metas_multiple_param(self, params): logger.info("DataStoreClientSMM2.get_metas_multiple_param()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(params, stream.add) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_METAS_MULTIPLE_PARAM, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.infos = stream.list(DataStoreMetaInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.get_metas_multiple_param -> done") return obj async def complete_post_objects(self, data_ids): logger.info("DataStoreClientSMM2.complete_post_objects()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_COMPLETE_POST_OBJECTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.complete_post_objects -> done") async def change_meta(self, param): logger.info("DataStoreClientSMM2.change_meta()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CHANGE_META, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.change_meta -> done") async def change_metas(self, data_ids, param, transactional): logger.info("DataStoreClientSMM2.change_metas()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) stream.list(param, stream.add) stream.bool(transactional) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CHANGE_METAS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.change_metas -> done") return results async def rate_objects(self, targets, param, transactional, fetch_ratings): logger.info("DataStoreClientSMM2.rate_objects()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(targets, stream.add) stream.list(param, stream.add) stream.bool(transactional) stream.bool(fetch_ratings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RATE_OBJECTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.infos = stream.list(DataStoreRatingInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.rate_objects -> done") return obj async def post_meta_binary_with_data_id(self, data_id, param): logger.info("DataStoreClientSMM2.post_meta_binary_with_data_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(data_id) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_POST_META_BINARY_WITH_DATA_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.post_meta_binary_with_data_id -> done") async def post_meta_binaries_with_data_id(self, data_ids, param, transactional): logger.info("DataStoreClientSMM2.post_meta_binaries_with_data_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) stream.list(param, stream.add) stream.bool(transactional) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_POST_META_BINARIES_WITH_DATA_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.post_meta_binaries_with_data_id -> done") return results async def rate_object_with_posting(self, target, rate_param, post_param, fetch_ratings): logger.info("DataStoreClientSMM2.rate_object_with_posting()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) stream.add(rate_param) stream.add(post_param) stream.bool(fetch_ratings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RATE_OBJECT_WITH_POSTING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(DataStoreRatingInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.rate_object_with_posting -> done") return info async def rate_objects_with_posting(self, targets, rate_param, post_param, transactional, fetch_ratings): logger.info("DataStoreClientSMM2.rate_objects_with_posting()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(targets, stream.add) stream.list(rate_param, stream.add) stream.list(post_param, stream.add) stream.bool(transactional) stream.bool(fetch_ratings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RATE_OBJECTS_WITH_POSTING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.ratings = stream.list(DataStoreRatingInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.rate_objects_with_posting -> done") return obj async def get_object_infos(self, data_ids): logger.info("DataStoreClientSMM2.get_object_infos()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(data_ids, stream.u64) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_OBJECT_INFOS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.infos = stream.list(DataStoreReqGetInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.get_object_infos -> done") return obj async def search_object_light(self, param): logger.info("DataStoreClientSMM2.search_object_light()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_OBJECT_LIGHT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.extract(DataStoreSearchResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.search_object_light -> done") return result async def register_user(self, param): logger.info("DataStoreClientSMM2.register_user()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REGISTER_USER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.register_user -> done") async def get_users(self, param): logger.info("DataStoreClientSMM2.get_users()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_USERS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.users = stream.list(UserInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.get_users -> done") return obj async def sync_user_profile(self, param): logger.info("DataStoreClientSMM2.sync_user_profile()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SYNC_USER_PROFILE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.extract(SyncUserProfileResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.sync_user_profile -> done") return result async def search_users_user_point(self, param): logger.info("DataStoreClientSMM2.search_users_user_point()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_USERS_USER_POINT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.users = stream.list(UserInfo) obj.ranks = stream.list(stream.u32) obj.result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.search_users_user_point -> done") return obj async def search_users_played_course(self, param): logger.info("DataStoreClientSMM2.search_users_played_course()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_USERS_PLAYED_COURSE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) users = stream.list(UserInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.search_users_played_course -> done") return users async def search_users_cleared_course(self, param): logger.info("DataStoreClientSMM2.search_users_cleared_course()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_USERS_CLEARED_COURSE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) users = stream.list(UserInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.search_users_cleared_course -> done") return users async def search_users_positive_rated_course(self, param): logger.info("DataStoreClientSMM2.search_users_positive_rated_course()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_USERS_POSITIVE_RATED_COURSE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) users = stream.list(UserInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.search_users_positive_rated_course -> done") return users async def update_last_login_time(self): logger.info("DataStoreClientSMM2.update_last_login_time()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_LAST_LOGIN_TIME, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.update_last_login_time -> done") async def get_username_ng_type(self): logger.info("DataStoreClientSMM2.get_username_ng_type()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_USERNAME_NG_TYPE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) unk = stream.u8() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.get_username_ng_type -> done") return unk async def get_courses(self, param): logger.info("DataStoreClientSMM2.get_courses()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_COURSES, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.courses = stream.list(CourseInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.get_courses -> done") return obj async def search_courses_point_ranking(self, param): logger.info("DataStoreClientSMM2.search_courses_point_ranking()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_COURSES_POINT_RANKING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.courses = stream.list(CourseInfo) obj.ranks = stream.list(stream.u32) obj.result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.search_courses_point_ranking -> done") return obj async def search_courses_latest(self, param): logger.info("DataStoreClientSMM2.search_courses_latest()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_COURSES_LATEST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.courses = stream.list(CourseInfo) obj.result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.search_courses_latest -> done") return obj async def search_courses_posted_by(self, param): logger.info("DataStoreClientSMM2.search_courses_posted_by()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_COURSES_POSTED_BY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.courses = stream.list(CourseInfo) obj.result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.search_courses_posted_by -> done") return obj async def search_courses_positive_rated_by(self, param): logger.info("DataStoreClientSMM2.search_courses_positive_rated_by()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_COURSES_POSITIVE_RATED_BY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) courses = stream.list(CourseInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.search_courses_positive_rated_by -> done") return courses async def search_courses_played_by(self, param): logger.info("DataStoreClientSMM2.search_courses_played_by()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_COURSES_PLAYED_BY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) courses = stream.list(CourseInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.search_courses_played_by -> done") return courses async def search_courses_endless_mode(self, param): logger.info("DataStoreClientSMM2.search_courses_endless_mode()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_COURSES_ENDLESS_MODE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) courses = stream.list(CourseInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.search_courses_endless_mode -> done") return courses async def search_courses_first_clear(self, param): logger.info("DataStoreClientSMM2.search_courses_first_clear()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_COURSES_FIRST_CLEAR, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.courses = stream.list(CourseInfo) obj.result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.search_courses_first_clear -> done") return obj async def search_courses_best_time(self, param): logger.info("DataStoreClientSMM2.search_courses_best_time()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_COURSES_BEST_TIME, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.courses = stream.list(CourseInfo) obj.result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.search_courses_best_time -> done") return obj async def get_courses_event(self, param, dummy): logger.info("DataStoreClientSMM2.get_courses_event()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) stream.add(dummy) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_COURSES_EVENT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.courses = stream.list(EventCourseInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.get_courses_event -> done") return obj async def search_courses_event(self, param): logger.info("DataStoreClientSMM2.search_courses_event()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_COURSES_EVENT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) courses = stream.list(EventCourseInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.search_courses_event -> done") return courses async def search_comments_in_order(self, param): logger.info("DataStoreClientSMM2.search_comments_in_order()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_COMMENTS_IN_ORDER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.comments = stream.list(CommentInfo) obj.result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.search_comments_in_order -> done") return obj async def search_comments(self, data_id): logger.info("DataStoreClientSMM2.search_comments()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(data_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_COMMENTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) comments = stream.list(CommentInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.search_comments -> done") return comments async def get_death_positions(self, data_id): logger.info("DataStoreClientSMM2.get_death_positions()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(data_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_DEATH_POSITIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) positions = stream.list(DeathPositionInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.get_death_positions -> done") return positions async def get_user_or_course(self, param): logger.info("DataStoreClientSMM2.get_user_or_course()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_USER_OR_COURSE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.user = stream.extract(UserInfo) obj.course = stream.extract(CourseInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.get_user_or_course -> done") return obj async def get_req_get_info_headers_info(self, type): logger.info("DataStoreClientSMM2.get_req_get_info_headers_info()") #--- request --- stream = streams.StreamOut(self.settings) stream.u8(type) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_REQ_GET_INFO_HEADERS_INFO, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.extract(ReqGetInfoHeadersInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.get_req_get_info_headers_info -> done") return result async def get_event_course_stamp(self): logger.info("DataStoreClientSMM2.get_event_course_stamp()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_EVENT_COURSE_STAMP, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) stamps = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.get_event_course_stamp -> done") return stamps async def get_event_course_status(self): logger.info("DataStoreClientSMM2.get_event_course_status()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_EVENT_COURSE_STATUS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(EventCourseStatusInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.get_event_course_status -> done") return info async def get_event_course_histogram(self, param): logger.info("DataStoreClientSMM2.get_event_course_histogram()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_EVENT_COURSE_HISTOGRAM, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) histogram = stream.extract(EventCourseHistogram) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.get_event_course_histogram -> done") return histogram async def get_event_course_ghost(self, param): logger.info("DataStoreClientSMM2.get_event_course_ghost()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_EVENT_COURSE_GHOST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) ghosts = stream.list(EventCourseGhostInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.get_event_course_ghost -> done") return ghosts async def get_world_map(self, param): logger.info("DataStoreClientSMM2.get_world_map()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_WORLD_MAP, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.maps = stream.list(WorldMapInfo) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.get_world_map -> done") return obj async def search_world_map_pick_up(self, param): logger.info("DataStoreClientSMM2.search_world_map_pick_up()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_WORLD_MAP_PICK_UP, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) maps = stream.list(WorldMapInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DataStoreClientSMM2.search_world_map_pick_up -> done") return maps class DataStoreServerSMM2(DataStoreProtocolSMM2): def __init__(self): self.methods = { self.METHOD_PREPARE_GET_OBJECT_V1: self.handle_prepare_get_object_v1, self.METHOD_PREPARE_POST_OBJECT_V1: self.handle_prepare_post_object_v1, self.METHOD_COMPLETE_POST_OBJECT_V1: self.handle_complete_post_object_v1, self.METHOD_DELETE_OBJECT: self.handle_delete_object, self.METHOD_DELETE_OBJECTS: self.handle_delete_objects, self.METHOD_CHANGE_META_V1: self.handle_change_meta_v1, self.METHOD_CHANGE_METAS_V1: self.handle_change_metas_v1, self.METHOD_GET_META: self.handle_get_meta, self.METHOD_GET_METAS: self.handle_get_metas, self.METHOD_PREPARE_UPDATE_OBJECT: self.handle_prepare_update_object, self.METHOD_COMPLETE_UPDATE_OBJECT: self.handle_complete_update_object, self.METHOD_SEARCH_OBJECT: self.handle_search_object, self.METHOD_GET_NOTIFICATION_URL: self.handle_get_notification_url, self.METHOD_GET_NEW_ARRIVED_NOTIFICATIONS_V1: self.handle_get_new_arrived_notifications_v1, self.METHOD_RATE_OBJECT: self.handle_rate_object, self.METHOD_GET_RATING: self.handle_get_rating, self.METHOD_GET_RATINGS: self.handle_get_ratings, self.METHOD_RESET_RATING: self.handle_reset_rating, self.METHOD_RESET_RATINGS: self.handle_reset_ratings, self.METHOD_GET_SPECIFIC_META_V1: self.handle_get_specific_meta_v1, self.METHOD_POST_META_BINARY: self.handle_post_meta_binary, self.METHOD_TOUCH_OBJECT: self.handle_touch_object, self.METHOD_GET_RATING_WITH_LOG: self.handle_get_rating_with_log, self.METHOD_PREPARE_POST_OBJECT: self.handle_prepare_post_object, self.METHOD_PREPARE_GET_OBJECT: self.handle_prepare_get_object, self.METHOD_COMPLETE_POST_OBJECT: self.handle_complete_post_object, self.METHOD_GET_NEW_ARRIVED_NOTIFICATIONS: self.handle_get_new_arrived_notifications, self.METHOD_GET_SPECIFIC_META: self.handle_get_specific_meta, self.METHOD_GET_PERSISTENCE_INFO: self.handle_get_persistence_info, self.METHOD_GET_PERSISTENCE_INFOS: self.handle_get_persistence_infos, self.METHOD_PERPETUATE_OBJECT: self.handle_perpetuate_object, self.METHOD_UNPERPETUATE_OBJECT: self.handle_unperpetuate_object, self.METHOD_PREPARE_GET_OBJECT_OR_META_BINARY: self.handle_prepare_get_object_or_meta_binary, self.METHOD_GET_PASSWORD_INFO: self.handle_get_password_info, self.METHOD_GET_PASSWORD_INFOS: self.handle_get_password_infos, self.METHOD_GET_METAS_MULTIPLE_PARAM: self.handle_get_metas_multiple_param, self.METHOD_COMPLETE_POST_OBJECTS: self.handle_complete_post_objects, self.METHOD_CHANGE_META: self.handle_change_meta, self.METHOD_CHANGE_METAS: self.handle_change_metas, self.METHOD_RATE_OBJECTS: self.handle_rate_objects, self.METHOD_POST_META_BINARY_WITH_DATA_ID: self.handle_post_meta_binary_with_data_id, self.METHOD_POST_META_BINARIES_WITH_DATA_ID: self.handle_post_meta_binaries_with_data_id, self.METHOD_RATE_OBJECT_WITH_POSTING: self.handle_rate_object_with_posting, self.METHOD_RATE_OBJECTS_WITH_POSTING: self.handle_rate_objects_with_posting, self.METHOD_GET_OBJECT_INFOS: self.handle_get_object_infos, self.METHOD_SEARCH_OBJECT_LIGHT: self.handle_search_object_light, self.METHOD_REGISTER_USER: self.handle_register_user, self.METHOD_GET_USERS: self.handle_get_users, self.METHOD_SYNC_USER_PROFILE: self.handle_sync_user_profile, self.METHOD_SEARCH_USERS_USER_POINT: self.handle_search_users_user_point, self.METHOD_SEARCH_USERS_PLAYED_COURSE: self.handle_search_users_played_course, self.METHOD_SEARCH_USERS_CLEARED_COURSE: self.handle_search_users_cleared_course, self.METHOD_SEARCH_USERS_POSITIVE_RATED_COURSE: self.handle_search_users_positive_rated_course, self.METHOD_UPDATE_LAST_LOGIN_TIME: self.handle_update_last_login_time, self.METHOD_GET_USERNAME_NG_TYPE: self.handle_get_username_ng_type, self.METHOD_GET_COURSES: self.handle_get_courses, self.METHOD_SEARCH_COURSES_POINT_RANKING: self.handle_search_courses_point_ranking, self.METHOD_SEARCH_COURSES_LATEST: self.handle_search_courses_latest, self.METHOD_SEARCH_COURSES_POSTED_BY: self.handle_search_courses_posted_by, self.METHOD_SEARCH_COURSES_POSITIVE_RATED_BY: self.handle_search_courses_positive_rated_by, self.METHOD_SEARCH_COURSES_PLAYED_BY: self.handle_search_courses_played_by, self.METHOD_SEARCH_COURSES_ENDLESS_MODE: self.handle_search_courses_endless_mode, self.METHOD_SEARCH_COURSES_FIRST_CLEAR: self.handle_search_courses_first_clear, self.METHOD_SEARCH_COURSES_BEST_TIME: self.handle_search_courses_best_time, self.METHOD_GET_COURSES_EVENT: self.handle_get_courses_event, self.METHOD_SEARCH_COURSES_EVENT: self.handle_search_courses_event, self.METHOD_SEARCH_COMMENTS_IN_ORDER: self.handle_search_comments_in_order, self.METHOD_SEARCH_COMMENTS: self.handle_search_comments, self.METHOD_GET_DEATH_POSITIONS: self.handle_get_death_positions, self.METHOD_GET_USER_OR_COURSE: self.handle_get_user_or_course, self.METHOD_GET_REQ_GET_INFO_HEADERS_INFO: self.handle_get_req_get_info_headers_info, self.METHOD_GET_EVENT_COURSE_STAMP: self.handle_get_event_course_stamp, self.METHOD_GET_EVENT_COURSE_STATUS: self.handle_get_event_course_status, self.METHOD_GET_EVENT_COURSE_HISTOGRAM: self.handle_get_event_course_histogram, self.METHOD_GET_EVENT_COURSE_GHOST: self.handle_get_event_course_ghost, self.METHOD_GET_WORLD_MAP: self.handle_get_world_map, self.METHOD_SEARCH_WORLD_MAP_PICK_UP: self.handle_search_world_map_pick_up, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on DataStoreServerSMM2: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_prepare_get_object_v1(self, client, input, output): logger.info("DataStoreServerSMM2.prepare_get_object_v1()") #--- request --- param = input.extract(DataStorePrepareGetParamV1) response = await self.prepare_get_object_v1(client, param) #--- response --- if not isinstance(response, DataStoreReqGetInfoV1): raise RuntimeError("Expected DataStoreReqGetInfoV1, got %s" %response.__class__.__name__) output.add(response) async def handle_prepare_post_object_v1(self, client, input, output): logger.info("DataStoreServerSMM2.prepare_post_object_v1()") #--- request --- param = input.extract(DataStorePreparePostParamV1) response = await self.prepare_post_object_v1(client, param) #--- response --- if not isinstance(response, DataStoreReqPostInfoV1): raise RuntimeError("Expected DataStoreReqPostInfoV1, got %s" %response.__class__.__name__) output.add(response) async def handle_complete_post_object_v1(self, client, input, output): logger.info("DataStoreServerSMM2.complete_post_object_v1()") #--- request --- param = input.extract(DataStoreCompletePostParamV1) await self.complete_post_object_v1(client, param) async def handle_delete_object(self, client, input, output): logger.info("DataStoreServerSMM2.delete_object()") #--- request --- param = input.extract(DataStoreDeleteParam) await self.delete_object(client, param) async def handle_delete_objects(self, client, input, output): logger.info("DataStoreServerSMM2.delete_objects()") #--- request --- param = input.list(DataStoreDeleteParam) transactional = input.bool() response = await self.delete_objects(client, param, transactional) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.result) async def handle_change_meta_v1(self, client, input, output): logger.info("DataStoreServerSMM2.change_meta_v1()") #--- request --- param = input.extract(DataStoreChangeMetaParamV1) await self.change_meta_v1(client, param) async def handle_change_metas_v1(self, client, input, output): logger.info("DataStoreServerSMM2.change_metas_v1()") #--- request --- data_ids = input.list(input.u64) param = input.list(DataStoreChangeMetaParamV1) transactional = input.bool() response = await self.change_metas_v1(client, data_ids, param, transactional) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.result) async def handle_get_meta(self, client, input, output): logger.info("DataStoreServerSMM2.get_meta()") #--- request --- param = input.extract(DataStoreGetMetaParam) response = await self.get_meta(client, param) #--- response --- if not isinstance(response, DataStoreMetaInfo): raise RuntimeError("Expected DataStoreMetaInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_metas(self, client, input, output): logger.info("DataStoreServerSMM2.get_metas()") #--- request --- data_ids = input.list(input.u64) param = input.extract(DataStoreGetMetaParam) response = await self.get_metas(client, data_ids, param) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['info', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.info, output.add) output.list(response.results, output.result) async def handle_prepare_update_object(self, client, input, output): logger.info("DataStoreServerSMM2.prepare_update_object()") #--- request --- param = input.extract(DataStorePrepareUpdateParam) response = await self.prepare_update_object(client, param) #--- response --- if not isinstance(response, DataStoreReqUpdateInfo): raise RuntimeError("Expected DataStoreReqUpdateInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_complete_update_object(self, client, input, output): logger.info("DataStoreServerSMM2.complete_update_object()") #--- request --- param = input.extract(DataStoreCompleteUpdateParam) await self.complete_update_object(client, param) async def handle_search_object(self, client, input, output): logger.info("DataStoreServerSMM2.search_object()") #--- request --- param = input.extract(DataStoreSearchParam) response = await self.search_object(client, param) #--- response --- if not isinstance(response, DataStoreSearchResult): raise RuntimeError("Expected DataStoreSearchResult, got %s" %response.__class__.__name__) output.add(response) async def handle_get_notification_url(self, client, input, output): logger.info("DataStoreServerSMM2.get_notification_url()") #--- request --- param = input.extract(DataStoreGetNotificationUrlParam) response = await self.get_notification_url(client, param) #--- response --- if not isinstance(response, DataStoreReqGetNotificationUrlInfo): raise RuntimeError("Expected DataStoreReqGetNotificationUrlInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_new_arrived_notifications_v1(self, client, input, output): logger.info("DataStoreServerSMM2.get_new_arrived_notifications_v1()") #--- request --- param = input.extract(DataStoreGetNewArrivedNotificationsParam) response = await self.get_new_arrived_notifications_v1(client, param) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'has_next']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.result, output.add) output.bool(response.has_next) async def handle_rate_object(self, client, input, output): logger.info("DataStoreServerSMM2.rate_object()") #--- request --- target = input.extract(DataStoreRatingTarget) param = input.extract(DataStoreRateObjectParam) fetch_ratings = input.bool() response = await self.rate_object(client, target, param, fetch_ratings) #--- response --- if not isinstance(response, DataStoreRatingInfo): raise RuntimeError("Expected DataStoreRatingInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_rating(self, client, input, output): logger.info("DataStoreServerSMM2.get_rating()") #--- request --- target = input.extract(DataStoreRatingTarget) access_password = input.u64() response = await self.get_rating(client, target, access_password) #--- response --- if not isinstance(response, DataStoreRatingInfo): raise RuntimeError("Expected DataStoreRatingInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_ratings(self, client, input, output): logger.info("DataStoreServerSMM2.get_ratings()") #--- request --- data_ids = input.list(input.u64) access_password = input.u64() response = await self.get_ratings(client, data_ids, access_password) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['ratings', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.ratings, lambda x: output.list(x, output.add)) output.list(response.results, output.result) async def handle_reset_rating(self, client, input, output): logger.info("DataStoreServerSMM2.reset_rating()") #--- request --- target = input.extract(DataStoreRatingTarget) update_password = input.u64() await self.reset_rating(client, target, update_password) async def handle_reset_ratings(self, client, input, output): logger.info("DataStoreServerSMM2.reset_ratings()") #--- request --- data_ids = input.list(input.u64) transactional = input.bool() response = await self.reset_ratings(client, data_ids, transactional) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.result) async def handle_get_specific_meta_v1(self, client, input, output): logger.info("DataStoreServerSMM2.get_specific_meta_v1()") #--- request --- param = input.extract(DataStoreGetSpecificMetaParamV1) response = await self.get_specific_meta_v1(client, param) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_post_meta_binary(self, client, input, output): logger.info("DataStoreServerSMM2.post_meta_binary()") #--- request --- param = input.extract(DataStorePreparePostParam) response = await self.post_meta_binary(client, param) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u64(response) async def handle_touch_object(self, client, input, output): logger.info("DataStoreServerSMM2.touch_object()") #--- request --- param = input.extract(DataStoreTouchObjectParam) await self.touch_object(client, param) async def handle_get_rating_with_log(self, client, input, output): logger.info("DataStoreServerSMM2.get_rating_with_log()") #--- request --- target = input.extract(DataStoreRatingTarget) access_password = input.u64() response = await self.get_rating_with_log(client, target, access_password) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['rating', 'log']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.add(response.rating) output.add(response.log) async def handle_prepare_post_object(self, client, input, output): logger.info("DataStoreServerSMM2.prepare_post_object()") #--- request --- param = input.extract(DataStorePreparePostParam) response = await self.prepare_post_object(client, param) #--- response --- if not isinstance(response, DataStoreReqPostInfo): raise RuntimeError("Expected DataStoreReqPostInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_prepare_get_object(self, client, input, output): logger.info("DataStoreServerSMM2.prepare_get_object()") #--- request --- param = input.extract(DataStorePrepareGetParam) response = await self.prepare_get_object(client, param) #--- response --- if not isinstance(response, DataStoreReqGetInfo): raise RuntimeError("Expected DataStoreReqGetInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_complete_post_object(self, client, input, output): logger.info("DataStoreServerSMM2.complete_post_object()") #--- request --- param = input.extract(DataStoreCompletePostParam) await self.complete_post_object(client, param) async def handle_get_new_arrived_notifications(self, client, input, output): logger.info("DataStoreServerSMM2.get_new_arrived_notifications()") #--- request --- param = input.extract(DataStoreGetNewArrivedNotificationsParam) response = await self.get_new_arrived_notifications(client, param) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'has_next']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.result, output.add) output.bool(response.has_next) async def handle_get_specific_meta(self, client, input, output): logger.info("DataStoreServerSMM2.get_specific_meta()") #--- request --- param = input.extract(DataStoreGetSpecificMetaParam) response = await self.get_specific_meta(client, param) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_persistence_info(self, client, input, output): logger.info("DataStoreServerSMM2.get_persistence_info()") #--- request --- owner_id = input.pid() slot_id = input.u16() response = await self.get_persistence_info(client, owner_id, slot_id) #--- response --- if not isinstance(response, DataStorePersistenceInfo): raise RuntimeError("Expected DataStorePersistenceInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_persistence_infos(self, client, input, output): logger.info("DataStoreServerSMM2.get_persistence_infos()") #--- request --- owner_id = input.pid() slot_ids = input.list(input.u16) response = await self.get_persistence_infos(client, owner_id, slot_ids) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['infos', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.infos, output.add) output.list(response.results, output.result) async def handle_perpetuate_object(self, client, input, output): logger.info("DataStoreServerSMM2.perpetuate_object()") #--- request --- persistence_slot_id = input.u16() data_id = input.u64() delete_last_object = input.bool() await self.perpetuate_object(client, persistence_slot_id, data_id, delete_last_object) async def handle_unperpetuate_object(self, client, input, output): logger.info("DataStoreServerSMM2.unperpetuate_object()") #--- request --- persistence_slot_id = input.u16() delete_last_object = input.bool() await self.unperpetuate_object(client, persistence_slot_id, delete_last_object) async def handle_prepare_get_object_or_meta_binary(self, client, input, output): logger.info("DataStoreServerSMM2.prepare_get_object_or_meta_binary()") #--- request --- param = input.extract(DataStorePrepareGetParam) response = await self.prepare_get_object_or_meta_binary(client, param) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['get_info', 'additional_meta']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.add(response.get_info) output.add(response.additional_meta) async def handle_get_password_info(self, client, input, output): logger.info("DataStoreServerSMM2.get_password_info()") #--- request --- data_id = input.u64() response = await self.get_password_info(client, data_id) #--- response --- if not isinstance(response, DataStorePasswordInfo): raise RuntimeError("Expected DataStorePasswordInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_password_infos(self, client, input, output): logger.info("DataStoreServerSMM2.get_password_infos()") #--- request --- data_ids = input.list(input.u64) response = await self.get_password_infos(client, data_ids) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['infos', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.infos, output.add) output.list(response.results, output.result) async def handle_get_metas_multiple_param(self, client, input, output): logger.info("DataStoreServerSMM2.get_metas_multiple_param()") #--- request --- params = input.list(DataStoreGetMetaParam) response = await self.get_metas_multiple_param(client, params) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['infos', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.infos, output.add) output.list(response.results, output.result) async def handle_complete_post_objects(self, client, input, output): logger.info("DataStoreServerSMM2.complete_post_objects()") #--- request --- data_ids = input.list(input.u64) await self.complete_post_objects(client, data_ids) async def handle_change_meta(self, client, input, output): logger.info("DataStoreServerSMM2.change_meta()") #--- request --- param = input.extract(DataStoreChangeMetaParam) await self.change_meta(client, param) async def handle_change_metas(self, client, input, output): logger.info("DataStoreServerSMM2.change_metas()") #--- request --- data_ids = input.list(input.u64) param = input.list(DataStoreChangeMetaParam) transactional = input.bool() response = await self.change_metas(client, data_ids, param, transactional) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.result) async def handle_rate_objects(self, client, input, output): logger.info("DataStoreServerSMM2.rate_objects()") #--- request --- targets = input.list(DataStoreRatingTarget) param = input.list(DataStoreRateObjectParam) transactional = input.bool() fetch_ratings = input.bool() response = await self.rate_objects(client, targets, param, transactional, fetch_ratings) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['infos', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.infos, output.add) output.list(response.results, output.result) async def handle_post_meta_binary_with_data_id(self, client, input, output): logger.info("DataStoreServerSMM2.post_meta_binary_with_data_id()") #--- request --- data_id = input.u64() param = input.extract(DataStorePreparePostParam) await self.post_meta_binary_with_data_id(client, data_id, param) async def handle_post_meta_binaries_with_data_id(self, client, input, output): logger.info("DataStoreServerSMM2.post_meta_binaries_with_data_id()") #--- request --- data_ids = input.list(input.u64) param = input.list(DataStorePreparePostParam) transactional = input.bool() response = await self.post_meta_binaries_with_data_id(client, data_ids, param, transactional) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.result) async def handle_rate_object_with_posting(self, client, input, output): logger.info("DataStoreServerSMM2.rate_object_with_posting()") #--- request --- target = input.extract(DataStoreRatingTarget) rate_param = input.extract(DataStoreRateObjectParam) post_param = input.extract(DataStorePreparePostParam) fetch_ratings = input.bool() response = await self.rate_object_with_posting(client, target, rate_param, post_param, fetch_ratings) #--- response --- if not isinstance(response, DataStoreRatingInfo): raise RuntimeError("Expected DataStoreRatingInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_rate_objects_with_posting(self, client, input, output): logger.info("DataStoreServerSMM2.rate_objects_with_posting()") #--- request --- targets = input.list(DataStoreRatingTarget) rate_param = input.list(DataStoreRateObjectParam) post_param = input.list(DataStorePreparePostParam) transactional = input.bool() fetch_ratings = input.bool() response = await self.rate_objects_with_posting(client, targets, rate_param, post_param, transactional, fetch_ratings) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['ratings', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.ratings, output.add) output.list(response.results, output.result) async def handle_get_object_infos(self, client, input, output): logger.info("DataStoreServerSMM2.get_object_infos()") #--- request --- data_ids = input.list(input.u64) response = await self.get_object_infos(client, data_ids) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['infos', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.infos, output.add) output.list(response.results, output.result) async def handle_search_object_light(self, client, input, output): logger.info("DataStoreServerSMM2.search_object_light()") #--- request --- param = input.extract(DataStoreSearchParam) response = await self.search_object_light(client, param) #--- response --- if not isinstance(response, DataStoreSearchResult): raise RuntimeError("Expected DataStoreSearchResult, got %s" %response.__class__.__name__) output.add(response) async def handle_register_user(self, client, input, output): logger.info("DataStoreServerSMM2.register_user()") #--- request --- param = input.extract(RegisterUserParam) await self.register_user(client, param) async def handle_get_users(self, client, input, output): logger.info("DataStoreServerSMM2.get_users()") #--- request --- param = input.extract(GetUsersParam) response = await self.get_users(client, param) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['users', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.users, output.add) output.list(response.results, output.result) async def handle_sync_user_profile(self, client, input, output): logger.info("DataStoreServerSMM2.sync_user_profile()") #--- request --- param = input.extract(SyncUserProfileParam) response = await self.sync_user_profile(client, param) #--- response --- if not isinstance(response, SyncUserProfileResult): raise RuntimeError("Expected SyncUserProfileResult, got %s" %response.__class__.__name__) output.add(response) async def handle_search_users_user_point(self, client, input, output): logger.info("DataStoreServerSMM2.search_users_user_point()") #--- request --- param = input.extract(SearchUsersUserPointParam) response = await self.search_users_user_point(client, param) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['users', 'ranks', 'result']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.users, output.add) output.list(response.ranks, output.u32) output.bool(response.result) async def handle_search_users_played_course(self, client, input, output): logger.info("DataStoreServerSMM2.search_users_played_course()") #--- request --- param = input.extract(SearchUsersPlayedCourseParam) response = await self.search_users_played_course(client, param) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_search_users_cleared_course(self, client, input, output): logger.info("DataStoreServerSMM2.search_users_cleared_course()") #--- request --- param = input.extract(SearchUsersClearedCourseParam) response = await self.search_users_cleared_course(client, param) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_search_users_positive_rated_course(self, client, input, output): logger.info("DataStoreServerSMM2.search_users_positive_rated_course()") #--- request --- param = input.extract(SearchUsersPositiveRatedCourseParam) response = await self.search_users_positive_rated_course(client, param) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_update_last_login_time(self, client, input, output): logger.info("DataStoreServerSMM2.update_last_login_time()") #--- request --- await self.update_last_login_time(client) async def handle_get_username_ng_type(self, client, input, output): logger.info("DataStoreServerSMM2.get_username_ng_type()") #--- request --- response = await self.get_username_ng_type(client) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u8(response) async def handle_get_courses(self, client, input, output): logger.info("DataStoreServerSMM2.get_courses()") #--- request --- param = input.extract(GetCoursesParam) response = await self.get_courses(client, param) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['courses', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.courses, output.add) output.list(response.results, output.result) async def handle_search_courses_point_ranking(self, client, input, output): logger.info("DataStoreServerSMM2.search_courses_point_ranking()") #--- request --- param = input.extract(SearchCoursesPointRankingParam) response = await self.search_courses_point_ranking(client, param) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['courses', 'ranks', 'result']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.courses, output.add) output.list(response.ranks, output.u32) output.bool(response.result) async def handle_search_courses_latest(self, client, input, output): logger.info("DataStoreServerSMM2.search_courses_latest()") #--- request --- param = input.extract(SearchCoursesLatestParam) response = await self.search_courses_latest(client, param) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['courses', 'result']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.courses, output.add) output.bool(response.result) async def handle_search_courses_posted_by(self, client, input, output): logger.info("DataStoreServerSMM2.search_courses_posted_by()") #--- request --- param = input.extract(SearchCoursesPostedByParam) response = await self.search_courses_posted_by(client, param) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['courses', 'result']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.courses, output.add) output.bool(response.result) async def handle_search_courses_positive_rated_by(self, client, input, output): logger.info("DataStoreServerSMM2.search_courses_positive_rated_by()") #--- request --- param = input.extract(SearchCoursesPositiveRatedByParam) response = await self.search_courses_positive_rated_by(client, param) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_search_courses_played_by(self, client, input, output): logger.info("DataStoreServerSMM2.search_courses_played_by()") #--- request --- param = input.extract(SearchCoursesPlayedByParam) response = await self.search_courses_played_by(client, param) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_search_courses_endless_mode(self, client, input, output): logger.info("DataStoreServerSMM2.search_courses_endless_mode()") #--- request --- param = input.extract(SearchCoursesEndlessModeParam) response = await self.search_courses_endless_mode(client, param) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_search_courses_first_clear(self, client, input, output): logger.info("DataStoreServerSMM2.search_courses_first_clear()") #--- request --- param = input.extract(SearchCoursesFirstClearParam) response = await self.search_courses_first_clear(client, param) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['courses', 'result']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.courses, output.add) output.bool(response.result) async def handle_search_courses_best_time(self, client, input, output): logger.info("DataStoreServerSMM2.search_courses_best_time()") #--- request --- param = input.extract(SearchCoursesBestTimeParam) response = await self.search_courses_best_time(client, param) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['courses', 'result']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.courses, output.add) output.bool(response.result) async def handle_get_courses_event(self, client, input, output): logger.info("DataStoreServerSMM2.get_courses_event()") #--- request --- param = input.extract(GetCoursesParam) dummy = input.extract(GetCoursesEventParam) response = await self.get_courses_event(client, param, dummy) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['courses', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.courses, output.add) output.list(response.results, output.result) async def handle_search_courses_event(self, client, input, output): logger.info("DataStoreServerSMM2.search_courses_event()") #--- request --- param = input.extract(SearchCoursesEventParam) response = await self.search_courses_event(client, param) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_search_comments_in_order(self, client, input, output): logger.info("DataStoreServerSMM2.search_comments_in_order()") #--- request --- param = input.extract(SearchCommentsInOrderParam) response = await self.search_comments_in_order(client, param) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['comments', 'result']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.comments, output.add) output.bool(response.result) async def handle_search_comments(self, client, input, output): logger.info("DataStoreServerSMM2.search_comments()") #--- request --- data_id = input.u64() response = await self.search_comments(client, data_id) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_death_positions(self, client, input, output): logger.info("DataStoreServerSMM2.get_death_positions()") #--- request --- data_id = input.u64() response = await self.get_death_positions(client, data_id) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_user_or_course(self, client, input, output): logger.info("DataStoreServerSMM2.get_user_or_course()") #--- request --- param = input.extract(GetUserOrCourseParam) response = await self.get_user_or_course(client, param) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['user', 'course']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.add(response.user) output.add(response.course) async def handle_get_req_get_info_headers_info(self, client, input, output): logger.info("DataStoreServerSMM2.get_req_get_info_headers_info()") #--- request --- type = input.u8() response = await self.get_req_get_info_headers_info(client, type) #--- response --- if not isinstance(response, ReqGetInfoHeadersInfo): raise RuntimeError("Expected ReqGetInfoHeadersInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_event_course_stamp(self, client, input, output): logger.info("DataStoreServerSMM2.get_event_course_stamp()") #--- request --- response = await self.get_event_course_stamp(client) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u32(response) async def handle_get_event_course_status(self, client, input, output): logger.info("DataStoreServerSMM2.get_event_course_status()") #--- request --- response = await self.get_event_course_status(client) #--- response --- if not isinstance(response, EventCourseStatusInfo): raise RuntimeError("Expected EventCourseStatusInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_event_course_histogram(self, client, input, output): logger.info("DataStoreServerSMM2.get_event_course_histogram()") #--- request --- param = input.extract(GetEventCourseHistogramParam) response = await self.get_event_course_histogram(client, param) #--- response --- if not isinstance(response, EventCourseHistogram): raise RuntimeError("Expected EventCourseHistogram, got %s" %response.__class__.__name__) output.add(response) async def handle_get_event_course_ghost(self, client, input, output): logger.info("DataStoreServerSMM2.get_event_course_ghost()") #--- request --- param = input.extract(GetEventCourseGhostParam) response = await self.get_event_course_ghost(client, param) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_world_map(self, client, input, output): logger.info("DataStoreServerSMM2.get_world_map()") #--- request --- param = input.extract(GetWorldMapParam) response = await self.get_world_map(client, param) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['maps', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.maps, output.add) output.list(response.results, output.result) async def handle_search_world_map_pick_up(self, client, input, output): logger.info("DataStoreServerSMM2.search_world_map_pick_up()") #--- request --- param = input.extract(SearchWorldMapPickUpParam) response = await self.search_world_map_pick_up(client, param) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def prepare_get_object_v1(self, *args): logger.warning("DataStoreServerSMM2.prepare_get_object_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def prepare_post_object_v1(self, *args): logger.warning("DataStoreServerSMM2.prepare_post_object_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def complete_post_object_v1(self, *args): logger.warning("DataStoreServerSMM2.complete_post_object_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def delete_object(self, *args): logger.warning("DataStoreServerSMM2.delete_object not implemented") raise common.RMCError("Core::NotImplemented") async def delete_objects(self, *args): logger.warning("DataStoreServerSMM2.delete_objects not implemented") raise common.RMCError("Core::NotImplemented") async def change_meta_v1(self, *args): logger.warning("DataStoreServerSMM2.change_meta_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def change_metas_v1(self, *args): logger.warning("DataStoreServerSMM2.change_metas_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def get_meta(self, *args): logger.warning("DataStoreServerSMM2.get_meta not implemented") raise common.RMCError("Core::NotImplemented") async def get_metas(self, *args): logger.warning("DataStoreServerSMM2.get_metas not implemented") raise common.RMCError("Core::NotImplemented") async def prepare_update_object(self, *args): logger.warning("DataStoreServerSMM2.prepare_update_object not implemented") raise common.RMCError("Core::NotImplemented") async def complete_update_object(self, *args): logger.warning("DataStoreServerSMM2.complete_update_object not implemented") raise common.RMCError("Core::NotImplemented") async def search_object(self, *args): logger.warning("DataStoreServerSMM2.search_object not implemented") raise common.RMCError("Core::NotImplemented") async def get_notification_url(self, *args): logger.warning("DataStoreServerSMM2.get_notification_url not implemented") raise common.RMCError("Core::NotImplemented") async def get_new_arrived_notifications_v1(self, *args): logger.warning("DataStoreServerSMM2.get_new_arrived_notifications_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def rate_object(self, *args): logger.warning("DataStoreServerSMM2.rate_object not implemented") raise common.RMCError("Core::NotImplemented") async def get_rating(self, *args): logger.warning("DataStoreServerSMM2.get_rating not implemented") raise common.RMCError("Core::NotImplemented") async def get_ratings(self, *args): logger.warning("DataStoreServerSMM2.get_ratings not implemented") raise common.RMCError("Core::NotImplemented") async def reset_rating(self, *args): logger.warning("DataStoreServerSMM2.reset_rating not implemented") raise common.RMCError("Core::NotImplemented") async def reset_ratings(self, *args): logger.warning("DataStoreServerSMM2.reset_ratings not implemented") raise common.RMCError("Core::NotImplemented") async def get_specific_meta_v1(self, *args): logger.warning("DataStoreServerSMM2.get_specific_meta_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def post_meta_binary(self, *args): logger.warning("DataStoreServerSMM2.post_meta_binary not implemented") raise common.RMCError("Core::NotImplemented") async def touch_object(self, *args): logger.warning("DataStoreServerSMM2.touch_object not implemented") raise common.RMCError("Core::NotImplemented") async def get_rating_with_log(self, *args): logger.warning("DataStoreServerSMM2.get_rating_with_log not implemented") raise common.RMCError("Core::NotImplemented") async def prepare_post_object(self, *args): logger.warning("DataStoreServerSMM2.prepare_post_object not implemented") raise common.RMCError("Core::NotImplemented") async def prepare_get_object(self, *args): logger.warning("DataStoreServerSMM2.prepare_get_object not implemented") raise common.RMCError("Core::NotImplemented") async def complete_post_object(self, *args): logger.warning("DataStoreServerSMM2.complete_post_object not implemented") raise common.RMCError("Core::NotImplemented") async def get_new_arrived_notifications(self, *args): logger.warning("DataStoreServerSMM2.get_new_arrived_notifications not implemented") raise common.RMCError("Core::NotImplemented") async def get_specific_meta(self, *args): logger.warning("DataStoreServerSMM2.get_specific_meta not implemented") raise common.RMCError("Core::NotImplemented") async def get_persistence_info(self, *args): logger.warning("DataStoreServerSMM2.get_persistence_info not implemented") raise common.RMCError("Core::NotImplemented") async def get_persistence_infos(self, *args): logger.warning("DataStoreServerSMM2.get_persistence_infos not implemented") raise common.RMCError("Core::NotImplemented") async def perpetuate_object(self, *args): logger.warning("DataStoreServerSMM2.perpetuate_object not implemented") raise common.RMCError("Core::NotImplemented") async def unperpetuate_object(self, *args): logger.warning("DataStoreServerSMM2.unperpetuate_object not implemented") raise common.RMCError("Core::NotImplemented") async def prepare_get_object_or_meta_binary(self, *args): logger.warning("DataStoreServerSMM2.prepare_get_object_or_meta_binary not implemented") raise common.RMCError("Core::NotImplemented") async def get_password_info(self, *args): logger.warning("DataStoreServerSMM2.get_password_info not implemented") raise common.RMCError("Core::NotImplemented") async def get_password_infos(self, *args): logger.warning("DataStoreServerSMM2.get_password_infos not implemented") raise common.RMCError("Core::NotImplemented") async def get_metas_multiple_param(self, *args): logger.warning("DataStoreServerSMM2.get_metas_multiple_param not implemented") raise common.RMCError("Core::NotImplemented") async def complete_post_objects(self, *args): logger.warning("DataStoreServerSMM2.complete_post_objects not implemented") raise common.RMCError("Core::NotImplemented") async def change_meta(self, *args): logger.warning("DataStoreServerSMM2.change_meta not implemented") raise common.RMCError("Core::NotImplemented") async def change_metas(self, *args): logger.warning("DataStoreServerSMM2.change_metas not implemented") raise common.RMCError("Core::NotImplemented") async def rate_objects(self, *args): logger.warning("DataStoreServerSMM2.rate_objects not implemented") raise common.RMCError("Core::NotImplemented") async def post_meta_binary_with_data_id(self, *args): logger.warning("DataStoreServerSMM2.post_meta_binary_with_data_id not implemented") raise common.RMCError("Core::NotImplemented") async def post_meta_binaries_with_data_id(self, *args): logger.warning("DataStoreServerSMM2.post_meta_binaries_with_data_id not implemented") raise common.RMCError("Core::NotImplemented") async def rate_object_with_posting(self, *args): logger.warning("DataStoreServerSMM2.rate_object_with_posting not implemented") raise common.RMCError("Core::NotImplemented") async def rate_objects_with_posting(self, *args): logger.warning("DataStoreServerSMM2.rate_objects_with_posting not implemented") raise common.RMCError("Core::NotImplemented") async def get_object_infos(self, *args): logger.warning("DataStoreServerSMM2.get_object_infos not implemented") raise common.RMCError("Core::NotImplemented") async def search_object_light(self, *args): logger.warning("DataStoreServerSMM2.search_object_light not implemented") raise common.RMCError("Core::NotImplemented") async def register_user(self, *args): logger.warning("DataStoreServerSMM2.register_user not implemented") raise common.RMCError("Core::NotImplemented") async def get_users(self, *args): logger.warning("DataStoreServerSMM2.get_users not implemented") raise common.RMCError("Core::NotImplemented") async def sync_user_profile(self, *args): logger.warning("DataStoreServerSMM2.sync_user_profile not implemented") raise common.RMCError("Core::NotImplemented") async def search_users_user_point(self, *args): logger.warning("DataStoreServerSMM2.search_users_user_point not implemented") raise common.RMCError("Core::NotImplemented") async def search_users_played_course(self, *args): logger.warning("DataStoreServerSMM2.search_users_played_course not implemented") raise common.RMCError("Core::NotImplemented") async def search_users_cleared_course(self, *args): logger.warning("DataStoreServerSMM2.search_users_cleared_course not implemented") raise common.RMCError("Core::NotImplemented") async def search_users_positive_rated_course(self, *args): logger.warning("DataStoreServerSMM2.search_users_positive_rated_course not implemented") raise common.RMCError("Core::NotImplemented") async def update_last_login_time(self, *args): logger.warning("DataStoreServerSMM2.update_last_login_time not implemented") raise common.RMCError("Core::NotImplemented") async def get_username_ng_type(self, *args): logger.warning("DataStoreServerSMM2.get_username_ng_type not implemented") raise common.RMCError("Core::NotImplemented") async def get_courses(self, *args): logger.warning("DataStoreServerSMM2.get_courses not implemented") raise common.RMCError("Core::NotImplemented") async def search_courses_point_ranking(self, *args): logger.warning("DataStoreServerSMM2.search_courses_point_ranking not implemented") raise common.RMCError("Core::NotImplemented") async def search_courses_latest(self, *args): logger.warning("DataStoreServerSMM2.search_courses_latest not implemented") raise common.RMCError("Core::NotImplemented") async def search_courses_posted_by(self, *args): logger.warning("DataStoreServerSMM2.search_courses_posted_by not implemented") raise common.RMCError("Core::NotImplemented") async def search_courses_positive_rated_by(self, *args): logger.warning("DataStoreServerSMM2.search_courses_positive_rated_by not implemented") raise common.RMCError("Core::NotImplemented") async def search_courses_played_by(self, *args): logger.warning("DataStoreServerSMM2.search_courses_played_by not implemented") raise common.RMCError("Core::NotImplemented") async def search_courses_endless_mode(self, *args): logger.warning("DataStoreServerSMM2.search_courses_endless_mode not implemented") raise common.RMCError("Core::NotImplemented") async def search_courses_first_clear(self, *args): logger.warning("DataStoreServerSMM2.search_courses_first_clear not implemented") raise common.RMCError("Core::NotImplemented") async def search_courses_best_time(self, *args): logger.warning("DataStoreServerSMM2.search_courses_best_time not implemented") raise common.RMCError("Core::NotImplemented") async def get_courses_event(self, *args): logger.warning("DataStoreServerSMM2.get_courses_event not implemented") raise common.RMCError("Core::NotImplemented") async def search_courses_event(self, *args): logger.warning("DataStoreServerSMM2.search_courses_event not implemented") raise common.RMCError("Core::NotImplemented") async def search_comments_in_order(self, *args): logger.warning("DataStoreServerSMM2.search_comments_in_order not implemented") raise common.RMCError("Core::NotImplemented") async def search_comments(self, *args): logger.warning("DataStoreServerSMM2.search_comments not implemented") raise common.RMCError("Core::NotImplemented") async def get_death_positions(self, *args): logger.warning("DataStoreServerSMM2.get_death_positions not implemented") raise common.RMCError("Core::NotImplemented") async def get_user_or_course(self, *args): logger.warning("DataStoreServerSMM2.get_user_or_course not implemented") raise common.RMCError("Core::NotImplemented") async def get_req_get_info_headers_info(self, *args): logger.warning("DataStoreServerSMM2.get_req_get_info_headers_info not implemented") raise common.RMCError("Core::NotImplemented") async def get_event_course_stamp(self, *args): logger.warning("DataStoreServerSMM2.get_event_course_stamp not implemented") raise common.RMCError("Core::NotImplemented") async def get_event_course_status(self, *args): logger.warning("DataStoreServerSMM2.get_event_course_status not implemented") raise common.RMCError("Core::NotImplemented") async def get_event_course_histogram(self, *args): logger.warning("DataStoreServerSMM2.get_event_course_histogram not implemented") raise common.RMCError("Core::NotImplemented") async def get_event_course_ghost(self, *args): logger.warning("DataStoreServerSMM2.get_event_course_ghost not implemented") raise common.RMCError("Core::NotImplemented") async def get_world_map(self, *args): logger.warning("DataStoreServerSMM2.get_world_map not implemented") raise common.RMCError("Core::NotImplemented") async def search_world_map_pick_up(self, *args): logger.warning("DataStoreServerSMM2.search_world_map_pick_up not implemented") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/debug.py ================================================ # This file was generated automatically by generate_protocols.py from nintendo.nex import notification, rmc, common, streams import logging logger = logging.getLogger(__name__) class ApiCall(common.Structure): def __init__(self): super().__init__() self.name = None self.time = None self.pid = None def check_required(self, settings, version): for field in ['name', 'time', 'pid']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.name = stream.string() self.time = stream.datetime() self.pid = stream.pid() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.name) stream.datetime(self.time) stream.pid(self.pid) class ApiCallSummary(common.Structure): def __init__(self): super().__init__() self.name = None self.limit_exceeded = None self.duration = None self.limit = None self.start = None self.limit_exceeded_count = None self.total_count = None def check_required(self, settings, version): for field in ['name', 'limit_exceeded', 'duration', 'limit', 'start', 'limit_exceeded_count', 'total_count']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.name = stream.string() self.limit_exceeded = stream.u32() self.duration = stream.u32() self.limit = stream.u32() self.start = stream.datetime() self.limit_exceeded_count = stream.u32() self.total_count = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.name) stream.u32(self.limit_exceeded) stream.u32(self.duration) stream.u32(self.limit) stream.datetime(self.start) stream.u32(self.limit_exceeded_count) stream.u32(self.total_count) class DebugProtocol: METHOD_ENABLE_API_RECORDER = 1 METHOD_DISABLE_API_RECORDER = 2 METHOD_IS_API_RECORDER_ENABLED = 3 METHOD_GET_API_CALLS = 4 METHOD_SET_EXCLUDE_JOINED_MATCHMAKE_SESSION = 5 METHOD_GET_EXCLUDE_JOINED_MATCHMAKE_SESSION = 6 METHOD_GET_API_CALL_SUMMARY = 7 PROTOCOL_ID = 0x74 class DebugClient(DebugProtocol): def __init__(self, client): self.settings = client.settings self.client = client async def enable_api_recorder(self): logger.info("DebugClient.enable_api_recorder()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_ENABLE_API_RECORDER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DebugClient.enable_api_recorder -> done") async def disable_api_recorder(self): logger.info("DebugClient.disable_api_recorder()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DISABLE_API_RECORDER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DebugClient.disable_api_recorder -> done") async def is_api_recorder_enabled(self): logger.info("DebugClient.is_api_recorder_enabled()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_IS_API_RECORDER_ENABLED, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) enabled = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DebugClient.is_api_recorder_enabled -> done") return enabled async def get_api_calls(self, pids, start, end): logger.info("DebugClient.get_api_calls()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) stream.datetime(start) stream.datetime(end) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_API_CALLS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) calls = stream.list(ApiCall) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DebugClient.get_api_calls -> done") return calls async def get_api_call_summary(self, pid, start, end, only_limit_exceeded): logger.info("DebugClient.get_api_call_summary()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) stream.datetime(start) stream.datetime(end) stream.bool(only_limit_exceeded) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_API_CALL_SUMMARY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) summaries = stream.list(ApiCallSummary) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("DebugClient.get_api_call_summary -> done") return summaries class DebugServer(DebugProtocol): def __init__(self): self.methods = { self.METHOD_ENABLE_API_RECORDER: self.handle_enable_api_recorder, self.METHOD_DISABLE_API_RECORDER: self.handle_disable_api_recorder, self.METHOD_IS_API_RECORDER_ENABLED: self.handle_is_api_recorder_enabled, self.METHOD_GET_API_CALLS: self.handle_get_api_calls, self.METHOD_SET_EXCLUDE_JOINED_MATCHMAKE_SESSION: self.handle_set_exclude_joined_matchmake_session, self.METHOD_GET_EXCLUDE_JOINED_MATCHMAKE_SESSION: self.handle_get_exclude_joined_matchmake_session, self.METHOD_GET_API_CALL_SUMMARY: self.handle_get_api_call_summary, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on DebugServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_enable_api_recorder(self, client, input, output): logger.info("DebugServer.enable_api_recorder()") #--- request --- await self.enable_api_recorder(client) async def handle_disable_api_recorder(self, client, input, output): logger.info("DebugServer.disable_api_recorder()") #--- request --- await self.disable_api_recorder(client) async def handle_is_api_recorder_enabled(self, client, input, output): logger.info("DebugServer.is_api_recorder_enabled()") #--- request --- response = await self.is_api_recorder_enabled(client) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_api_calls(self, client, input, output): logger.info("DebugServer.get_api_calls()") #--- request --- pids = input.list(input.pid) start = input.datetime() end = input.datetime() response = await self.get_api_calls(client, pids, start, end) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_set_exclude_joined_matchmake_session(self, client, input, output): logger.warning("DebugServer.set_exclude_joined_matchmake_session is not supported") raise common.RMCError("Core::NotImplemented") async def handle_get_exclude_joined_matchmake_session(self, client, input, output): logger.warning("DebugServer.get_exclude_joined_matchmake_session is not supported") raise common.RMCError("Core::NotImplemented") async def handle_get_api_call_summary(self, client, input, output): logger.info("DebugServer.get_api_call_summary()") #--- request --- pid = input.pid() start = input.datetime() end = input.datetime() only_limit_exceeded = input.bool() response = await self.get_api_call_summary(client, pid, start, end, only_limit_exceeded) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def enable_api_recorder(self, *args): logger.warning("DebugServer.enable_api_recorder not implemented") raise common.RMCError("Core::NotImplemented") async def disable_api_recorder(self, *args): logger.warning("DebugServer.disable_api_recorder not implemented") raise common.RMCError("Core::NotImplemented") async def is_api_recorder_enabled(self, *args): logger.warning("DebugServer.is_api_recorder_enabled not implemented") raise common.RMCError("Core::NotImplemented") async def get_api_calls(self, *args): logger.warning("DebugServer.get_api_calls not implemented") raise common.RMCError("Core::NotImplemented") async def get_api_call_summary(self, *args): logger.warning("DebugServer.get_api_call_summary not implemented") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/errors.py ================================================ error_names = { 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" } error_codes = {name: code for code, name in error_names.items()} ================================================ FILE: nintendo/nex/friends.py ================================================ # This file was generated automatically by generate_protocols.py from nintendo.nex import notification, rmc, common, streams import logging logger = logging.getLogger(__name__) class AccountExtraInfo(common.Structure): def __init__(self): super().__init__() self.local_friend_code = None self.move_count = None self.token = None def check_required(self, settings, version): for field in ['local_friend_code', 'move_count', 'token']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.local_friend_code = stream.u64() self.move_count = stream.u32() self.token = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.local_friend_code) stream.u32(self.move_count) stream.string(self.token) class FriendComment(common.Data): def __init__(self): super().__init__() self.pid = None self.comment = None self.modified_at = None def check_required(self, settings, version): for field in ['pid', 'comment', 'modified_at']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.u32() self.comment = stream.string() self.modified_at = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.pid) stream.string(self.comment) stream.datetime(self.modified_at) common.DataHolder.register(FriendComment, "FriendComment") class FriendKey(common.Structure): def __init__(self): super().__init__() self.unk1 = None self.unk2 = None def check_required(self, settings, version): for field in ['unk1', 'unk2']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.unk1 = stream.u32() self.unk2 = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.unk1) stream.datetime(self.unk2) class FriendMii(common.Data): def __init__(self): super().__init__() self.pid = None self.mii = Mii() self.modified_at = None def check_required(self, settings, version): for field in ['pid', 'modified_at']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.mii = stream.extract(Mii) self.modified_at = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.add(self.mii) stream.datetime(self.modified_at) common.DataHolder.register(FriendMii, "FriendMii") class FriendMiiList(common.Data): def __init__(self): super().__init__() self.unk1 = None self.mii = MiiList() self.unk2 = None def check_required(self, settings, version): for field in ['unk1', 'unk2']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.unk1 = stream.u32() self.mii = stream.extract(MiiList) self.unk2 = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.unk1) stream.add(self.mii) stream.datetime(self.unk2) common.DataHolder.register(FriendMiiList, "FriendMiiList") class FriendPersistentInfo(common.Data): def __init__(self): super().__init__() self.pid = None self.region = None self.country = None self.area = None self.language = None self.platform = None self.game_key = GameKey() self.message = None self.message_updated = None self.friended = None self.last_online = None def check_required(self, settings, version): for field in ['pid', 'region', 'country', 'area', 'language', 'platform', 'message', 'message_updated', 'friended', 'last_online']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.region = stream.u8() self.country = stream.u8() self.area = stream.u8() self.language = stream.u8() self.platform = stream.u8() self.game_key = stream.extract(GameKey) self.message = stream.string() self.message_updated = stream.datetime() self.friended = stream.datetime() self.last_online = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.u8(self.region) stream.u8(self.country) stream.u8(self.area) stream.u8(self.language) stream.u8(self.platform) stream.add(self.game_key) stream.string(self.message) stream.datetime(self.message_updated) stream.datetime(self.friended) stream.datetime(self.last_online) common.DataHolder.register(FriendPersistentInfo, "FriendPersistentInfo") class FriendPicture(common.Data): def __init__(self): super().__init__() self.unk = None self.data = None self.datetime = None def check_required(self, settings, version): for field in ['unk', 'data', 'datetime']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.unk = stream.u32() self.data = stream.buffer() self.datetime = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.unk) stream.buffer(self.data) stream.datetime(self.datetime) common.DataHolder.register(FriendPicture, "FriendPicture") class FriendPresence(common.Data): def __init__(self): super().__init__() self.pid = None self.presence = NintendoPresence() def check_required(self, settings, version): for field in ['pid']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.presence = stream.extract(NintendoPresence) def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.add(self.presence) common.DataHolder.register(FriendPresence, "FriendPresence") class FriendRelationship(common.Data): def __init__(self): super().__init__() self.pid = None self.friend_code = None self.is_complete = None def check_required(self, settings, version): for field in ['pid', 'friend_code', 'is_complete']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.friend_code = stream.u64() self.is_complete = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.u64(self.friend_code) stream.u8(self.is_complete) common.DataHolder.register(FriendRelationship, "FriendRelationship") class GameKey(common.Data): def __init__(self): super().__init__() self.title_id = 0 self.title_version = 0 def check_required(self, settings, version): pass def load(self, stream, version): self.title_id = stream.u64() self.title_version = stream.u16() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.title_id) stream.u16(self.title_version) common.DataHolder.register(GameKey, "GameKey") class Mii(common.Data): def __init__(self): super().__init__() self.name = None self.unk1 = None self.unk2 = None self.mii_data = None def check_required(self, settings, version): for field in ['name', 'unk1', 'unk2', 'mii_data']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.name = stream.string() self.unk1 = stream.bool() self.unk2 = stream.u8() self.mii_data = stream.buffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.name) stream.bool(self.unk1) stream.u8(self.unk2) stream.buffer(self.mii_data) common.DataHolder.register(Mii, "Mii") class MiiList(common.Data): def __init__(self): super().__init__() self.unk1 = None self.unk2 = None self.unk3 = None self.mii_datas = None def check_required(self, settings, version): for field in ['unk1', 'unk2', 'unk3', 'mii_datas']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.unk1 = stream.string() self.unk2 = stream.bool() self.unk3 = stream.u8() self.mii_datas = stream.list(stream.buffer) def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.unk1) stream.bool(self.unk2) stream.u8(self.unk3) stream.list(self.mii_datas, stream.buffer) common.DataHolder.register(MiiList, "MiiList") class MyProfile(common.Data): def __init__(self): super().__init__() self.region = None self.country = None self.area = None self.language = None self.platform = None self.local_friend_code_seed = None self.mac_address = None self.serial_number = None def check_required(self, settings, version): for field in ['region', 'country', 'area', 'language', 'platform', 'local_friend_code_seed', 'mac_address', 'serial_number']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.region = stream.u8() self.country = stream.u8() self.area = stream.u8() self.language = stream.u8() self.platform = stream.u8() self.local_friend_code_seed = stream.u64() self.mac_address = stream.string() self.serial_number = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.region) stream.u8(self.country) stream.u8(self.area) stream.u8(self.language) stream.u8(self.platform) stream.u64(self.local_friend_code_seed) stream.string(self.mac_address) stream.string(self.serial_number) common.DataHolder.register(MyProfile, "MyProfile") class NintendoPresence(common.Data): def __init__(self): super().__init__() self.changed_bit_flag = None self.game_key = GameKey() self.game_mode_description = None self.join_availability_flag = None self.matchmake_system_type = None self.join_game_id = None self.join_game_mode = None self.owner_pid = None self.join_group_id = None self.application_data = None def check_required(self, settings, version): for field in ['changed_bit_flag', 'game_mode_description', 'join_availability_flag', 'matchmake_system_type', 'join_game_id', 'join_game_mode', 'owner_pid', 'join_group_id', 'application_data']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.changed_bit_flag = stream.u32() self.game_key = stream.extract(GameKey) self.game_mode_description = stream.string() self.join_availability_flag = stream.u32() self.matchmake_system_type = stream.u8() self.join_game_id = stream.u32() self.join_game_mode = stream.u32() self.owner_pid = stream.pid() self.join_group_id = stream.u32() self.application_data = stream.buffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.changed_bit_flag) stream.add(self.game_key) stream.string(self.game_mode_description) stream.u32(self.join_availability_flag) stream.u8(self.matchmake_system_type) stream.u32(self.join_game_id) stream.u32(self.join_game_mode) stream.pid(self.owner_pid) stream.u32(self.join_group_id) stream.buffer(self.application_data) common.DataHolder.register(NintendoPresence, "NintendoPresence") class PlayedGame(common.Data): def __init__(self): super().__init__() self.game_key = GameKey() self.datetime = None def check_required(self, settings, version): for field in ['datetime']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.game_key = stream.extract(GameKey) self.datetime = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.add(self.game_key) stream.datetime(self.datetime) common.DataHolder.register(PlayedGame, "PlayedGame") class BlacklistedPrincipal(common.Data): def __init__(self): super().__init__() self.principal_info = PrincipalBasicInfo() self.game_key = GameKey() self.since = None def check_required(self, settings, version): for field in ['since']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.principal_info = stream.extract(PrincipalBasicInfo) self.game_key = stream.extract(GameKey) self.since = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.add(self.principal_info) stream.add(self.game_key) stream.datetime(self.since) common.DataHolder.register(BlacklistedPrincipal, "BlacklistedPrincipal") class Comment(common.Data): def __init__(self): super().__init__() self.unk = None self.text = None self.changed = None def check_required(self, settings, version): for field in ['unk', 'text', 'changed']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.unk = stream.u8() self.text = stream.string() self.changed = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.unk) stream.string(self.text) stream.datetime(self.changed) common.DataHolder.register(Comment, "Comment") class FriendInfo(common.Data): def __init__(self): super().__init__() self.nna_info = NNAInfo() self.presence = NintendoPresenceV2() self.comment = Comment() self.befriended = None self.last_online = None self.unk = None def check_required(self, settings, version): for field in ['befriended', 'last_online', 'unk']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.nna_info = stream.extract(NNAInfo) self.presence = stream.extract(NintendoPresenceV2) self.comment = stream.extract(Comment) self.befriended = stream.datetime() self.last_online = stream.datetime() self.unk = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.add(self.nna_info) stream.add(self.presence) stream.add(self.comment) stream.datetime(self.befriended) stream.datetime(self.last_online) stream.u64(self.unk) common.DataHolder.register(FriendInfo, "FriendInfo") class FriendRequest(common.Data): def __init__(self): super().__init__() self.principal_info = PrincipalBasicInfo() self.message = FriendRequestMessage() self.sent = None def check_required(self, settings, version): for field in ['sent']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.principal_info = stream.extract(PrincipalBasicInfo) self.message = stream.extract(FriendRequestMessage) self.sent = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.add(self.principal_info) stream.add(self.message) stream.datetime(self.sent) common.DataHolder.register(FriendRequest, "FriendRequest") class FriendRequestMessage(common.Data): def __init__(self): super().__init__() self.friend_request_id = None self.unk1 = None self.unk2 = None self.message = None self.unk3 = None self.string = None self.game_key = GameKey() self.datetime = None self.expires = None def check_required(self, settings, version): for field in ['friend_request_id', 'unk1', 'unk2', 'message', 'unk3', 'string', 'datetime', 'expires']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.friend_request_id = stream.u64() self.unk1 = stream.u8() self.unk2 = stream.u8() self.message = stream.string() self.unk3 = stream.u8() self.string = stream.string() self.game_key = stream.extract(GameKey) self.datetime = stream.datetime() self.expires = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.friend_request_id) stream.u8(self.unk1) stream.u8(self.unk2) stream.string(self.message) stream.u8(self.unk3) stream.string(self.string) stream.add(self.game_key) stream.datetime(self.datetime) stream.datetime(self.expires) common.DataHolder.register(FriendRequestMessage, "FriendRequestMessage") class MiiV2(common.Data): def __init__(self): super().__init__() self.name = None self.unk1 = 0 self.unk2 = 0 self.data = None self.datetime = common.DateTime(0) def check_required(self, settings, version): for field in ['name', 'data']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.name = stream.string() self.unk1 = stream.u8() self.unk2 = stream.u8() self.data = stream.buffer() self.datetime = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.name) stream.u8(self.unk1) stream.u8(self.unk2) stream.buffer(self.data) stream.datetime(self.datetime) common.DataHolder.register(MiiV2, "MiiV2") class NNAInfo(common.Data): def __init__(self): super().__init__() self.principal_info = PrincipalBasicInfo() self.unk1 = 94 self.unk2 = 11 def check_required(self, settings, version): pass def load(self, stream, version): self.principal_info = stream.extract(PrincipalBasicInfo) self.unk1 = stream.u8() self.unk2 = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.add(self.principal_info) stream.u8(self.unk1) stream.u8(self.unk2) common.DataHolder.register(NNAInfo, "NNAInfo") class NintendoCreateAccountData(common.Data): def __init__(self): super().__init__() self.info = NNAInfo() self.token = None self.birthday = None self.unk = None def check_required(self, settings, version): for field in ['token', 'birthday', 'unk']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.info = stream.extract(NNAInfo) self.token = stream.string() self.birthday = stream.datetime() self.unk = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.add(self.info) stream.string(self.token) stream.datetime(self.birthday) stream.u64(self.unk) common.DataHolder.register(NintendoCreateAccountData, "NintendoCreateAccountData") class NintendoPresenceV2(common.Data): def __init__(self): super().__init__() self.flags = 0 self.is_online = False self.game_key = GameKey() self.unk1 = 0 self.message = "" self.unk2 = 0 self.unk3 = 0 self.game_server_id = 0 self.unk4 = 0 self.pid = 0 self.gathering_id = 0 self.application_data = b"" self.unk5 = 3 self.unk6 = 3 self.unk7 = 3 def check_required(self, settings, version): pass def load(self, stream, version): self.flags = stream.u32() self.is_online = stream.bool() self.game_key = stream.extract(GameKey) self.unk1 = stream.u8() self.message = stream.string() self.unk2 = stream.u32() self.unk3 = stream.u8() self.game_server_id = stream.u32() self.unk4 = stream.u32() self.pid = stream.u32() self.gathering_id = stream.u32() self.application_data = stream.buffer() self.unk5 = stream.u8() self.unk6 = stream.u8() self.unk7 = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.flags) stream.bool(self.is_online) stream.add(self.game_key) stream.u8(self.unk1) stream.string(self.message) stream.u32(self.unk2) stream.u8(self.unk3) stream.u32(self.game_server_id) stream.u32(self.unk4) stream.u32(self.pid) stream.u32(self.gathering_id) stream.buffer(self.application_data) stream.u8(self.unk5) stream.u8(self.unk6) stream.u8(self.unk7) common.DataHolder.register(NintendoPresenceV2, "NintendoPresenceV2") class PersistentNotification(common.Data): def __init__(self): super().__init__() self.unk1 = None self.unk2 = None self.unk3 = None self.unk4 = None self.string = None def check_required(self, settings, version): for field in ['unk1', 'unk2', 'unk3', 'unk4', 'string']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.unk1 = stream.u64() self.unk2 = stream.u32() self.unk3 = stream.u32() self.unk4 = stream.u32() self.string = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.unk1) stream.u32(self.unk2) stream.u32(self.unk3) stream.u32(self.unk4) stream.string(self.string) common.DataHolder.register(PersistentNotification, "PersistentNotification") class PrincipalBasicInfo(common.Data): def __init__(self): super().__init__() self.pid = None self.nnid = None self.mii = MiiV2() self.unk = 2 def check_required(self, settings, version): for field in ['pid', 'nnid']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.nnid = stream.string() self.mii = stream.extract(MiiV2) self.unk = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.string(self.nnid) stream.add(self.mii) stream.u8(self.unk) common.DataHolder.register(PrincipalBasicInfo, "PrincipalBasicInfo") class PrincipalPreference(common.Data): def __init__(self): super().__init__() self.show_online_status = None self.show_current_title = None self.block_friend_requests = None def check_required(self, settings, version): for field in ['show_online_status', 'show_current_title', 'block_friend_requests']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.show_online_status = stream.bool() self.show_current_title = stream.bool() self.block_friend_requests = stream.bool() def save(self, stream, version): self.check_required(stream.settings, version) stream.bool(self.show_online_status) stream.bool(self.show_current_title) stream.bool(self.block_friend_requests) common.DataHolder.register(PrincipalPreference, "PrincipalPreference") class PrincipalRequestBlockSetting(common.Data): def __init__(self): super().__init__() self.pid = None self.blocked = None def check_required(self, settings, version): for field in ['pid', 'blocked']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.u32() self.blocked = stream.bool() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.pid) stream.bool(self.blocked) common.DataHolder.register(PrincipalRequestBlockSetting, "PrincipalRequestBlockSetting") class FriendsProtocolV1: METHOD_UPDATE_PROFILE = 1 METHOD_UPDATE_MII = 2 METHOD_UPDATE_MII_LIST = 3 METHOD_UPDATE_PLAYED_GAMES = 4 METHOD_UPDATE_PREFERENCE = 5 METHOD_GET_FRIEND_MII = 6 METHOD_GET_FRIEND_MII_LIST = 7 METHOD_IS_ACTIVE_GAME = 8 METHOD_GET_PRINCIPAL_ID_BY_LOCAL_FRIEND_CODE = 9 METHOD_GET_FRIEND_RELATIONSHIPS = 10 METHOD_ADD_FRIEND_BY_PRINCIPAL_ID = 11 METHOD_ADD_FRIEND_BY_PRINCIPAL_IDS = 12 METHOD_REMOVE_FRIEND_BY_LOCAL_FRIEND_CODE = 13 METHOD_REMOVE_FRIEND_BY_PRINCIPAL_ID = 14 METHOD_GET_ALL_FRIENDS = 15 METHOD_UPDATE_BLACK_LIST = 16 METHOD_SYNC_FRIEND = 17 METHOD_UPDATE_PRESENCE = 18 METHOD_UPDATE_FAVORITE_GAME_KEY = 19 METHOD_UPDATE_COMMENT = 20 METHOD_UPDATE_PICTURE = 21 METHOD_GET_FRIEND_PRESENCE = 22 METHOD_GET_FRIEND_COMMENT = 23 METHOD_GET_FRIEND_PICTURE = 24 METHOD_GET_FRIEND_PERSISTENT_INFO = 25 METHOD_SEND_INVITATION = 26 PROTOCOL_ID = 0x65 class FriendsProtocolV2: METHOD_UPDATE_AND_GET_ALL_INFORMATION = 1 METHOD_ADD_FRIEND = 2 METHOD_ADD_FRIEND_BY_NAME = 3 METHOD_REMOVE_FRIEND = 4 METHOD_ADD_FRIEND_REQUEST = 5 METHOD_CANCEL_FRIEND_REQUEST = 6 METHOD_ACCEPT_FRIEND_REQUEST = 7 METHOD_DELETE_FRIEND_REQUEST = 8 METHOD_DENY_FRIEND_REQUEST = 9 METHOD_MARK_FRIEND_REQUESTS_AS_RECEIVED = 10 METHOD_ADD_BLACK_LIST = 11 METHOD_REMOVE_BLACK_LIST = 12 METHOD_UPDATE_PRESENCE = 13 METHOD_UPDATE_MII = 14 METHOD_UPDATE_COMMENT = 15 METHOD_UPDATE_PREFERENCE = 16 METHOD_GET_BASIC_INFO = 17 METHOD_DELETE_PERSISTENT_NOTIFICATION = 18 METHOD_CHECK_SETTING_STATUS = 19 METHOD_GET_REQUEST_BLOCK_SETTINGS = 20 PROTOCOL_ID = 0x66 class FriendsClientV1(FriendsProtocolV1): def __init__(self, client): self.settings = client.settings self.client = client async def update_profile(self, profile_data): logger.info("FriendsClientV1.update_profile()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(profile_data) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_PROFILE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV1.update_profile -> done") async def update_mii(self, mii): logger.info("FriendsClientV1.update_mii()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(mii) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_MII, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV1.update_mii -> done") async def update_mii_list(self, mii_list): logger.info("FriendsClientV1.update_mii_list()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(mii_list) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_MII_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV1.update_mii_list -> done") async def update_played_games(self, played_games): logger.info("FriendsClientV1.update_played_games()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(played_games, stream.add) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_PLAYED_GAMES, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV1.update_played_games -> done") async def update_preference(self, show_online_status, show_current_title, block_friend_requests): logger.info("FriendsClientV1.update_preference()") #--- request --- stream = streams.StreamOut(self.settings) stream.bool(show_online_status) stream.bool(show_current_title) stream.bool(block_friend_requests) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_PREFERENCE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV1.update_preference -> done") async def get_friend_mii(self, friends): logger.info("FriendsClientV1.get_friend_mii()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(friends, stream.add) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_FRIEND_MII, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) miis = stream.list(FriendMii) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV1.get_friend_mii -> done") return miis async def get_friend_mii_list(self, friends): logger.info("FriendsClientV1.get_friend_mii_list()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(friends, stream.add) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_FRIEND_MII_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) mii_lists = stream.list(FriendMiiList) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV1.get_friend_mii_list -> done") return mii_lists async def is_active_game(self, unk1, game_key): logger.info("FriendsClientV1.is_active_game()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(unk1, stream.u32) stream.add(game_key) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_IS_ACTIVE_GAME, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) unk = stream.list(stream.u32) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV1.is_active_game -> done") return unk async def get_principal_id_by_local_friend_code(self, unk1, unk2): logger.info("FriendsClientV1.get_principal_id_by_local_friend_code()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(unk1) stream.list(unk2, stream.u64) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PRINCIPAL_ID_BY_LOCAL_FRIEND_CODE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) friend_relationships = stream.list(FriendRelationship) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV1.get_principal_id_by_local_friend_code -> done") return friend_relationships async def get_friend_relationships(self, principal_ids): logger.info("FriendsClientV1.get_friend_relationships()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(principal_ids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_FRIEND_RELATIONSHIPS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) friend_relationships = stream.list(FriendRelationship) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV1.get_friend_relationships -> done") return friend_relationships async def add_friend_by_principal_id(self, friend_seed, pid): logger.info("FriendsClientV1.add_friend_by_principal_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(friend_seed) stream.pid(pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_ADD_FRIEND_BY_PRINCIPAL_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) friend_relationship = stream.extract(FriendRelationship) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV1.add_friend_by_principal_id -> done") return friend_relationship async def add_friend_by_principal_ids(self, unk, pids): logger.info("FriendsClientV1.add_friend_by_principal_ids()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(unk) stream.list(pids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_ADD_FRIEND_BY_PRINCIPAL_IDS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) friend_relationships = stream.list(FriendRelationship) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV1.add_friend_by_principal_ids -> done") return friend_relationships async def remove_friend_by_local_friend_code(self, friend_code): logger.info("FriendsClientV1.remove_friend_by_local_friend_code()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(friend_code) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REMOVE_FRIEND_BY_LOCAL_FRIEND_CODE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV1.remove_friend_by_local_friend_code -> done") async def remove_friend_by_principal_id(self, pid): logger.info("FriendsClientV1.remove_friend_by_principal_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REMOVE_FRIEND_BY_PRINCIPAL_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV1.remove_friend_by_principal_id -> done") async def get_all_friends(self): logger.info("FriendsClientV1.get_all_friends()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_ALL_FRIENDS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) friend_relationships = stream.list(FriendRelationship) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV1.get_all_friends -> done") return friend_relationships async def update_black_list(self, unk): logger.info("FriendsClientV1.update_black_list()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(unk, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_BLACK_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV1.update_black_list -> done") async def sync_friend(self, friend_seed, principal_ids, unk): logger.info("FriendsClientV1.sync_friend()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(friend_seed) stream.list(principal_ids, stream.pid) stream.list(unk, stream.u64) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SYNC_FRIEND, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) friend_list = stream.list(FriendRelationship) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV1.sync_friend -> done") return friend_list async def update_presence(self, presence_info, unk): logger.info("FriendsClientV1.update_presence()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(presence_info) stream.bool(unk) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_PRESENCE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV1.update_presence -> done") async def update_favorite_game_key(self, game_key): logger.info("FriendsClientV1.update_favorite_game_key()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(game_key) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_FAVORITE_GAME_KEY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV1.update_favorite_game_key -> done") async def update_comment(self, comment): logger.info("FriendsClientV1.update_comment()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(comment) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_COMMENT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV1.update_comment -> done") async def update_picture(self, unk, picture): logger.info("FriendsClientV1.update_picture()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(unk) stream.buffer(picture) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_PICTURE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV1.update_picture -> done") async def get_friend_presence(self, principal_ids): logger.info("FriendsClientV1.get_friend_presence()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(principal_ids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_FRIEND_PRESENCE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) friend_presence_list = stream.list(FriendPresence) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV1.get_friend_presence -> done") return friend_presence_list async def get_friend_comment(self, friends): logger.info("FriendsClientV1.get_friend_comment()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(friends, stream.add) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_FRIEND_COMMENT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) comments = stream.list(FriendComment) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV1.get_friend_comment -> done") return comments async def get_friend_picture(self, principal_ids): logger.info("FriendsClientV1.get_friend_picture()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(principal_ids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_FRIEND_PICTURE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) friend_pictures = stream.list(FriendPicture) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV1.get_friend_picture -> done") return friend_pictures async def get_friend_persistent_info(self, principal_ids): logger.info("FriendsClientV1.get_friend_persistent_info()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(principal_ids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_FRIEND_PERSISTENT_INFO, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) persistent_infos = stream.list(FriendPersistentInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV1.get_friend_persistent_info -> done") return persistent_infos async def send_invitation(self, unk): logger.info("FriendsClientV1.send_invitation()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(unk, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEND_INVITATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV1.send_invitation -> done") class FriendsClientV2(FriendsProtocolV2): def __init__(self, client): self.settings = client.settings self.client = client async def update_and_get_all_information(self, nna_info, presence, birthday): logger.info("FriendsClientV2.update_and_get_all_information()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(nna_info) stream.add(presence) stream.datetime(birthday) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_AND_GET_ALL_INFORMATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.principal_preference = stream.extract(PrincipalPreference) obj.comment = stream.extract(Comment) obj.friends = stream.list(FriendInfo) obj.sent_requests = stream.list(FriendRequest) obj.received_requests = stream.list(FriendRequest) obj.blacklist = stream.list(BlacklistedPrincipal) obj.unk1 = stream.bool() obj.notifications = stream.list(PersistentNotification) obj.unk2 = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV2.update_and_get_all_information -> done") return obj async def add_friend(self, pid): logger.info("FriendsClientV2.add_friend()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_ADD_FRIEND, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.request = stream.extract(FriendRequest) obj.info = stream.extract(FriendInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV2.add_friend -> done") return obj async def add_friend_by_name(self, name): logger.info("FriendsClientV2.add_friend_by_name()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(name) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_ADD_FRIEND_BY_NAME, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.request = stream.extract(FriendRequest) obj.info = stream.extract(FriendInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV2.add_friend_by_name -> done") return obj async def remove_friend(self, pid): logger.info("FriendsClientV2.remove_friend()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REMOVE_FRIEND, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV2.remove_friend -> done") async def add_friend_request(self, unk1, unk2, unk3, unk4, unk5, game_key, unk6): logger.info("FriendsClientV2.add_friend_request()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(unk1) stream.u8(unk2) stream.string(unk3) stream.u8(unk4) stream.string(unk5) stream.add(game_key) stream.datetime(unk6) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_ADD_FRIEND_REQUEST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.request = stream.extract(FriendRequest) obj.info = stream.extract(FriendInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV2.add_friend_request -> done") return obj async def cancel_friend_request(self, id): logger.info("FriendsClientV2.cancel_friend_request()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CANCEL_FRIEND_REQUEST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV2.cancel_friend_request -> done") async def accept_friend_request(self, id): logger.info("FriendsClientV2.accept_friend_request()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_ACCEPT_FRIEND_REQUEST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(FriendInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV2.accept_friend_request -> done") return info async def delete_friend_request(self, id): logger.info("FriendsClientV2.delete_friend_request()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_FRIEND_REQUEST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV2.delete_friend_request -> done") async def deny_friend_request(self, id): logger.info("FriendsClientV2.deny_friend_request()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DENY_FRIEND_REQUEST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) blacklist = stream.extract(BlacklistedPrincipal) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV2.deny_friend_request -> done") return blacklist async def mark_friend_requests_as_received(self, ids): logger.info("FriendsClientV2.mark_friend_requests_as_received()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(ids, stream.u64) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_MARK_FRIEND_REQUESTS_AS_RECEIVED, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV2.mark_friend_requests_as_received -> done") async def add_black_list(self, principal): logger.info("FriendsClientV2.add_black_list()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(principal) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_ADD_BLACK_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) principal = stream.extract(BlacklistedPrincipal) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV2.add_black_list -> done") return principal async def remove_black_list(self, pid): logger.info("FriendsClientV2.remove_black_list()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REMOVE_BLACK_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV2.remove_black_list -> done") async def update_presence(self, presence): logger.info("FriendsClientV2.update_presence()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(presence) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_PRESENCE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV2.update_presence -> done") async def update_mii(self, mii): logger.info("FriendsClientV2.update_mii()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(mii) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_MII, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) unk = stream.datetime() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV2.update_mii -> done") return unk async def update_comment(self, comment): logger.info("FriendsClientV2.update_comment()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(comment) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_COMMENT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) unk = stream.datetime() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV2.update_comment -> done") return unk async def update_preference(self, preference): logger.info("FriendsClientV2.update_preference()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(preference) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_PREFERENCE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV2.update_preference -> done") async def get_basic_info(self, pids): logger.info("FriendsClientV2.get_basic_info()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_BASIC_INFO, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.list(PrincipalBasicInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV2.get_basic_info -> done") return info async def delete_persistent_notification(self, notifications): logger.info("FriendsClientV2.delete_persistent_notification()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(notifications, stream.add) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_PERSISTENT_NOTIFICATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV2.delete_persistent_notification -> done") async def check_setting_status(self): logger.info("FriendsClientV2.check_setting_status()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CHECK_SETTING_STATUS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) unk = stream.u8() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV2.check_setting_status -> done") return unk async def get_request_block_settings(self, unk): logger.info("FriendsClientV2.get_request_block_settings()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(unk, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_REQUEST_BLOCK_SETTINGS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) settings = stream.list(PrincipalRequestBlockSetting) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("FriendsClientV2.get_request_block_settings -> done") return settings class FriendsServerV1(FriendsProtocolV1): def __init__(self): self.methods = { self.METHOD_UPDATE_PROFILE: self.handle_update_profile, self.METHOD_UPDATE_MII: self.handle_update_mii, self.METHOD_UPDATE_MII_LIST: self.handle_update_mii_list, self.METHOD_UPDATE_PLAYED_GAMES: self.handle_update_played_games, self.METHOD_UPDATE_PREFERENCE: self.handle_update_preference, self.METHOD_GET_FRIEND_MII: self.handle_get_friend_mii, self.METHOD_GET_FRIEND_MII_LIST: self.handle_get_friend_mii_list, self.METHOD_IS_ACTIVE_GAME: self.handle_is_active_game, self.METHOD_GET_PRINCIPAL_ID_BY_LOCAL_FRIEND_CODE: self.handle_get_principal_id_by_local_friend_code, self.METHOD_GET_FRIEND_RELATIONSHIPS: self.handle_get_friend_relationships, self.METHOD_ADD_FRIEND_BY_PRINCIPAL_ID: self.handle_add_friend_by_principal_id, self.METHOD_ADD_FRIEND_BY_PRINCIPAL_IDS: self.handle_add_friend_by_principal_ids, self.METHOD_REMOVE_FRIEND_BY_LOCAL_FRIEND_CODE: self.handle_remove_friend_by_local_friend_code, self.METHOD_REMOVE_FRIEND_BY_PRINCIPAL_ID: self.handle_remove_friend_by_principal_id, self.METHOD_GET_ALL_FRIENDS: self.handle_get_all_friends, self.METHOD_UPDATE_BLACK_LIST: self.handle_update_black_list, self.METHOD_SYNC_FRIEND: self.handle_sync_friend, self.METHOD_UPDATE_PRESENCE: self.handle_update_presence, self.METHOD_UPDATE_FAVORITE_GAME_KEY: self.handle_update_favorite_game_key, self.METHOD_UPDATE_COMMENT: self.handle_update_comment, self.METHOD_UPDATE_PICTURE: self.handle_update_picture, self.METHOD_GET_FRIEND_PRESENCE: self.handle_get_friend_presence, self.METHOD_GET_FRIEND_COMMENT: self.handle_get_friend_comment, self.METHOD_GET_FRIEND_PICTURE: self.handle_get_friend_picture, self.METHOD_GET_FRIEND_PERSISTENT_INFO: self.handle_get_friend_persistent_info, self.METHOD_SEND_INVITATION: self.handle_send_invitation, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on FriendsServerV1: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_update_profile(self, client, input, output): logger.info("FriendsServerV1.update_profile()") #--- request --- profile_data = input.extract(MyProfile) await self.update_profile(client, profile_data) async def handle_update_mii(self, client, input, output): logger.info("FriendsServerV1.update_mii()") #--- request --- mii = input.extract(Mii) await self.update_mii(client, mii) async def handle_update_mii_list(self, client, input, output): logger.info("FriendsServerV1.update_mii_list()") #--- request --- mii_list = input.extract(MiiList) await self.update_mii_list(client, mii_list) async def handle_update_played_games(self, client, input, output): logger.info("FriendsServerV1.update_played_games()") #--- request --- played_games = input.list(PlayedGame) await self.update_played_games(client, played_games) async def handle_update_preference(self, client, input, output): logger.info("FriendsServerV1.update_preference()") #--- request --- show_online_status = input.bool() show_current_title = input.bool() block_friend_requests = input.bool() await self.update_preference(client, show_online_status, show_current_title, block_friend_requests) async def handle_get_friend_mii(self, client, input, output): logger.info("FriendsServerV1.get_friend_mii()") #--- request --- friends = input.list(FriendKey) response = await self.get_friend_mii(client, friends) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_friend_mii_list(self, client, input, output): logger.info("FriendsServerV1.get_friend_mii_list()") #--- request --- friends = input.list(FriendKey) response = await self.get_friend_mii_list(client, friends) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_is_active_game(self, client, input, output): logger.info("FriendsServerV1.is_active_game()") #--- request --- unk1 = input.list(input.u32) game_key = input.extract(GameKey) response = await self.is_active_game(client, unk1, game_key) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.u32) async def handle_get_principal_id_by_local_friend_code(self, client, input, output): logger.info("FriendsServerV1.get_principal_id_by_local_friend_code()") #--- request --- unk1 = input.u64() unk2 = input.list(input.u64) response = await self.get_principal_id_by_local_friend_code(client, unk1, unk2) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_friend_relationships(self, client, input, output): logger.info("FriendsServerV1.get_friend_relationships()") #--- request --- principal_ids = input.list(input.pid) response = await self.get_friend_relationships(client, principal_ids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_add_friend_by_principal_id(self, client, input, output): logger.info("FriendsServerV1.add_friend_by_principal_id()") #--- request --- friend_seed = input.u64() pid = input.pid() response = await self.add_friend_by_principal_id(client, friend_seed, pid) #--- response --- if not isinstance(response, FriendRelationship): raise RuntimeError("Expected FriendRelationship, got %s" %response.__class__.__name__) output.add(response) async def handle_add_friend_by_principal_ids(self, client, input, output): logger.info("FriendsServerV1.add_friend_by_principal_ids()") #--- request --- unk = input.u64() pids = input.list(input.pid) response = await self.add_friend_by_principal_ids(client, unk, pids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_remove_friend_by_local_friend_code(self, client, input, output): logger.info("FriendsServerV1.remove_friend_by_local_friend_code()") #--- request --- friend_code = input.u64() await self.remove_friend_by_local_friend_code(client, friend_code) async def handle_remove_friend_by_principal_id(self, client, input, output): logger.info("FriendsServerV1.remove_friend_by_principal_id()") #--- request --- pid = input.pid() await self.remove_friend_by_principal_id(client, pid) async def handle_get_all_friends(self, client, input, output): logger.info("FriendsServerV1.get_all_friends()") #--- request --- response = await self.get_all_friends(client) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_update_black_list(self, client, input, output): logger.info("FriendsServerV1.update_black_list()") #--- request --- unk = input.list(input.u32) await self.update_black_list(client, unk) async def handle_sync_friend(self, client, input, output): logger.info("FriendsServerV1.sync_friend()") #--- request --- friend_seed = input.u64() principal_ids = input.list(input.pid) unk = input.list(input.u64) response = await self.sync_friend(client, friend_seed, principal_ids, unk) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_update_presence(self, client, input, output): logger.info("FriendsServerV1.update_presence()") #--- request --- presence_info = input.extract(NintendoPresence) unk = input.bool() await self.update_presence(client, presence_info, unk) async def handle_update_favorite_game_key(self, client, input, output): logger.info("FriendsServerV1.update_favorite_game_key()") #--- request --- game_key = input.extract(GameKey) await self.update_favorite_game_key(client, game_key) async def handle_update_comment(self, client, input, output): logger.info("FriendsServerV1.update_comment()") #--- request --- comment = input.string() await self.update_comment(client, comment) async def handle_update_picture(self, client, input, output): logger.info("FriendsServerV1.update_picture()") #--- request --- unk = input.u32() picture = input.buffer() await self.update_picture(client, unk, picture) async def handle_get_friend_presence(self, client, input, output): logger.info("FriendsServerV1.get_friend_presence()") #--- request --- principal_ids = input.list(input.pid) response = await self.get_friend_presence(client, principal_ids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_friend_comment(self, client, input, output): logger.info("FriendsServerV1.get_friend_comment()") #--- request --- friends = input.list(FriendKey) response = await self.get_friend_comment(client, friends) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_friend_picture(self, client, input, output): logger.info("FriendsServerV1.get_friend_picture()") #--- request --- principal_ids = input.list(input.pid) response = await self.get_friend_picture(client, principal_ids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_friend_persistent_info(self, client, input, output): logger.info("FriendsServerV1.get_friend_persistent_info()") #--- request --- principal_ids = input.list(input.pid) response = await self.get_friend_persistent_info(client, principal_ids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_send_invitation(self, client, input, output): logger.info("FriendsServerV1.send_invitation()") #--- request --- unk = input.list(input.u32) await self.send_invitation(client, unk) async def update_profile(self, *args): logger.warning("FriendsServerV1.update_profile not implemented") raise common.RMCError("Core::NotImplemented") async def update_mii(self, *args): logger.warning("FriendsServerV1.update_mii not implemented") raise common.RMCError("Core::NotImplemented") async def update_mii_list(self, *args): logger.warning("FriendsServerV1.update_mii_list not implemented") raise common.RMCError("Core::NotImplemented") async def update_played_games(self, *args): logger.warning("FriendsServerV1.update_played_games not implemented") raise common.RMCError("Core::NotImplemented") async def update_preference(self, *args): logger.warning("FriendsServerV1.update_preference not implemented") raise common.RMCError("Core::NotImplemented") async def get_friend_mii(self, *args): logger.warning("FriendsServerV1.get_friend_mii not implemented") raise common.RMCError("Core::NotImplemented") async def get_friend_mii_list(self, *args): logger.warning("FriendsServerV1.get_friend_mii_list not implemented") raise common.RMCError("Core::NotImplemented") async def is_active_game(self, *args): logger.warning("FriendsServerV1.is_active_game not implemented") raise common.RMCError("Core::NotImplemented") async def get_principal_id_by_local_friend_code(self, *args): logger.warning("FriendsServerV1.get_principal_id_by_local_friend_code not implemented") raise common.RMCError("Core::NotImplemented") async def get_friend_relationships(self, *args): logger.warning("FriendsServerV1.get_friend_relationships not implemented") raise common.RMCError("Core::NotImplemented") async def add_friend_by_principal_id(self, *args): logger.warning("FriendsServerV1.add_friend_by_principal_id not implemented") raise common.RMCError("Core::NotImplemented") async def add_friend_by_principal_ids(self, *args): logger.warning("FriendsServerV1.add_friend_by_principal_ids not implemented") raise common.RMCError("Core::NotImplemented") async def remove_friend_by_local_friend_code(self, *args): logger.warning("FriendsServerV1.remove_friend_by_local_friend_code not implemented") raise common.RMCError("Core::NotImplemented") async def remove_friend_by_principal_id(self, *args): logger.warning("FriendsServerV1.remove_friend_by_principal_id not implemented") raise common.RMCError("Core::NotImplemented") async def get_all_friends(self, *args): logger.warning("FriendsServerV1.get_all_friends not implemented") raise common.RMCError("Core::NotImplemented") async def update_black_list(self, *args): logger.warning("FriendsServerV1.update_black_list not implemented") raise common.RMCError("Core::NotImplemented") async def sync_friend(self, *args): logger.warning("FriendsServerV1.sync_friend not implemented") raise common.RMCError("Core::NotImplemented") async def update_presence(self, *args): logger.warning("FriendsServerV1.update_presence not implemented") raise common.RMCError("Core::NotImplemented") async def update_favorite_game_key(self, *args): logger.warning("FriendsServerV1.update_favorite_game_key not implemented") raise common.RMCError("Core::NotImplemented") async def update_comment(self, *args): logger.warning("FriendsServerV1.update_comment not implemented") raise common.RMCError("Core::NotImplemented") async def update_picture(self, *args): logger.warning("FriendsServerV1.update_picture not implemented") raise common.RMCError("Core::NotImplemented") async def get_friend_presence(self, *args): logger.warning("FriendsServerV1.get_friend_presence not implemented") raise common.RMCError("Core::NotImplemented") async def get_friend_comment(self, *args): logger.warning("FriendsServerV1.get_friend_comment not implemented") raise common.RMCError("Core::NotImplemented") async def get_friend_picture(self, *args): logger.warning("FriendsServerV1.get_friend_picture not implemented") raise common.RMCError("Core::NotImplemented") async def get_friend_persistent_info(self, *args): logger.warning("FriendsServerV1.get_friend_persistent_info not implemented") raise common.RMCError("Core::NotImplemented") async def send_invitation(self, *args): logger.warning("FriendsServerV1.send_invitation not implemented") raise common.RMCError("Core::NotImplemented") class FriendsServerV2(FriendsProtocolV2): def __init__(self): self.methods = { self.METHOD_UPDATE_AND_GET_ALL_INFORMATION: self.handle_update_and_get_all_information, self.METHOD_ADD_FRIEND: self.handle_add_friend, self.METHOD_ADD_FRIEND_BY_NAME: self.handle_add_friend_by_name, self.METHOD_REMOVE_FRIEND: self.handle_remove_friend, self.METHOD_ADD_FRIEND_REQUEST: self.handle_add_friend_request, self.METHOD_CANCEL_FRIEND_REQUEST: self.handle_cancel_friend_request, self.METHOD_ACCEPT_FRIEND_REQUEST: self.handle_accept_friend_request, self.METHOD_DELETE_FRIEND_REQUEST: self.handle_delete_friend_request, self.METHOD_DENY_FRIEND_REQUEST: self.handle_deny_friend_request, self.METHOD_MARK_FRIEND_REQUESTS_AS_RECEIVED: self.handle_mark_friend_requests_as_received, self.METHOD_ADD_BLACK_LIST: self.handle_add_black_list, self.METHOD_REMOVE_BLACK_LIST: self.handle_remove_black_list, self.METHOD_UPDATE_PRESENCE: self.handle_update_presence, self.METHOD_UPDATE_MII: self.handle_update_mii, self.METHOD_UPDATE_COMMENT: self.handle_update_comment, self.METHOD_UPDATE_PREFERENCE: self.handle_update_preference, self.METHOD_GET_BASIC_INFO: self.handle_get_basic_info, self.METHOD_DELETE_PERSISTENT_NOTIFICATION: self.handle_delete_persistent_notification, self.METHOD_CHECK_SETTING_STATUS: self.handle_check_setting_status, self.METHOD_GET_REQUEST_BLOCK_SETTINGS: self.handle_get_request_block_settings, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on FriendsServerV2: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_update_and_get_all_information(self, client, input, output): logger.info("FriendsServerV2.update_and_get_all_information()") #--- request --- nna_info = input.extract(NNAInfo) presence = input.extract(NintendoPresenceV2) birthday = input.datetime() response = await self.update_and_get_all_information(client, nna_info, presence, birthday) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['principal_preference', 'comment', 'friends', 'sent_requests', 'received_requests', 'blacklist', 'unk1', 'notifications', 'unk2']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.add(response.principal_preference) output.add(response.comment) output.list(response.friends, output.add) output.list(response.sent_requests, output.add) output.list(response.received_requests, output.add) output.list(response.blacklist, output.add) output.bool(response.unk1) output.list(response.notifications, output.add) output.bool(response.unk2) async def handle_add_friend(self, client, input, output): logger.info("FriendsServerV2.add_friend()") #--- request --- pid = input.pid() response = await self.add_friend(client, pid) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['request', 'info']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.add(response.request) output.add(response.info) async def handle_add_friend_by_name(self, client, input, output): logger.info("FriendsServerV2.add_friend_by_name()") #--- request --- name = input.string() response = await self.add_friend_by_name(client, name) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['request', 'info']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.add(response.request) output.add(response.info) async def handle_remove_friend(self, client, input, output): logger.info("FriendsServerV2.remove_friend()") #--- request --- pid = input.pid() await self.remove_friend(client, pid) async def handle_add_friend_request(self, client, input, output): logger.info("FriendsServerV2.add_friend_request()") #--- request --- unk1 = input.u32() unk2 = input.u8() unk3 = input.string() unk4 = input.u8() unk5 = input.string() game_key = input.extract(GameKey) unk6 = input.datetime() response = await self.add_friend_request(client, unk1, unk2, unk3, unk4, unk5, game_key, unk6) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['request', 'info']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.add(response.request) output.add(response.info) async def handle_cancel_friend_request(self, client, input, output): logger.info("FriendsServerV2.cancel_friend_request()") #--- request --- id = input.u64() await self.cancel_friend_request(client, id) async def handle_accept_friend_request(self, client, input, output): logger.info("FriendsServerV2.accept_friend_request()") #--- request --- id = input.u64() response = await self.accept_friend_request(client, id) #--- response --- if not isinstance(response, FriendInfo): raise RuntimeError("Expected FriendInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_delete_friend_request(self, client, input, output): logger.info("FriendsServerV2.delete_friend_request()") #--- request --- id = input.u64() await self.delete_friend_request(client, id) async def handle_deny_friend_request(self, client, input, output): logger.info("FriendsServerV2.deny_friend_request()") #--- request --- id = input.u64() response = await self.deny_friend_request(client, id) #--- response --- if not isinstance(response, BlacklistedPrincipal): raise RuntimeError("Expected BlacklistedPrincipal, got %s" %response.__class__.__name__) output.add(response) async def handle_mark_friend_requests_as_received(self, client, input, output): logger.info("FriendsServerV2.mark_friend_requests_as_received()") #--- request --- ids = input.list(input.u64) await self.mark_friend_requests_as_received(client, ids) async def handle_add_black_list(self, client, input, output): logger.info("FriendsServerV2.add_black_list()") #--- request --- principal = input.extract(BlacklistedPrincipal) response = await self.add_black_list(client, principal) #--- response --- if not isinstance(response, BlacklistedPrincipal): raise RuntimeError("Expected BlacklistedPrincipal, got %s" %response.__class__.__name__) output.add(response) async def handle_remove_black_list(self, client, input, output): logger.info("FriendsServerV2.remove_black_list()") #--- request --- pid = input.pid() await self.remove_black_list(client, pid) async def handle_update_presence(self, client, input, output): logger.info("FriendsServerV2.update_presence()") #--- request --- presence = input.extract(NintendoPresenceV2) await self.update_presence(client, presence) async def handle_update_mii(self, client, input, output): logger.info("FriendsServerV2.update_mii()") #--- request --- mii = input.extract(MiiV2) response = await self.update_mii(client, mii) #--- response --- if not isinstance(response, common.DateTime): raise RuntimeError("Expected common.DateTime, got %s" %response.__class__.__name__) output.datetime(response) async def handle_update_comment(self, client, input, output): logger.info("FriendsServerV2.update_comment()") #--- request --- comment = input.extract(Comment) response = await self.update_comment(client, comment) #--- response --- if not isinstance(response, common.DateTime): raise RuntimeError("Expected common.DateTime, got %s" %response.__class__.__name__) output.datetime(response) async def handle_update_preference(self, client, input, output): logger.info("FriendsServerV2.update_preference()") #--- request --- preference = input.extract(PrincipalPreference) await self.update_preference(client, preference) async def handle_get_basic_info(self, client, input, output): logger.info("FriendsServerV2.get_basic_info()") #--- request --- pids = input.list(input.pid) response = await self.get_basic_info(client, pids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_delete_persistent_notification(self, client, input, output): logger.info("FriendsServerV2.delete_persistent_notification()") #--- request --- notifications = input.list(PersistentNotification) await self.delete_persistent_notification(client, notifications) async def handle_check_setting_status(self, client, input, output): logger.info("FriendsServerV2.check_setting_status()") #--- request --- response = await self.check_setting_status(client) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u8(response) async def handle_get_request_block_settings(self, client, input, output): logger.info("FriendsServerV2.get_request_block_settings()") #--- request --- unk = input.list(input.u32) response = await self.get_request_block_settings(client, unk) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def update_and_get_all_information(self, *args): logger.warning("FriendsServerV2.update_and_get_all_information not implemented") raise common.RMCError("Core::NotImplemented") async def add_friend(self, *args): logger.warning("FriendsServerV2.add_friend not implemented") raise common.RMCError("Core::NotImplemented") async def add_friend_by_name(self, *args): logger.warning("FriendsServerV2.add_friend_by_name not implemented") raise common.RMCError("Core::NotImplemented") async def remove_friend(self, *args): logger.warning("FriendsServerV2.remove_friend not implemented") raise common.RMCError("Core::NotImplemented") async def add_friend_request(self, *args): logger.warning("FriendsServerV2.add_friend_request not implemented") raise common.RMCError("Core::NotImplemented") async def cancel_friend_request(self, *args): logger.warning("FriendsServerV2.cancel_friend_request not implemented") raise common.RMCError("Core::NotImplemented") async def accept_friend_request(self, *args): logger.warning("FriendsServerV2.accept_friend_request not implemented") raise common.RMCError("Core::NotImplemented") async def delete_friend_request(self, *args): logger.warning("FriendsServerV2.delete_friend_request not implemented") raise common.RMCError("Core::NotImplemented") async def deny_friend_request(self, *args): logger.warning("FriendsServerV2.deny_friend_request not implemented") raise common.RMCError("Core::NotImplemented") async def mark_friend_requests_as_received(self, *args): logger.warning("FriendsServerV2.mark_friend_requests_as_received not implemented") raise common.RMCError("Core::NotImplemented") async def add_black_list(self, *args): logger.warning("FriendsServerV2.add_black_list not implemented") raise common.RMCError("Core::NotImplemented") async def remove_black_list(self, *args): logger.warning("FriendsServerV2.remove_black_list not implemented") raise common.RMCError("Core::NotImplemented") async def update_presence(self, *args): logger.warning("FriendsServerV2.update_presence not implemented") raise common.RMCError("Core::NotImplemented") async def update_mii(self, *args): logger.warning("FriendsServerV2.update_mii not implemented") raise common.RMCError("Core::NotImplemented") async def update_comment(self, *args): logger.warning("FriendsServerV2.update_comment not implemented") raise common.RMCError("Core::NotImplemented") async def update_preference(self, *args): logger.warning("FriendsServerV2.update_preference not implemented") raise common.RMCError("Core::NotImplemented") async def get_basic_info(self, *args): logger.warning("FriendsServerV2.get_basic_info not implemented") raise common.RMCError("Core::NotImplemented") async def delete_persistent_notification(self, *args): logger.warning("FriendsServerV2.delete_persistent_notification not implemented") raise common.RMCError("Core::NotImplemented") async def check_setting_status(self, *args): logger.warning("FriendsServerV2.check_setting_status not implemented") raise common.RMCError("Core::NotImplemented") async def get_request_block_settings(self, *args): logger.warning("FriendsServerV2.get_request_block_settings not implemented") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/health.py ================================================ # This file was generated automatically by generate_protocols.py from nintendo.nex import notification, rmc, common, streams import logging logger = logging.getLogger(__name__) class HealthProtocol: METHOD_PING_DAEMON = 1 METHOD_PING_DATABASE = 2 METHOD_RUN_SANITY_CHECK = 3 METHOD_FIX_SANITY_ERRORS = 4 PROTOCOL_ID = 0x12 class HealthClient(HealthProtocol): def __init__(self, client): self.settings = client.settings self.client = client async def ping_daemon(self): logger.info("HealthClient.ping_daemon()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PING_DAEMON, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("HealthClient.ping_daemon -> done") return result async def ping_database(self): logger.info("HealthClient.ping_database()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PING_DATABASE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("HealthClient.ping_database -> done") return result async def run_sanity_check(self): logger.info("HealthClient.run_sanity_check()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RUN_SANITY_CHECK, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("HealthClient.run_sanity_check -> done") return result async def fix_sanity_errors(self): logger.info("HealthClient.fix_sanity_errors()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIX_SANITY_ERRORS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("HealthClient.fix_sanity_errors -> done") return result class HealthServer(HealthProtocol): def __init__(self): self.methods = { self.METHOD_PING_DAEMON: self.handle_ping_daemon, self.METHOD_PING_DATABASE: self.handle_ping_database, self.METHOD_RUN_SANITY_CHECK: self.handle_run_sanity_check, self.METHOD_FIX_SANITY_ERRORS: self.handle_fix_sanity_errors, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on HealthServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_ping_daemon(self, client, input, output): logger.info("HealthServer.ping_daemon()") #--- request --- response = await self.ping_daemon(client) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_ping_database(self, client, input, output): logger.info("HealthServer.ping_database()") #--- request --- response = await self.ping_database(client) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_run_sanity_check(self, client, input, output): logger.info("HealthServer.run_sanity_check()") #--- request --- response = await self.run_sanity_check(client) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_fix_sanity_errors(self, client, input, output): logger.info("HealthServer.fix_sanity_errors()") #--- request --- response = await self.fix_sanity_errors(client) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def ping_daemon(self, *args): logger.warning("HealthServer.ping_daemon not implemented") raise common.RMCError("Core::NotImplemented") async def ping_database(self, *args): logger.warning("HealthServer.ping_database not implemented") raise common.RMCError("Core::NotImplemented") async def run_sanity_check(self, *args): logger.warning("HealthServer.run_sanity_check not implemented") raise common.RMCError("Core::NotImplemented") async def fix_sanity_errors(self, *args): logger.warning("HealthServer.fix_sanity_errors not implemented") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/hpp.py ================================================ from anynet import http, tls from nintendo import resources from nintendo.nex import common, kerberos, rmc, streams import hashlib import hmac import secrets class HppClient: def __init__(self, settings, game_server_id, nex_version, pid, password): self.settings = settings self.game_server_id = game_server_id self.nex_version = nex_version self.pid = pid self.password = password self.environment = "L1" self.key_derivation = kerberos.KeyDerivationOld(65000, 1024) self.call_id = 1 ca = resources.certificate("Nintendo_Class_2_CA_G3.der") self.context = tls.TLSContext() self.context.set_authority(ca) def set_environment(self, env): self.environment = env def host(self): return "hpp-%08x-%s.n.app.nintendo.net" %(self.game_server_id, self.environment.lower()) async def request(self, protocol, method, body): call_id = self.call_id self.call_id = (call_id + 1) & 0xFFFFFFFF message = rmc.RMCMessage.request(self.settings, protocol, method, call_id, body) data = message.encode() key1 = bytes.fromhex(self.settings["prudp.access_key"]).ljust(8, b"\0") key2 = self.key_derivation.derive_key(self.password.encode(), self.pid) signature1 = hmac.new(key1, data, hashlib.md5).hexdigest() signature2 = hmac.new(key2, data, hashlib.md5).hexdigest() random = secrets.token_hex(8).upper() req = http.HTTPRequest.post("https://%s/hpp/" %self.host()) req.headers["Host"] = self.host() req.headers["pid"] = str(self.pid) req.headers["version"] = self.nex_version req.headers["token"] = "normaltoken" req.headers["signature1"] = signature1.upper() req.headers["signature2"] = signature2.upper() req.headers["Content-Type"] = "multipart/form-data" req.headers["Content-Length"] = 0 req.boundary = "--------BOUNDARY--------" + random req.files = {"file": data} response = await http.request(self.host(), req, self.context) if response.error(): raise ValueError("Hpp request failed with status %i" %response.status_code) stream = streams.StreamIn(response.body, self.settings) if stream.u32() != stream.available(): raise ValueError("Hpp response has unexpected size") success = stream.bool() if not success: error = stream.u32() if call_id != stream.u32(): raise ValueError("Hpp error response has unexpected call id") if not stream.eof(): raise ValueError("Hpp error response is bigger than expected") raise common.RMCError(error) if call_id != stream.u32(): raise ValueError("Hpp response has unexpected call id") method_id = stream.u32() if method_id != method | 0x8000: raise ValueError("Hpp response has unexpected method id") return stream.readall() ================================================ FILE: nintendo/nex/kerberos.py ================================================ from Crypto.Cipher import ARC4 from nintendo.nex import streams import struct import secrets import hashlib import hmac class KeyDerivationOld: def __init__(self, base_count = 65000, pid_count = 1024): self.base_count = base_count self.pid_count = pid_count def derive_key(self, password, pid): key = password for i in range(self.base_count + pid % self.pid_count): key = hashlib.md5(key).digest() return key class KeyDerivationNew: def __init__(self, base_count = 1, pid_count = 1): self.base_count = base_count self.pid_count = pid_count def derive_key(self, password, pid): key = password for i in range(self.base_count): key = hashlib.md5(key).digest() key += struct.pack("= 30500: pass if settings["nex.version"] >= 40000: pass def load(self, stream, version): self.attribs = stream.list(stream.string) self.game_mode = stream.string() self.min_participants = stream.string() self.max_participants = stream.string() self.matchmake_system = stream.string() self.vacant_only = stream.bool() self.exclude_locked = stream.bool() self.exclude_non_host_pid = stream.bool() self.selection_method = stream.u32() if stream.settings["nex.version"] >= 30500: self.vacant_participants = stream.u16() if stream.settings["nex.version"] >= 40000: self.param = stream.extract(MatchmakeParam) self.exclude_user_password = stream.bool() self.exclude_system_password = stream.bool() self.refer_gid = stream.u32() self.codeword = stream.string() self.range = stream.extract(common.ResultRange) def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.attribs, stream.string) stream.string(self.game_mode) stream.string(self.min_participants) stream.string(self.max_participants) stream.string(self.matchmake_system) stream.bool(self.vacant_only) stream.bool(self.exclude_locked) stream.bool(self.exclude_non_host_pid) stream.u32(self.selection_method) if stream.settings["nex.version"] >= 30500: stream.u16(self.vacant_participants) if stream.settings["nex.version"] >= 40000: stream.add(self.param) stream.bool(self.exclude_user_password) stream.bool(self.exclude_system_password) stream.u32(self.refer_gid) stream.string(self.codeword) stream.add(self.range) class MatchmakeSession(Gathering): def __init__(self): super().__init__() self.game_mode = 0 self.attribs = [0, 0, 0, 0, 0, 0] self.open_participation = True self.matchmake_system = 0 self.application_data = b"" self.num_participants = 0 self.progress_score = 100 self.session_key = b"" self.option = 0 self.param = MatchmakeParam() self.started_time = common.DateTime(0) self.user_password = "" self.refer_gid = 0 self.user_password_enabled = False self.system_password_enabled = False self.codeword = "" def max_version(self, settings): version = 0 if 30000 <= settings["nex.version"] < 40000: if settings["nex.version"] >= 30600: version = 1 if settings["nex.version"] >= 30700: version = 2 if settings["nex.version"] >= 30800: version = 3 return version def check_required(self, settings, version): if 30000 <= settings["nex.version"] < 40000: if settings["nex.version"] >= 30500: pass if settings["nex.version"] >= 30000: pass if settings["nex.version"] >= 30500: pass if settings["nex.version"] >= 30600: if version >= 1: pass if settings["nex.version"] >= 30700: if version >= 2: pass if settings["nex.version"] >= 30800: if version >= 3: pass if settings["nex.version"] >= 40000: pass def load(self, stream, version): self.game_mode = stream.u32() self.attribs = stream.list(stream.u32) self.open_participation = stream.bool() self.matchmake_system = stream.u32() self.application_data = stream.buffer() self.num_participants = stream.u32() if 30000 <= stream.settings["nex.version"] < 40000: if stream.settings["nex.version"] >= 30500: self.progress_score = stream.u8() if stream.settings["nex.version"] >= 30000: self.session_key = stream.buffer() if stream.settings["nex.version"] >= 30500: self.option = stream.u32() if stream.settings["nex.version"] >= 30600: if version >= 1: self.param = stream.extract(MatchmakeParam) self.started_time = stream.datetime() if stream.settings["nex.version"] >= 30700: if version >= 2: self.user_password = stream.string() if stream.settings["nex.version"] >= 30800: if version >= 3: self.refer_gid = stream.u32() self.user_password_enabled = stream.bool() self.system_password_enabled = stream.bool() if stream.settings["nex.version"] >= 40000: self.progress_score = stream.u8() self.session_key = stream.buffer() self.option = stream.u32() self.param = stream.extract(MatchmakeParam) self.started_time = stream.datetime() self.user_password = stream.string() self.refer_gid = stream.u32() self.user_password_enabled = stream.bool() self.system_password_enabled = stream.bool() self.codeword = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.game_mode) stream.list(self.attribs, stream.u32) stream.bool(self.open_participation) stream.u32(self.matchmake_system) stream.buffer(self.application_data) stream.u32(self.num_participants) if 30000 <= stream.settings["nex.version"] < 40000: if stream.settings["nex.version"] >= 30500: stream.u8(self.progress_score) if stream.settings["nex.version"] >= 30000: stream.buffer(self.session_key) if stream.settings["nex.version"] >= 30500: stream.u32(self.option) if stream.settings["nex.version"] >= 30600: if version >= 1: stream.add(self.param) stream.datetime(self.started_time) if stream.settings["nex.version"] >= 30700: if version >= 2: stream.string(self.user_password) if stream.settings["nex.version"] >= 30800: if version >= 3: stream.u32(self.refer_gid) stream.bool(self.user_password_enabled) stream.bool(self.system_password_enabled) if stream.settings["nex.version"] >= 40000: stream.u8(self.progress_score) stream.buffer(self.session_key) stream.u32(self.option) stream.add(self.param) stream.datetime(self.started_time) stream.string(self.user_password) stream.u32(self.refer_gid) stream.bool(self.user_password_enabled) stream.bool(self.system_password_enabled) stream.string(self.codeword) common.DataHolder.register(MatchmakeSession, "MatchmakeSession") class MatchmakeBlockListParam(common.Structure): def __init__(self): super().__init__() self.options = 0 def check_required(self, settings, version): pass def load(self, stream, version): self.options = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.options) class CreateMatchmakeSessionParam(common.Structure): def __init__(self): super().__init__() self.session = MatchmakeSession() self.additional_participants = None self.gid_for_participation_check = None self.options = None self.join_message = None self.num_participants = None def check_required(self, settings, version): for field in ['additional_participants', 'gid_for_participation_check', 'options', 'join_message', 'num_participants']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.session = stream.extract(MatchmakeSession) self.additional_participants = stream.list(stream.pid) self.gid_for_participation_check = stream.u32() self.options = stream.u32() self.join_message = stream.string() self.num_participants = stream.u16() def save(self, stream, version): self.check_required(stream.settings, version) stream.add(self.session) stream.list(self.additional_participants, stream.pid) stream.u32(self.gid_for_participation_check) stream.u32(self.options) stream.string(self.join_message) stream.u16(self.num_participants) class JoinMatchmakeSessionParam(common.Structure): def __init__(self): super().__init__() self.gid = None self.participants = None self.gid_for_participation_check = None self.options = None self.behavior = None self.user_password = None self.system_password = None self.join_message = None self.num_participants = None self.extra_participants = None self.block_list = MatchmakeBlockListParam() def check_required(self, settings, version): for field in ['gid', 'participants', 'gid_for_participation_check', 'options', 'behavior', 'user_password', 'system_password', 'join_message', 'num_participants', 'extra_participants']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.gid = stream.u32() self.participants = stream.list(stream.pid) self.gid_for_participation_check = stream.u32() self.options = stream.u32() self.behavior = stream.u8() self.user_password = stream.string() self.system_password = stream.string() self.join_message = stream.string() self.num_participants = stream.u16() self.extra_participants = stream.u16() self.block_list = stream.extract(MatchmakeBlockListParam) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.gid) stream.list(self.participants, stream.pid) stream.u32(self.gid_for_participation_check) stream.u32(self.options) stream.u8(self.behavior) stream.string(self.user_password) stream.string(self.system_password) stream.string(self.join_message) stream.u16(self.num_participants) stream.u16(self.extra_participants) stream.add(self.block_list) class UpdateMatchmakeSessionParam(common.Structure): def __init__(self): super().__init__() self.gid = None self.modification_flags = None self.attributes = None self.open_participation = None self.application_buffer = None self.progress_score = None self.param = MatchmakeParam() self.started_time = None self.user_password = None self.game_mode = None self.description = None self.min_participants = None self.max_participants = None self.matchmake_system = None self.participation_policy = None self.policy_argument = None self.codeword = None def check_required(self, settings, version): for field in ['gid', 'modification_flags', 'attributes', 'open_participation', 'application_buffer', 'progress_score', 'started_time', 'user_password', 'game_mode', 'description', 'min_participants', 'max_participants', 'matchmake_system', 'participation_policy', 'policy_argument', 'codeword']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.gid = stream.u32() self.modification_flags = stream.u32() self.attributes = stream.list(stream.u32) self.open_participation = stream.bool() self.application_buffer = stream.buffer() self.progress_score = stream.u8() self.param = stream.extract(MatchmakeParam) self.started_time = stream.datetime() self.user_password = stream.string() self.game_mode = stream.u32() self.description = stream.string() self.min_participants = stream.u16() self.max_participants = stream.u16() self.matchmake_system = stream.u32() self.participation_policy = stream.u32() self.policy_argument = stream.u32() self.codeword = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.gid) stream.u32(self.modification_flags) stream.list(self.attributes, stream.u32) stream.bool(self.open_participation) stream.buffer(self.application_buffer) stream.u8(self.progress_score) stream.add(self.param) stream.datetime(self.started_time) stream.string(self.user_password) stream.u32(self.game_mode) stream.string(self.description) stream.u16(self.min_participants) stream.u16(self.max_participants) stream.u32(self.matchmake_system) stream.u32(self.participation_policy) stream.u32(self.policy_argument) stream.string(self.codeword) class AutoMatchmakeParam(common.Structure): def __init__(self): super().__init__() self.session = MatchmakeSession() self.participants = None self.gid_for_participation_check = None self.options = None self.join_message = None self.num_participants = None self.search_criteria = None self.target_gids = None self.block_list = MatchmakeBlockListParam() def check_required(self, settings, version): for field in ['participants', 'gid_for_participation_check', 'options', 'join_message', 'num_participants', 'search_criteria', 'target_gids']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.session = stream.extract(MatchmakeSession) self.participants = stream.list(stream.pid) self.gid_for_participation_check = stream.u32() self.options = stream.u32() self.join_message = stream.string() self.num_participants = stream.u16() self.search_criteria = stream.list(MatchmakeSessionSearchCriteria) self.target_gids = stream.list(stream.u32) self.block_list = stream.extract(MatchmakeBlockListParam) def save(self, stream, version): self.check_required(stream.settings, version) stream.add(self.session) stream.list(self.participants, stream.pid) stream.u32(self.gid_for_participation_check) stream.u32(self.options) stream.string(self.join_message) stream.u16(self.num_participants) stream.list(self.search_criteria, stream.add) stream.list(self.target_gids, stream.u32) stream.add(self.block_list) class FindMatchmakeSessionByParticipantParam(common.Structure): def __init__(self): super().__init__() self.pids = None self.options = None self.block_list = MatchmakeBlockListParam() def check_required(self, settings, version): for field in ['pids', 'options']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pids = stream.list(stream.pid) self.options = stream.u32() self.block_list = stream.extract(MatchmakeBlockListParam) def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.pids, stream.pid) stream.u32(self.options) stream.add(self.block_list) class FindMatchmakeSessionByParticipantResult(common.Structure): def __init__(self): super().__init__() self.pid = None self.session = MatchmakeSession() def check_required(self, settings, version): for field in ['pid']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.session = stream.extract(MatchmakeSession) def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.add(self.session) class PersistentGathering(Gathering): def __init__(self): super().__init__() self.type = None self.password = None self.attribs = None self.application_buffer = None self.participation_start = None self.participation_end = None self.matchmake_session_count = None self.num_participants = None def check_required(self, settings, version): for field in ['type', 'password', 'attribs', 'application_buffer', 'participation_start', 'participation_end', 'matchmake_session_count', 'num_participants']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.type = stream.u32() self.password = stream.string() self.attribs = stream.list(stream.u32) self.application_buffer = stream.buffer() self.participation_start = stream.datetime() self.participation_end = stream.datetime() self.matchmake_session_count = stream.u32() self.num_participants = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.type) stream.string(self.password) stream.list(self.attribs, stream.u32) stream.buffer(self.application_buffer) stream.datetime(self.participation_start) stream.datetime(self.participation_end) stream.u32(self.matchmake_session_count) stream.u32(self.num_participants) common.DataHolder.register(PersistentGathering, "PersistentGathering") class SimpleCommunity(common.Structure): def __init__(self): super().__init__() self.gid = None self.matchmake_session_count = None def check_required(self, settings, version): for field in ['gid', 'matchmake_session_count']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.gid = stream.u32() self.matchmake_session_count = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.gid) stream.u32(self.matchmake_session_count) class PlayingSession(common.Structure): def __init__(self): super().__init__() self.pid = None self.gathering = None def check_required(self, settings, version): for field in ['pid', 'gathering']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.gathering = stream.anydata() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.anydata(self.gathering) class SimplePlayingSession(common.Structure): def __init__(self): super().__init__() self.pid = None self.gid = None self.game_mode = None self.attribute = None def check_required(self, settings, version): for field in ['pid', 'gid', 'game_mode', 'attribute']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.gid = stream.u32() self.game_mode = stream.u32() self.attribute = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.u32(self.gid) stream.u32(self.game_mode) stream.u32(self.attribute) class MatchmakeRefereeRound(common.Structure): def __init__(self): super().__init__() self.id = None self.gid = None self.state = None self.personal_data_category = None self.results = None def check_required(self, settings, version): for field in ['id', 'gid', 'state', 'personal_data_category', 'results']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.id = stream.u64() self.gid = stream.u32() self.state = stream.u32() self.personal_data_category = stream.u32() self.results = stream.list(MatchmakeRefereePersonalRoundResult) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.id) stream.u32(self.gid) stream.u32(self.state) stream.u32(self.personal_data_category) stream.list(self.results, stream.add) class MatchmakeRefereeStartRoundParam(common.Structure): def __init__(self): super().__init__() self.personal_data_category = None self.gid = None self.pids = None def check_required(self, settings, version): for field in ['personal_data_category', 'gid', 'pids']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.personal_data_category = stream.u32() self.gid = stream.u32() self.pids = stream.list(stream.pid) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.personal_data_category) stream.u32(self.gid) stream.list(self.pids, stream.pid) class MatchmakeRefereeEndRoundParam(common.Structure): def __init__(self): super().__init__() self.round_id = None self.results = None def check_required(self, settings, version): for field in ['round_id', 'results']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.round_id = stream.u64() self.results = stream.list(MatchmakeRefereePersonalRoundResult) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.round_id) stream.list(self.results, stream.add) class MatchmakeRefereePersonalRoundResult(common.Structure): def __init__(self): super().__init__() self.pid = None self.personal_round_result_flag = None self.round_win_loss = None self.rating_change = None self.buffer = None def check_required(self, settings, version): for field in ['pid', 'personal_round_result_flag', 'round_win_loss', 'rating_change', 'buffer']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.personal_round_result_flag = stream.u32() self.round_win_loss = stream.u32() self.rating_change = stream.s32() self.buffer = stream.qbuffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.u32(self.personal_round_result_flag) stream.u32(self.round_win_loss) stream.s32(self.rating_change) stream.qbuffer(self.buffer) class MatchmakeRefereeStats(common.Structure): def __init__(self): super().__init__() self.unique_id = None self.category = None self.pid = None self.recent_disconnection = None self.recent_violation = None self.recent_mismatch = None self.recent_win = None self.recent_loss = None self.recent_draw = None self.total_disconnect = None self.total_violation = None self.total_mismatch = None self.total_win = None self.total_loss = None self.total_draw = None self.rating_value = None def check_required(self, settings, version): for field in ['unique_id', 'category', 'pid', 'recent_disconnection', 'recent_violation', 'recent_mismatch', 'recent_win', 'recent_loss', 'recent_draw', 'total_disconnect', 'total_violation', 'total_mismatch', 'total_win', 'total_loss', 'total_draw', 'rating_value']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.unique_id = stream.u64() self.category = stream.u32() self.pid = stream.pid() self.recent_disconnection = stream.u32() self.recent_violation = stream.u32() self.recent_mismatch = stream.u32() self.recent_win = stream.u32() self.recent_loss = stream.u32() self.recent_draw = stream.u32() self.total_disconnect = stream.u32() self.total_violation = stream.u32() self.total_mismatch = stream.u32() self.total_win = stream.u32() self.total_loss = stream.u32() self.total_draw = stream.u32() self.rating_value = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.unique_id) stream.u32(self.category) stream.pid(self.pid) stream.u32(self.recent_disconnection) stream.u32(self.recent_violation) stream.u32(self.recent_mismatch) stream.u32(self.recent_win) stream.u32(self.recent_loss) stream.u32(self.recent_draw) stream.u32(self.total_disconnect) stream.u32(self.total_violation) stream.u32(self.total_mismatch) stream.u32(self.total_win) stream.u32(self.total_loss) stream.u32(self.total_draw) stream.u32(self.rating_value) class MatchmakeRefereeStatsTarget(common.Structure): def __init__(self): super().__init__() self.pid = None self.category = None def check_required(self, settings, version): for field in ['pid', 'category']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.category = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.u32(self.category) class MatchmakeRefereeStatsInitParam(common.Structure): def __init__(self): super().__init__() self.category = None self.initial_rating = None def check_required(self, settings, version): for field in ['category', 'initial_rating']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.category = stream.u32() self.initial_rating = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.category) stream.u32(self.initial_rating) class MatchMakingProtocol: METHOD_REGISTER_GATHERING = 1 METHOD_UNREGISTER_GATHERING = 2 METHOD_UNREGISTER_GATHERINGS = 3 METHOD_UPDATE_GATHERING = 4 METHOD_INVITE = 5 METHOD_ACCEPT_INVITATION = 6 METHOD_DECLINE_INVITATION = 7 METHOD_CANCEL_INVITATION = 8 METHOD_GET_INVITATIONS_SENT = 9 METHOD_GET_INVITATIONS_RECEIVED = 10 METHOD_PARTICIPATE = 11 METHOD_CANCEL_PARTICIPATION = 12 METHOD_GET_PARTICIPANTS = 13 METHOD_ADD_PARTICIPANTS = 14 METHOD_GET_DETAILED_PARTICIPANTS = 15 METHOD_GET_PARTICIPANTS_URLS = 16 METHOD_FIND_BY_TYPE = 17 METHOD_FIND_BY_DESCRIPTION = 18 METHOD_FIND_BY_DESCRIPTION_REGEX = 19 METHOD_FIND_BY_ID = 20 METHOD_FIND_BY_SINGLE_ID = 21 METHOD_FIND_BY_OWNER = 22 METHOD_FIND_BY_PARTICIPANTS = 23 METHOD_FIND_INVITATIONS = 24 METHOD_FIND_BY_SQL_QUERY = 25 METHOD_LAUNCH_SESSION = 26 METHOD_UPDATE_SESSION_URL = 27 METHOD_GET_SESSION_URL = 28 METHOD_GET_STATE = 29 METHOD_SET_STATE = 30 METHOD_REPORT_STATS = 31 METHOD_GET_STATS = 32 METHOD_DELETE_GATHERING = 33 METHOD_GET_PENDING_DELETIONS = 34 METHOD_DELETE_FROM_DELETIONS = 35 METHOD_MIGRATE_GATHERING_OWNERSHIP_V1 = 36 METHOD_FIND_BY_DESCRIPTION_LIKE = 37 METHOD_REGISTER_LOCAL_URL = 38 METHOD_REGISTER_LOCAL_URLS = 39 METHOD_UPDATE_SESSION_HOST_V1 = 40 METHOD_GET_SESSION_URLS = 41 METHOD_UPDATE_SESSION_HOST = 42 METHOD_UPDATE_GATHERING_OWNERSHIP = 43 METHOD_MIGRATE_GATHERING_OWNERSHIP = 44 PROTOCOL_ID = 0x15 class MatchMakingProtocolExt: METHOD_END_PARTICIPATION = 1 METHOD_GET_PARTICIPANTS = 2 METHOD_GET_DETAILED_PARTICIPANTS = 3 METHOD_GET_PARTICIPANTS_URLS = 4 METHOD_GET_GATHERING_RELATIONS = 5 METHOD_DELETE_FROM_DELETIONS = 6 PROTOCOL_ID = 0x32 class MatchmakeExtensionProtocol: METHOD_CLOSE_PARTICIPATION = 1 METHOD_OPEN_PARTICIPATION = 2 METHOD_AUTO_MATCHMAKE_POSTPONE = 3 METHOD_BROWSE_MATCHMAKE_SESSION = 4 METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS = 5 METHOD_CREATE_MATCHMAKE_SESSION = 6 METHOD_JOIN_MATCHMAKE_SESSION = 7 METHOD_MODIFY_CURRENT_GAME_ATTRIBUTE = 8 METHOD_UPDATE_NOTIFICATION_DATA = 9 METHOD_GET_FRIEND_NOTIFICATION_DATA = 10 METHOD_UPDATE_APPLICATION_BUFFER = 11 METHOD_UPDATE_MATCHMAKE_SESSION_ATTRIBUTE = 12 METHOD_GET_FRIEND_NOTIFICATION_DATA_LIST = 13 METHOD_UPDATE_MATCHMAKE_SESSION = 14 METHOD_AUTO_MATCHMAKE_WITH_SEARCH_CRITERIA_POSTPONE = 15 METHOD_GET_PLAYING_SESSION = 16 METHOD_CREATE_COMMUNITY = 17 METHOD_UPDATE_COMMUNITY = 18 METHOD_JOIN_COMMUNITY = 19 METHOD_FIND_COMMUNITY_BY_GATHERING_ID = 20 METHOD_FIND_OFFICIAL_COMMUNITY = 21 METHOD_FIND_COMMUNITY_BY_PARTICIPANT = 22 METHOD_UPDATE_PRIVACY_SETTING = 23 METHOD_GET_MY_BLOCK_LIST = 24 METHOD_ADD_TO_BLOCK_LIST = 25 METHOD_REMOVE_FROM_BLOCK_LIST = 26 METHOD_CLEAR_MY_BLOCK_LIST = 27 METHOD_REPORT_VIOLATION = 28 METHOD_IS_VIOLATION_USER = 29 METHOD_JOIN_MATCHMAKE_SESSION_EX = 30 METHOD_GET_SIMPLE_PLAYING_SESSION = 31 METHOD_GET_SIMPLE_COMMUNITY = 32 METHOD_AUTO_MATCHMAKE_WITH_GATHERING_ID_POSTPONE = 33 METHOD_UPDATE_PROGRESS_SCORE = 34 METHOD_DEBUG_NOTIFY_EVENT = 35 METHOD_GENERATE_MATCHMAKE_SESSION_SYSTEM_PASSWORD = 36 METHOD_CLEAR_MATCHMAKE_SESSION_SYSTEM_PASSWORD = 37 METHOD_CREATE_MATCHMAKE_SESSION_WITH_PARAM = 38 METHOD_JOIN_MATCHMAKE_SESSION_WITH_PARAM = 39 METHOD_AUTO_MATCHMAKE_WITH_PARAM_POSTPONE = 40 METHOD_FIND_MATCHMAKE_SESSION_BY_GATHERING_ID_DETAIL = 41 METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER = 42 METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER = 43 METHOD_UPDATE_MATCHMAKE_SESSION_PART = 44 METHOD_REQUEST_MATCHMAKING = 45 METHOD_WITHDRAW_MATCHMAKING = 46 METHOD_WITHDRAW_MATCHMAKING_ALL = 47 METHOD_FIND_MATCHMAKE_SESSION_BY_GATHERING_ID = 48 METHOD_FIND_MATCHMAKE_SESSION_BY_SINGLE_GATHERING_ID = 49 METHOD_FIND_MATCHMAKE_SESSION_BY_OWNER = 50 METHOD_FIND_MATCHMAKE_SESSION_BY_PARTICIPANT = 51 METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER_NO_RESULT_RANGE = 52 METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER_NO_RESULT_RANGE = 53 PROTOCOL_ID = 0x6D class MatchmakeRefereeProtocol: METHOD_START_ROUND = 1 METHOD_GET_START_ROUND_PARAM = 2 METHOD_END_ROUND = 3 METHOD_END_ROUND_WITHOUT_REPORT = 4 METHOD_GET_ROUND_PARTICIPANTS = 5 METHOD_GET_NOT_SUMMARIZED_ROUND = 6 METHOD_GET_ROUND = 7 METHOD_GET_STATS_PRIMARY = 8 METHOD_GET_STATS_PRIMARIES = 9 METHOD_GET_STATS_ALL = 10 METHOD_CREATE_STATS = 11 METHOD_GET_OR_CREATE_STATS = 12 METHOD_RESET_STATS = 13 PROTOCOL_ID = 0x78 class MatchMakingClient(MatchMakingProtocol): def __init__(self, client): self.settings = client.settings self.client = client async def register_gathering(self, gathering): logger.info("MatchMakingClient.register_gathering()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(gathering) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REGISTER_GATHERING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gid = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.register_gathering -> done") return gid async def unregister_gathering(self, gid): logger.info("MatchMakingClient.unregister_gathering()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UNREGISTER_GATHERING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.unregister_gathering -> done") return result async def unregister_gatherings(self, gids): logger.info("MatchMakingClient.unregister_gatherings()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UNREGISTER_GATHERINGS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.unregister_gatherings -> done") return result async def update_gathering(self, gathering): logger.info("MatchMakingClient.update_gathering()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(gathering) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_GATHERING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.update_gathering -> done") return result async def invite(self, gid, pids, message): logger.info("MatchMakingClient.invite()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(pids, stream.pid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_INVITE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.invite -> done") return result async def accept_invitation(self, gid, message): logger.info("MatchMakingClient.accept_invitation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_ACCEPT_INVITATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.accept_invitation -> done") return result async def decline_invitation(self, gid, message): logger.info("MatchMakingClient.decline_invitation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DECLINE_INVITATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.decline_invitation -> done") return result async def cancel_invitation(self, gid, pids, message): logger.info("MatchMakingClient.cancel_invitation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(pids, stream.pid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CANCEL_INVITATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.cancel_invitation -> done") return result async def get_invitations_sent(self, gid): logger.info("MatchMakingClient.get_invitations_sent()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_INVITATIONS_SENT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) invitations = stream.list(Invitation) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_invitations_sent -> done") return invitations async def get_invitations_received(self): logger.info("MatchMakingClient.get_invitations_received()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_INVITATIONS_RECEIVED, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) invitations = stream.list(Invitation) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_invitations_received -> done") return invitations async def participate(self, gid, message): logger.info("MatchMakingClient.participate()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PARTICIPATE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.participate -> done") return result async def cancel_participation(self, gid, message): logger.info("MatchMakingClient.cancel_participation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CANCEL_PARTICIPATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.cancel_participation -> done") return result async def get_participants(self, gid): logger.info("MatchMakingClient.get_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) participants = stream.list(stream.pid) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_participants -> done") return participants async def add_participants(self, gid, pids, message): logger.info("MatchMakingClient.add_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(pids, stream.pid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_ADD_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.add_participants -> done") return result async def get_detailed_participants(self, gid): logger.info("MatchMakingClient.get_detailed_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_DETAILED_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) details = stream.list(ParticipantDetails) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_detailed_participants -> done") return details async def get_participants_urls(self, gid): logger.info("MatchMakingClient.get_participants_urls()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PARTICIPANTS_URLS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) urls = stream.list(stream.stationurl) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_participants_urls -> done") return urls async def find_by_type(self, type, range): logger.info("MatchMakingClient.find_by_type()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(type) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_TYPE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_type -> done") return gatherings async def find_by_description(self, description, range): logger.info("MatchMakingClient.find_by_description()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(description) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_DESCRIPTION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_description -> done") return gatherings async def find_by_description_regex(self, regex, range): logger.info("MatchMakingClient.find_by_description_regex()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(regex) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_DESCRIPTION_REGEX, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_description_regex -> done") return gatherings async def find_by_id(self, ids): logger.info("MatchMakingClient.find_by_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(ids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_id -> done") return gatherings async def find_by_single_id(self, gid): logger.info("MatchMakingClient.find_by_single_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_SINGLE_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.gathering = stream.anydata() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_single_id -> done") return obj async def find_by_owner(self, owner, range): logger.info("MatchMakingClient.find_by_owner()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(owner) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_OWNER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_owner -> done") return gatherings async def find_by_participants(self, pids): logger.info("MatchMakingClient.find_by_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_participants -> done") return gatherings async def find_invitations(self, range): logger.info("MatchMakingClient.find_invitations()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_INVITATIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_invitations -> done") return gatherings async def find_by_sql_query(self, query, range): logger.info("MatchMakingClient.find_by_sql_query()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(query) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_SQL_QUERY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_sql_query -> done") return gatherings async def launch_session(self, gid, url): logger.info("MatchMakingClient.launch_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(url) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_LAUNCH_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.launch_session -> done") return result async def update_session_url(self, gid, url): logger.info("MatchMakingClient.update_session_url()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(url) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_SESSION_URL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.update_session_url -> done") return result async def get_session_url(self, gid): logger.info("MatchMakingClient.get_session_url()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SESSION_URL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.url = stream.string() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_session_url -> done") return obj async def get_state(self, gid): logger.info("MatchMakingClient.get_state()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.state = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_state -> done") return obj async def set_state(self, gid, state): logger.info("MatchMakingClient.set_state()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.u32(state) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SET_STATE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.set_state -> done") return result async def report_stats(self, gid, stats): logger.info("MatchMakingClient.report_stats()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(stats, stream.add) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REPORT_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.report_stats -> done") return result async def get_stats(self, gid, pids, columns): logger.info("MatchMakingClient.get_stats()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(pids, stream.pid) stream.list(columns, stream.u8) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.stats = stream.list(GatheringStats) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_stats -> done") return obj async def delete_gathering(self, gid): logger.info("MatchMakingClient.delete_gathering()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_GATHERING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.delete_gathering -> done") return result async def get_pending_deletions(self, reason, range): logger.info("MatchMakingClient.get_pending_deletions()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(reason) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PENDING_DELETIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.deletions = stream.list(DeletionEntry) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_pending_deletions -> done") return obj async def delete_from_deletions(self, deletions): logger.info("MatchMakingClient.delete_from_deletions()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(deletions, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_FROM_DELETIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.delete_from_deletions -> done") return result async def migrate_gathering_ownership_v1(self, gid, potential_owners): logger.info("MatchMakingClient.migrate_gathering_ownership_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(potential_owners, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_MIGRATE_GATHERING_OWNERSHIP_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.migrate_gathering_ownership_v1 -> done") return result async def find_by_description_like(self, description, range): logger.info("MatchMakingClient.find_by_description_like()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(description) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_DESCRIPTION_LIKE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_description_like -> done") return gatherings async def register_local_url(self, gid, url): logger.info("MatchMakingClient.register_local_url()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.stationurl(url) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REGISTER_LOCAL_URL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.register_local_url -> done") async def register_local_urls(self, gid, urls): logger.info("MatchMakingClient.register_local_urls()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(urls, stream.stationurl) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REGISTER_LOCAL_URLS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.register_local_urls -> done") async def update_session_host_v1(self, gid): logger.info("MatchMakingClient.update_session_host_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_SESSION_HOST_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.update_session_host_v1 -> done") async def get_session_urls(self, gid): logger.info("MatchMakingClient.get_session_urls()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SESSION_URLS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) urls = stream.list(stream.stationurl) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_session_urls -> done") return urls async def update_session_host(self, gid, is_migrate_owner): logger.info("MatchMakingClient.update_session_host()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.bool(is_migrate_owner) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_SESSION_HOST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.update_session_host -> done") async def update_gathering_ownership(self, gid, participants_only): logger.info("MatchMakingClient.update_gathering_ownership()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.bool(participants_only) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_GATHERING_OWNERSHIP, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.update_gathering_ownership -> done") return result async def migrate_gathering_ownership(self, gid, potential_owners, participants_only): logger.info("MatchMakingClient.migrate_gathering_ownership()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(potential_owners, stream.pid) stream.bool(participants_only) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_MIGRATE_GATHERING_OWNERSHIP, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.migrate_gathering_ownership -> done") class MatchMakingClientExt(MatchMakingProtocolExt): def __init__(self, client): self.settings = client.settings self.client = client async def end_participation(self, gid, message): logger.info("MatchMakingClientExt.end_participation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_END_PARTICIPATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.end_participation -> done") return result async def get_participants(self, gid, only_active): logger.info("MatchMakingClientExt.get_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.bool(only_active) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) participants = stream.list(stream.pid) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.get_participants -> done") return participants async def get_detailed_participants(self, gid, only_active): logger.info("MatchMakingClientExt.get_detailed_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.bool(only_active) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_DETAILED_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) details = stream.list(ParticipantDetails) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.get_detailed_participants -> done") return details async def get_participants_urls(self, gids): logger.info("MatchMakingClientExt.get_participants_urls()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PARTICIPANTS_URLS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) urls = stream.list(GatheringURLs) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.get_participants_urls -> done") return urls async def get_gathering_relations(self, id, descr): logger.info("MatchMakingClientExt.get_gathering_relations()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(id) stream.string(descr) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_GATHERING_RELATIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.string() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.get_gathering_relations -> done") return result async def delete_from_deletions(self, deletions, pid): logger.info("MatchMakingClientExt.delete_from_deletions()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(deletions, stream.u32) stream.pid(pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_FROM_DELETIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.delete_from_deletions -> done") class MatchmakeExtensionClient(MatchmakeExtensionProtocol): def __init__(self, client): self.settings = client.settings self.client = client async def close_participation(self, gid): logger.info("MatchmakeExtensionClient.close_participation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CLOSE_PARTICIPATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.close_participation -> done") async def open_participation(self, gid): logger.info("MatchmakeExtensionClient.open_participation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_OPEN_PARTICIPATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.open_participation -> done") async def auto_matchmake_postpone(self, gathering, message): logger.info("MatchmakeExtensionClient.auto_matchmake_postpone()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(gathering) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_AUTO_MATCHMAKE_POSTPONE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gathering = stream.anydata() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.auto_matchmake_postpone -> done") return gathering async def browse_matchmake_session(self, search_criteria, range): logger.info("MatchmakeExtensionClient.browse_matchmake_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.browse_matchmake_session -> done") return gatherings async def browse_matchmake_session_with_host_urls(self, search_criteria, range): logger.info("MatchmakeExtensionClient.browse_matchmake_session_with_host_urls()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.gatherings = stream.list(stream.anydata) obj.urls = stream.list(GatheringURLs) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.browse_matchmake_session_with_host_urls -> done") return obj async def create_matchmake_session(self, gathering, description, num_participants): logger.info("MatchmakeExtensionClient.create_matchmake_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(gathering) stream.string(description) stream.u16(num_participants) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CREATE_MATCHMAKE_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.gid = stream.u32() obj.session_key = stream.buffer() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.create_matchmake_session -> done") return obj async def join_matchmake_session(self, gid, message): logger.info("MatchmakeExtensionClient.join_matchmake_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_JOIN_MATCHMAKE_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session_key = stream.buffer() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.join_matchmake_session -> done") return session_key async def modify_current_game_attribute(self, gid, attrib, value): logger.info("MatchmakeExtensionClient.modify_current_game_attribute()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.u32(attrib) stream.u32(value) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_MODIFY_CURRENT_GAME_ATTRIBUTE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.modify_current_game_attribute -> done") async def update_notification_data(self, type, param1, param2, param3): logger.info("MatchmakeExtensionClient.update_notification_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(type) stream.pid(param1) stream.pid(param2) stream.string(param3) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_NOTIFICATION_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.update_notification_data -> done") async def get_friend_notification_data(self, type): logger.info("MatchmakeExtensionClient.get_friend_notification_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.s32(type) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_FRIEND_NOTIFICATION_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) notifications = stream.list(notification.NotificationEvent) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.get_friend_notification_data -> done") return notifications async def update_application_buffer(self, gid, buffer): logger.info("MatchmakeExtensionClient.update_application_buffer()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.buffer(buffer) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_APPLICATION_BUFFER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.update_application_buffer -> done") async def update_matchmake_session_attribute(self, gid, attribs): logger.info("MatchmakeExtensionClient.update_matchmake_session_attribute()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(attribs, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_MATCHMAKE_SESSION_ATTRIBUTE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.update_matchmake_session_attribute -> done") async def get_friend_notification_data_list(self, types): logger.info("MatchmakeExtensionClient.get_friend_notification_data_list()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(types, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_FRIEND_NOTIFICATION_DATA_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) notifications = stream.list(notification.NotificationEvent) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.get_friend_notification_data_list -> done") return notifications async def update_matchmake_session(self, gathering): logger.info("MatchmakeExtensionClient.update_matchmake_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(gathering) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_MATCHMAKE_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.update_matchmake_session -> done") async def auto_matchmake_with_search_criteria_postpone(self, search_criteria, gathering, message): logger.info("MatchmakeExtensionClient.auto_matchmake_with_search_criteria_postpone()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(search_criteria, stream.add) stream.anydata(gathering) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_AUTO_MATCHMAKE_WITH_SEARCH_CRITERIA_POSTPONE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gathering = stream.anydata() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.auto_matchmake_with_search_criteria_postpone -> done") return gathering async def get_playing_session(self, pids): logger.info("MatchmakeExtensionClient.get_playing_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PLAYING_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) sessions = stream.list(PlayingSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.get_playing_session -> done") return sessions async def create_community(self, community, message): logger.info("MatchmakeExtensionClient.create_community()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(community) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CREATE_COMMUNITY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gid = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.create_community -> done") return gid async def update_community(self, community): logger.info("MatchmakeExtensionClient.update_community()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(community) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_COMMUNITY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.update_community -> done") async def join_community(self, gid, message, password): logger.info("MatchmakeExtensionClient.join_community()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) stream.string(password) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_JOIN_COMMUNITY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.join_community -> done") async def find_community_by_gathering_id(self, gids): logger.info("MatchmakeExtensionClient.find_community_by_gathering_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_COMMUNITY_BY_GATHERING_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) communities = stream.list(PersistentGathering) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.find_community_by_gathering_id -> done") return communities async def find_official_community(self, available_only, range): logger.info("MatchmakeExtensionClient.find_official_community()") #--- request --- stream = streams.StreamOut(self.settings) stream.bool(available_only) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_OFFICIAL_COMMUNITY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) communities = stream.list(PersistentGathering) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.find_official_community -> done") return communities async def find_community_by_participant(self, pid, range): logger.info("MatchmakeExtensionClient.find_community_by_participant()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_COMMUNITY_BY_PARTICIPANT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) communities = stream.list(PersistentGathering) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.find_community_by_participant -> done") return communities async def update_privacy_setting(self, online_status, community_participation): logger.info("MatchmakeExtensionClient.update_privacy_setting()") #--- request --- stream = streams.StreamOut(self.settings) stream.bool(online_status) stream.bool(community_participation) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_PRIVACY_SETTING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.update_privacy_setting -> done") async def get_my_block_list(self): logger.info("MatchmakeExtensionClient.get_my_block_list()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_MY_BLOCK_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) pids = stream.list(stream.pid) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.get_my_block_list -> done") return pids async def add_to_block_list(self, pids): logger.info("MatchmakeExtensionClient.add_to_block_list()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_ADD_TO_BLOCK_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.add_to_block_list -> done") async def remove_from_block_list(self, pids): logger.info("MatchmakeExtensionClient.remove_from_block_list()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REMOVE_FROM_BLOCK_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.remove_from_block_list -> done") async def clear_my_block_list(self): logger.info("MatchmakeExtensionClient.clear_my_block_list()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CLEAR_MY_BLOCK_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.clear_my_block_list -> done") async def report_violation(self, pid, username, violation_code): logger.info("MatchmakeExtensionClient.report_violation()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) stream.string(username) stream.u32(violation_code) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REPORT_VIOLATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.report_violation -> done") async def is_violation_user(self): logger.info("MatchmakeExtensionClient.is_violation_user()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_IS_VIOLATION_USER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.flag = stream.bool() obj.score = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.is_violation_user -> done") return obj async def join_matchmake_session_ex(self, gid, gmessage, ignore_block_list, num_participants): logger.info("MatchmakeExtensionClient.join_matchmake_session_ex()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(gmessage) stream.bool(ignore_block_list) stream.u16(num_participants) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_JOIN_MATCHMAKE_SESSION_EX, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session_key = stream.buffer() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.join_matchmake_session_ex -> done") return session_key async def get_simple_playing_session(self, pids, include_login_user): logger.info("MatchmakeExtensionClient.get_simple_playing_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) stream.bool(include_login_user) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SIMPLE_PLAYING_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session = stream.list(SimplePlayingSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.get_simple_playing_session -> done") return session async def get_simple_community(self, gids): logger.info("MatchmakeExtensionClient.get_simple_community()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SIMPLE_COMMUNITY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) communities = stream.list(SimpleCommunity) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.get_simple_community -> done") return communities async def auto_matchmake_with_gathering_id_postpone(self, gids, gathering, message): logger.info("MatchmakeExtensionClient.auto_matchmake_with_gathering_id_postpone()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) stream.anydata(gathering) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_AUTO_MATCHMAKE_WITH_GATHERING_ID_POSTPONE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) joined_gathering = stream.anydata() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.auto_matchmake_with_gathering_id_postpone -> done") return joined_gathering async def update_progress_score(self, gid, score): logger.info("MatchmakeExtensionClient.update_progress_score()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.u8(score) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_PROGRESS_SCORE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.update_progress_score -> done") async def debug_notify_event(self, pid, main_type, sub_type, param1, param2, param3): logger.info("MatchmakeExtensionClient.debug_notify_event()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) stream.u32(main_type) stream.u32(sub_type) stream.u64(param1) stream.u64(param2) stream.string(param3) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DEBUG_NOTIFY_EVENT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.debug_notify_event -> done") async def generate_matchmake_session_system_password(self, gid): logger.info("MatchmakeExtensionClient.generate_matchmake_session_system_password()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GENERATE_MATCHMAKE_SESSION_SYSTEM_PASSWORD, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) password = stream.string() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.generate_matchmake_session_system_password -> done") return password async def clear_matchmake_session_system_password(self, gid): logger.info("MatchmakeExtensionClient.clear_matchmake_session_system_password()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CLEAR_MATCHMAKE_SESSION_SYSTEM_PASSWORD, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.clear_matchmake_session_system_password -> done") async def create_matchmake_session_with_param(self, param): logger.info("MatchmakeExtensionClient.create_matchmake_session_with_param()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CREATE_MATCHMAKE_SESSION_WITH_PARAM, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session = stream.extract(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.create_matchmake_session_with_param -> done") return session async def join_matchmake_session_with_param(self, param): logger.info("MatchmakeExtensionClient.join_matchmake_session_with_param()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_JOIN_MATCHMAKE_SESSION_WITH_PARAM, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session = stream.extract(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.join_matchmake_session_with_param -> done") return session async def auto_matchmake_with_param_postpone(self, param): logger.info("MatchmakeExtensionClient.auto_matchmake_with_param_postpone()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_AUTO_MATCHMAKE_WITH_PARAM_POSTPONE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session = stream.extract(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.auto_matchmake_with_param_postpone -> done") return session async def find_matchmake_session_by_gathering_id_detail(self, gid): logger.info("MatchmakeExtensionClient.find_matchmake_session_by_gathering_id_detail()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_MATCHMAKE_SESSION_BY_GATHERING_ID_DETAIL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session = stream.extract(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.find_matchmake_session_by_gathering_id_detail -> done") return session async def browse_matchmake_session_no_holder(self, search_criteria, range): logger.info("MatchmakeExtensionClient.browse_matchmake_session_no_holder()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) sessions = stream.list(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.browse_matchmake_session_no_holder -> done") return sessions async def browse_matchmake_session_with_host_urls_no_holder(self, search_criteria, range): logger.info("MatchmakeExtensionClient.browse_matchmake_session_with_host_urls_no_holder()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.sessions = stream.list(MatchmakeSession) obj.urls = stream.list(GatheringURLs) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.browse_matchmake_session_with_host_urls_no_holder -> done") return obj async def update_matchmake_session_part(self, param): logger.info("MatchmakeExtensionClient.update_matchmake_session_part()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_MATCHMAKE_SESSION_PART, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.update_matchmake_session_part -> done") async def request_matchmaking(self, param): logger.info("MatchmakeExtensionClient.request_matchmaking()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REQUEST_MATCHMAKING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) request_id = stream.u64() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.request_matchmaking -> done") return request_id async def withdraw_matchmaking(self, request_id): logger.info("MatchmakeExtensionClient.withdraw_matchmaking()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(request_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_WITHDRAW_MATCHMAKING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.withdraw_matchmaking -> done") async def withdraw_matchmaking_all(self): logger.info("MatchmakeExtensionClient.withdraw_matchmaking_all()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_WITHDRAW_MATCHMAKING_ALL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.withdraw_matchmaking_all -> done") async def find_matchmake_session_by_gathering_id(self, gids): logger.info("MatchmakeExtensionClient.find_matchmake_session_by_gathering_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_MATCHMAKE_SESSION_BY_GATHERING_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) sessions = stream.list(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.find_matchmake_session_by_gathering_id -> done") return sessions async def find_matchmake_session_by_single_gathering_id(self, gid): logger.info("MatchmakeExtensionClient.find_matchmake_session_by_single_gathering_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_MATCHMAKE_SESSION_BY_SINGLE_GATHERING_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session = stream.extract(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.find_matchmake_session_by_single_gathering_id -> done") return session async def find_matchmake_session_by_owner(self, pid, range): logger.info("MatchmakeExtensionClient.find_matchmake_session_by_owner()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_MATCHMAKE_SESSION_BY_OWNER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) sessions = stream.list(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.find_matchmake_session_by_owner -> done") return sessions async def find_matchmake_session_by_participant(self, param): logger.info("MatchmakeExtensionClient.find_matchmake_session_by_participant()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_MATCHMAKE_SESSION_BY_PARTICIPANT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.list(FindMatchmakeSessionByParticipantResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.find_matchmake_session_by_participant -> done") return result async def browse_matchmake_session_no_holder_no_result_range(self, search_criteria): logger.info("MatchmakeExtensionClient.browse_matchmake_session_no_holder_no_result_range()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER_NO_RESULT_RANGE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) sessions = stream.list(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.browse_matchmake_session_no_holder_no_result_range -> done") return sessions async def browse_matchmake_session_with_host_urls_no_holder_no_result_range(self, search_criteria): logger.info("MatchmakeExtensionClient.browse_matchmake_session_with_host_urls_no_holder_no_result_range()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER_NO_RESULT_RANGE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.sessions = stream.list(MatchmakeSession) obj.urls = stream.list(GatheringURLs) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.browse_matchmake_session_with_host_urls_no_holder_no_result_range -> done") return obj class MatchmakeRefereeClient(MatchmakeRefereeProtocol): def __init__(self, client): self.settings = client.settings self.client = client async def start_round(self, param): logger.info("MatchmakeRefereeClient.start_round()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_START_ROUND, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) round_id = stream.u64() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.start_round -> done") return round_id async def get_start_round_param(self, round_id): logger.info("MatchmakeRefereeClient.get_start_round_param()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(round_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_START_ROUND_PARAM, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) param = stream.extract(MatchmakeRefereeStartRoundParam) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_start_round_param -> done") return param async def end_round(self, param): logger.info("MatchmakeRefereeClient.end_round()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_END_ROUND, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.end_round -> done") async def end_round_without_report(self, round_id): logger.info("MatchmakeRefereeClient.end_round_without_report()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(round_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_END_ROUND_WITHOUT_REPORT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.end_round_without_report -> done") async def get_round_participants(self, round_id): logger.info("MatchmakeRefereeClient.get_round_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(round_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_ROUND_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) pids = stream.list(stream.pid) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_round_participants -> done") return pids async def get_not_summarized_round(self): logger.info("MatchmakeRefereeClient.get_not_summarized_round()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_NOT_SUMMARIZED_ROUND, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) rounds = stream.list(MatchmakeRefereeRound) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_not_summarized_round -> done") return rounds async def get_round(self, round): logger.info("MatchmakeRefereeClient.get_round()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(round) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_ROUND, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) round = stream.extract(MatchmakeRefereeRound) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_round -> done") return round async def get_stats_primary(self, target): logger.info("MatchmakeRefereeClient.get_stats_primary()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATS_PRIMARY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) stats = stream.extract(MatchmakeRefereeStats) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_stats_primary -> done") return stats async def get_stats_primaries(self, targets): logger.info("MatchmakeRefereeClient.get_stats_primaries()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(targets, stream.add) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATS_PRIMARIES, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.stats = stream.list(MatchmakeRefereeStats) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_stats_primaries -> done") return obj async def get_stats_all(self, target): logger.info("MatchmakeRefereeClient.get_stats_all()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATS_ALL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) stats = stream.list(MatchmakeRefereeStats) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_stats_all -> done") return stats async def create_stats(self, param): logger.info("MatchmakeRefereeClient.create_stats()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CREATE_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) stats = stream.extract(MatchmakeRefereeStats) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.create_stats -> done") return stats async def get_or_create_stats(self, param): logger.info("MatchmakeRefereeClient.get_or_create_stats()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_OR_CREATE_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) stats = stream.extract(MatchmakeRefereeStats) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_or_create_stats -> done") return stats async def reset_stats(self): logger.info("MatchmakeRefereeClient.reset_stats()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RESET_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.reset_stats -> done") class MatchMakingServer(MatchMakingProtocol): def __init__(self): self.methods = { self.METHOD_REGISTER_GATHERING: self.handle_register_gathering, self.METHOD_UNREGISTER_GATHERING: self.handle_unregister_gathering, self.METHOD_UNREGISTER_GATHERINGS: self.handle_unregister_gatherings, self.METHOD_UPDATE_GATHERING: self.handle_update_gathering, self.METHOD_INVITE: self.handle_invite, self.METHOD_ACCEPT_INVITATION: self.handle_accept_invitation, self.METHOD_DECLINE_INVITATION: self.handle_decline_invitation, self.METHOD_CANCEL_INVITATION: self.handle_cancel_invitation, self.METHOD_GET_INVITATIONS_SENT: self.handle_get_invitations_sent, self.METHOD_GET_INVITATIONS_RECEIVED: self.handle_get_invitations_received, self.METHOD_PARTICIPATE: self.handle_participate, self.METHOD_CANCEL_PARTICIPATION: self.handle_cancel_participation, self.METHOD_GET_PARTICIPANTS: self.handle_get_participants, self.METHOD_ADD_PARTICIPANTS: self.handle_add_participants, self.METHOD_GET_DETAILED_PARTICIPANTS: self.handle_get_detailed_participants, self.METHOD_GET_PARTICIPANTS_URLS: self.handle_get_participants_urls, self.METHOD_FIND_BY_TYPE: self.handle_find_by_type, self.METHOD_FIND_BY_DESCRIPTION: self.handle_find_by_description, self.METHOD_FIND_BY_DESCRIPTION_REGEX: self.handle_find_by_description_regex, self.METHOD_FIND_BY_ID: self.handle_find_by_id, self.METHOD_FIND_BY_SINGLE_ID: self.handle_find_by_single_id, self.METHOD_FIND_BY_OWNER: self.handle_find_by_owner, self.METHOD_FIND_BY_PARTICIPANTS: self.handle_find_by_participants, self.METHOD_FIND_INVITATIONS: self.handle_find_invitations, self.METHOD_FIND_BY_SQL_QUERY: self.handle_find_by_sql_query, self.METHOD_LAUNCH_SESSION: self.handle_launch_session, self.METHOD_UPDATE_SESSION_URL: self.handle_update_session_url, self.METHOD_GET_SESSION_URL: self.handle_get_session_url, self.METHOD_GET_STATE: self.handle_get_state, self.METHOD_SET_STATE: self.handle_set_state, self.METHOD_REPORT_STATS: self.handle_report_stats, self.METHOD_GET_STATS: self.handle_get_stats, self.METHOD_DELETE_GATHERING: self.handle_delete_gathering, self.METHOD_GET_PENDING_DELETIONS: self.handle_get_pending_deletions, self.METHOD_DELETE_FROM_DELETIONS: self.handle_delete_from_deletions, self.METHOD_MIGRATE_GATHERING_OWNERSHIP_V1: self.handle_migrate_gathering_ownership_v1, self.METHOD_FIND_BY_DESCRIPTION_LIKE: self.handle_find_by_description_like, self.METHOD_REGISTER_LOCAL_URL: self.handle_register_local_url, self.METHOD_REGISTER_LOCAL_URLS: self.handle_register_local_urls, self.METHOD_UPDATE_SESSION_HOST_V1: self.handle_update_session_host_v1, self.METHOD_GET_SESSION_URLS: self.handle_get_session_urls, self.METHOD_UPDATE_SESSION_HOST: self.handle_update_session_host, self.METHOD_UPDATE_GATHERING_OWNERSHIP: self.handle_update_gathering_ownership, self.METHOD_MIGRATE_GATHERING_OWNERSHIP: self.handle_migrate_gathering_ownership, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on MatchMakingServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_register_gathering(self, client, input, output): logger.info("MatchMakingServer.register_gathering()") #--- request --- gathering = input.anydata() response = await self.register_gathering(client, gathering) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u32(response) async def handle_unregister_gathering(self, client, input, output): logger.info("MatchMakingServer.unregister_gathering()") #--- request --- gid = input.u32() response = await self.unregister_gathering(client, gid) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_unregister_gatherings(self, client, input, output): logger.info("MatchMakingServer.unregister_gatherings()") #--- request --- gids = input.list(input.u32) response = await self.unregister_gatherings(client, gids) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_update_gathering(self, client, input, output): logger.info("MatchMakingServer.update_gathering()") #--- request --- gathering = input.anydata() response = await self.update_gathering(client, gathering) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_invite(self, client, input, output): logger.info("MatchMakingServer.invite()") #--- request --- gid = input.u32() pids = input.list(input.pid) message = input.string() response = await self.invite(client, gid, pids, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_accept_invitation(self, client, input, output): logger.info("MatchMakingServer.accept_invitation()") #--- request --- gid = input.u32() message = input.string() response = await self.accept_invitation(client, gid, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_decline_invitation(self, client, input, output): logger.info("MatchMakingServer.decline_invitation()") #--- request --- gid = input.u32() message = input.string() response = await self.decline_invitation(client, gid, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_cancel_invitation(self, client, input, output): logger.info("MatchMakingServer.cancel_invitation()") #--- request --- gid = input.u32() pids = input.list(input.pid) message = input.string() response = await self.cancel_invitation(client, gid, pids, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_invitations_sent(self, client, input, output): logger.info("MatchMakingServer.get_invitations_sent()") #--- request --- gid = input.u32() response = await self.get_invitations_sent(client, gid) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_invitations_received(self, client, input, output): logger.info("MatchMakingServer.get_invitations_received()") #--- request --- response = await self.get_invitations_received(client) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_participate(self, client, input, output): logger.info("MatchMakingServer.participate()") #--- request --- gid = input.u32() message = input.string() response = await self.participate(client, gid, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_cancel_participation(self, client, input, output): logger.info("MatchMakingServer.cancel_participation()") #--- request --- gid = input.u32() message = input.string() response = await self.cancel_participation(client, gid, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_participants(self, client, input, output): logger.info("MatchMakingServer.get_participants()") #--- request --- gid = input.u32() response = await self.get_participants(client, gid) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.pid) async def handle_add_participants(self, client, input, output): logger.info("MatchMakingServer.add_participants()") #--- request --- gid = input.u32() pids = input.list(input.pid) message = input.string() response = await self.add_participants(client, gid, pids, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_detailed_participants(self, client, input, output): logger.info("MatchMakingServer.get_detailed_participants()") #--- request --- gid = input.u32() response = await self.get_detailed_participants(client, gid) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_participants_urls(self, client, input, output): logger.info("MatchMakingServer.get_participants_urls()") #--- request --- gid = input.u32() response = await self.get_participants_urls(client, gid) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.stationurl) async def handle_find_by_type(self, client, input, output): logger.info("MatchMakingServer.find_by_type()") #--- request --- type = input.string() range = input.extract(common.ResultRange) response = await self.find_by_type(client, type, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_description(self, client, input, output): logger.info("MatchMakingServer.find_by_description()") #--- request --- description = input.string() range = input.extract(common.ResultRange) response = await self.find_by_description(client, description, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_description_regex(self, client, input, output): logger.info("MatchMakingServer.find_by_description_regex()") #--- request --- regex = input.string() range = input.extract(common.ResultRange) response = await self.find_by_description_regex(client, regex, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_id(self, client, input, output): logger.info("MatchMakingServer.find_by_id()") #--- request --- ids = input.list(input.u32) response = await self.find_by_id(client, ids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_single_id(self, client, input, output): logger.info("MatchMakingServer.find_by_single_id()") #--- request --- gid = input.u32() response = await self.find_by_single_id(client, gid) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'gathering']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.anydata(response.gathering) async def handle_find_by_owner(self, client, input, output): logger.info("MatchMakingServer.find_by_owner()") #--- request --- owner = input.pid() range = input.extract(common.ResultRange) response = await self.find_by_owner(client, owner, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_participants(self, client, input, output): logger.info("MatchMakingServer.find_by_participants()") #--- request --- pids = input.list(input.pid) response = await self.find_by_participants(client, pids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_invitations(self, client, input, output): logger.info("MatchMakingServer.find_invitations()") #--- request --- range = input.extract(common.ResultRange) response = await self.find_invitations(client, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_sql_query(self, client, input, output): logger.info("MatchMakingServer.find_by_sql_query()") #--- request --- query = input.string() range = input.extract(common.ResultRange) response = await self.find_by_sql_query(client, query, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_launch_session(self, client, input, output): logger.info("MatchMakingServer.launch_session()") #--- request --- gid = input.u32() url = input.string() response = await self.launch_session(client, gid, url) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_update_session_url(self, client, input, output): logger.info("MatchMakingServer.update_session_url()") #--- request --- gid = input.u32() url = input.string() response = await self.update_session_url(client, gid, url) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_session_url(self, client, input, output): logger.info("MatchMakingServer.get_session_url()") #--- request --- gid = input.u32() response = await self.get_session_url(client, gid) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'url']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.string(response.url) async def handle_get_state(self, client, input, output): logger.info("MatchMakingServer.get_state()") #--- request --- gid = input.u32() response = await self.get_state(client, gid) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'state']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.u32(response.state) async def handle_set_state(self, client, input, output): logger.info("MatchMakingServer.set_state()") #--- request --- gid = input.u32() state = input.u32() response = await self.set_state(client, gid, state) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_report_stats(self, client, input, output): logger.info("MatchMakingServer.report_stats()") #--- request --- gid = input.u32() stats = input.list(GatheringStats) response = await self.report_stats(client, gid, stats) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_stats(self, client, input, output): logger.info("MatchMakingServer.get_stats()") #--- request --- gid = input.u32() pids = input.list(input.pid) columns = input.list(input.u8) response = await self.get_stats(client, gid, pids, columns) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'stats']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.list(response.stats, output.add) async def handle_delete_gathering(self, client, input, output): logger.info("MatchMakingServer.delete_gathering()") #--- request --- gid = input.u32() response = await self.delete_gathering(client, gid) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_pending_deletions(self, client, input, output): logger.info("MatchMakingServer.get_pending_deletions()") #--- request --- reason = input.u32() range = input.extract(common.ResultRange) response = await self.get_pending_deletions(client, reason, range) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'deletions']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.list(response.deletions, output.add) async def handle_delete_from_deletions(self, client, input, output): logger.info("MatchMakingServer.delete_from_deletions()") #--- request --- deletions = input.list(input.u32) response = await self.delete_from_deletions(client, deletions) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_migrate_gathering_ownership_v1(self, client, input, output): logger.info("MatchMakingServer.migrate_gathering_ownership_v1()") #--- request --- gid = input.u32() potential_owners = input.list(input.pid) response = await self.migrate_gathering_ownership_v1(client, gid, potential_owners) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_find_by_description_like(self, client, input, output): logger.info("MatchMakingServer.find_by_description_like()") #--- request --- description = input.string() range = input.extract(common.ResultRange) response = await self.find_by_description_like(client, description, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_register_local_url(self, client, input, output): logger.info("MatchMakingServer.register_local_url()") #--- request --- gid = input.u32() url = input.stationurl() await self.register_local_url(client, gid, url) async def handle_register_local_urls(self, client, input, output): logger.info("MatchMakingServer.register_local_urls()") #--- request --- gid = input.u32() urls = input.list(input.stationurl) await self.register_local_urls(client, gid, urls) async def handle_update_session_host_v1(self, client, input, output): logger.info("MatchMakingServer.update_session_host_v1()") #--- request --- gid = input.u32() await self.update_session_host_v1(client, gid) async def handle_get_session_urls(self, client, input, output): logger.info("MatchMakingServer.get_session_urls()") #--- request --- gid = input.u32() response = await self.get_session_urls(client, gid) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.stationurl) async def handle_update_session_host(self, client, input, output): logger.info("MatchMakingServer.update_session_host()") #--- request --- gid = input.u32() is_migrate_owner = input.bool() await self.update_session_host(client, gid, is_migrate_owner) async def handle_update_gathering_ownership(self, client, input, output): logger.info("MatchMakingServer.update_gathering_ownership()") #--- request --- gid = input.u32() participants_only = input.bool() response = await self.update_gathering_ownership(client, gid, participants_only) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_migrate_gathering_ownership(self, client, input, output): logger.info("MatchMakingServer.migrate_gathering_ownership()") #--- request --- gid = input.u32() potential_owners = input.list(input.pid) participants_only = input.bool() await self.migrate_gathering_ownership(client, gid, potential_owners, participants_only) async def register_gathering(self, *args): logger.warning("MatchMakingServer.register_gathering not implemented") raise common.RMCError("Core::NotImplemented") async def unregister_gathering(self, *args): logger.warning("MatchMakingServer.unregister_gathering not implemented") raise common.RMCError("Core::NotImplemented") async def unregister_gatherings(self, *args): logger.warning("MatchMakingServer.unregister_gatherings not implemented") raise common.RMCError("Core::NotImplemented") async def update_gathering(self, *args): logger.warning("MatchMakingServer.update_gathering not implemented") raise common.RMCError("Core::NotImplemented") async def invite(self, *args): logger.warning("MatchMakingServer.invite not implemented") raise common.RMCError("Core::NotImplemented") async def accept_invitation(self, *args): logger.warning("MatchMakingServer.accept_invitation not implemented") raise common.RMCError("Core::NotImplemented") async def decline_invitation(self, *args): logger.warning("MatchMakingServer.decline_invitation not implemented") raise common.RMCError("Core::NotImplemented") async def cancel_invitation(self, *args): logger.warning("MatchMakingServer.cancel_invitation not implemented") raise common.RMCError("Core::NotImplemented") async def get_invitations_sent(self, *args): logger.warning("MatchMakingServer.get_invitations_sent not implemented") raise common.RMCError("Core::NotImplemented") async def get_invitations_received(self, *args): logger.warning("MatchMakingServer.get_invitations_received not implemented") raise common.RMCError("Core::NotImplemented") async def participate(self, *args): logger.warning("MatchMakingServer.participate not implemented") raise common.RMCError("Core::NotImplemented") async def cancel_participation(self, *args): logger.warning("MatchMakingServer.cancel_participation not implemented") raise common.RMCError("Core::NotImplemented") async def get_participants(self, *args): logger.warning("MatchMakingServer.get_participants not implemented") raise common.RMCError("Core::NotImplemented") async def add_participants(self, *args): logger.warning("MatchMakingServer.add_participants not implemented") raise common.RMCError("Core::NotImplemented") async def get_detailed_participants(self, *args): logger.warning("MatchMakingServer.get_detailed_participants not implemented") raise common.RMCError("Core::NotImplemented") async def get_participants_urls(self, *args): logger.warning("MatchMakingServer.get_participants_urls not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_type(self, *args): logger.warning("MatchMakingServer.find_by_type not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_description(self, *args): logger.warning("MatchMakingServer.find_by_description not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_description_regex(self, *args): logger.warning("MatchMakingServer.find_by_description_regex not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_id(self, *args): logger.warning("MatchMakingServer.find_by_id not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_single_id(self, *args): logger.warning("MatchMakingServer.find_by_single_id not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_owner(self, *args): logger.warning("MatchMakingServer.find_by_owner not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_participants(self, *args): logger.warning("MatchMakingServer.find_by_participants not implemented") raise common.RMCError("Core::NotImplemented") async def find_invitations(self, *args): logger.warning("MatchMakingServer.find_invitations not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_sql_query(self, *args): logger.warning("MatchMakingServer.find_by_sql_query not implemented") raise common.RMCError("Core::NotImplemented") async def launch_session(self, *args): logger.warning("MatchMakingServer.launch_session not implemented") raise common.RMCError("Core::NotImplemented") async def update_session_url(self, *args): logger.warning("MatchMakingServer.update_session_url not implemented") raise common.RMCError("Core::NotImplemented") async def get_session_url(self, *args): logger.warning("MatchMakingServer.get_session_url not implemented") raise common.RMCError("Core::NotImplemented") async def get_state(self, *args): logger.warning("MatchMakingServer.get_state not implemented") raise common.RMCError("Core::NotImplemented") async def set_state(self, *args): logger.warning("MatchMakingServer.set_state not implemented") raise common.RMCError("Core::NotImplemented") async def report_stats(self, *args): logger.warning("MatchMakingServer.report_stats not implemented") raise common.RMCError("Core::NotImplemented") async def get_stats(self, *args): logger.warning("MatchMakingServer.get_stats not implemented") raise common.RMCError("Core::NotImplemented") async def delete_gathering(self, *args): logger.warning("MatchMakingServer.delete_gathering not implemented") raise common.RMCError("Core::NotImplemented") async def get_pending_deletions(self, *args): logger.warning("MatchMakingServer.get_pending_deletions not implemented") raise common.RMCError("Core::NotImplemented") async def delete_from_deletions(self, *args): logger.warning("MatchMakingServer.delete_from_deletions not implemented") raise common.RMCError("Core::NotImplemented") async def migrate_gathering_ownership_v1(self, *args): logger.warning("MatchMakingServer.migrate_gathering_ownership_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_description_like(self, *args): logger.warning("MatchMakingServer.find_by_description_like not implemented") raise common.RMCError("Core::NotImplemented") async def register_local_url(self, *args): logger.warning("MatchMakingServer.register_local_url not implemented") raise common.RMCError("Core::NotImplemented") async def register_local_urls(self, *args): logger.warning("MatchMakingServer.register_local_urls not implemented") raise common.RMCError("Core::NotImplemented") async def update_session_host_v1(self, *args): logger.warning("MatchMakingServer.update_session_host_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def get_session_urls(self, *args): logger.warning("MatchMakingServer.get_session_urls not implemented") raise common.RMCError("Core::NotImplemented") async def update_session_host(self, *args): logger.warning("MatchMakingServer.update_session_host not implemented") raise common.RMCError("Core::NotImplemented") async def update_gathering_ownership(self, *args): logger.warning("MatchMakingServer.update_gathering_ownership not implemented") raise common.RMCError("Core::NotImplemented") async def migrate_gathering_ownership(self, *args): logger.warning("MatchMakingServer.migrate_gathering_ownership not implemented") raise common.RMCError("Core::NotImplemented") class MatchMakingServerExt(MatchMakingProtocolExt): def __init__(self): self.methods = { self.METHOD_END_PARTICIPATION: self.handle_end_participation, self.METHOD_GET_PARTICIPANTS: self.handle_get_participants, self.METHOD_GET_DETAILED_PARTICIPANTS: self.handle_get_detailed_participants, self.METHOD_GET_PARTICIPANTS_URLS: self.handle_get_participants_urls, self.METHOD_GET_GATHERING_RELATIONS: self.handle_get_gathering_relations, self.METHOD_DELETE_FROM_DELETIONS: self.handle_delete_from_deletions, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on MatchMakingServerExt: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_end_participation(self, client, input, output): logger.info("MatchMakingServerExt.end_participation()") #--- request --- gid = input.u32() message = input.string() response = await self.end_participation(client, gid, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_participants(self, client, input, output): logger.info("MatchMakingServerExt.get_participants()") #--- request --- gid = input.u32() only_active = input.bool() response = await self.get_participants(client, gid, only_active) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.pid) async def handle_get_detailed_participants(self, client, input, output): logger.info("MatchMakingServerExt.get_detailed_participants()") #--- request --- gid = input.u32() only_active = input.bool() response = await self.get_detailed_participants(client, gid, only_active) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_participants_urls(self, client, input, output): logger.info("MatchMakingServerExt.get_participants_urls()") #--- request --- gids = input.list(input.u32) response = await self.get_participants_urls(client, gids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_gathering_relations(self, client, input, output): logger.info("MatchMakingServerExt.get_gathering_relations()") #--- request --- id = input.u32() descr = input.string() response = await self.get_gathering_relations(client, id, descr) #--- response --- if not isinstance(response, str): raise RuntimeError("Expected str, got %s" %response.__class__.__name__) output.string(response) async def handle_delete_from_deletions(self, client, input, output): logger.info("MatchMakingServerExt.delete_from_deletions()") #--- request --- deletions = input.list(input.u32) pid = input.pid() await self.delete_from_deletions(client, deletions, pid) async def end_participation(self, *args): logger.warning("MatchMakingServerExt.end_participation not implemented") raise common.RMCError("Core::NotImplemented") async def get_participants(self, *args): logger.warning("MatchMakingServerExt.get_participants not implemented") raise common.RMCError("Core::NotImplemented") async def get_detailed_participants(self, *args): logger.warning("MatchMakingServerExt.get_detailed_participants not implemented") raise common.RMCError("Core::NotImplemented") async def get_participants_urls(self, *args): logger.warning("MatchMakingServerExt.get_participants_urls not implemented") raise common.RMCError("Core::NotImplemented") async def get_gathering_relations(self, *args): logger.warning("MatchMakingServerExt.get_gathering_relations not implemented") raise common.RMCError("Core::NotImplemented") async def delete_from_deletions(self, *args): logger.warning("MatchMakingServerExt.delete_from_deletions not implemented") raise common.RMCError("Core::NotImplemented") class MatchmakeExtensionServer(MatchmakeExtensionProtocol): def __init__(self): self.methods = { self.METHOD_CLOSE_PARTICIPATION: self.handle_close_participation, self.METHOD_OPEN_PARTICIPATION: self.handle_open_participation, self.METHOD_AUTO_MATCHMAKE_POSTPONE: self.handle_auto_matchmake_postpone, self.METHOD_BROWSE_MATCHMAKE_SESSION: self.handle_browse_matchmake_session, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS: self.handle_browse_matchmake_session_with_host_urls, self.METHOD_CREATE_MATCHMAKE_SESSION: self.handle_create_matchmake_session, self.METHOD_JOIN_MATCHMAKE_SESSION: self.handle_join_matchmake_session, self.METHOD_MODIFY_CURRENT_GAME_ATTRIBUTE: self.handle_modify_current_game_attribute, self.METHOD_UPDATE_NOTIFICATION_DATA: self.handle_update_notification_data, self.METHOD_GET_FRIEND_NOTIFICATION_DATA: self.handle_get_friend_notification_data, self.METHOD_UPDATE_APPLICATION_BUFFER: self.handle_update_application_buffer, self.METHOD_UPDATE_MATCHMAKE_SESSION_ATTRIBUTE: self.handle_update_matchmake_session_attribute, self.METHOD_GET_FRIEND_NOTIFICATION_DATA_LIST: self.handle_get_friend_notification_data_list, self.METHOD_UPDATE_MATCHMAKE_SESSION: self.handle_update_matchmake_session, self.METHOD_AUTO_MATCHMAKE_WITH_SEARCH_CRITERIA_POSTPONE: self.handle_auto_matchmake_with_search_criteria_postpone, self.METHOD_GET_PLAYING_SESSION: self.handle_get_playing_session, self.METHOD_CREATE_COMMUNITY: self.handle_create_community, self.METHOD_UPDATE_COMMUNITY: self.handle_update_community, self.METHOD_JOIN_COMMUNITY: self.handle_join_community, self.METHOD_FIND_COMMUNITY_BY_GATHERING_ID: self.handle_find_community_by_gathering_id, self.METHOD_FIND_OFFICIAL_COMMUNITY: self.handle_find_official_community, self.METHOD_FIND_COMMUNITY_BY_PARTICIPANT: self.handle_find_community_by_participant, self.METHOD_UPDATE_PRIVACY_SETTING: self.handle_update_privacy_setting, self.METHOD_GET_MY_BLOCK_LIST: self.handle_get_my_block_list, self.METHOD_ADD_TO_BLOCK_LIST: self.handle_add_to_block_list, self.METHOD_REMOVE_FROM_BLOCK_LIST: self.handle_remove_from_block_list, self.METHOD_CLEAR_MY_BLOCK_LIST: self.handle_clear_my_block_list, self.METHOD_REPORT_VIOLATION: self.handle_report_violation, self.METHOD_IS_VIOLATION_USER: self.handle_is_violation_user, self.METHOD_JOIN_MATCHMAKE_SESSION_EX: self.handle_join_matchmake_session_ex, self.METHOD_GET_SIMPLE_PLAYING_SESSION: self.handle_get_simple_playing_session, self.METHOD_GET_SIMPLE_COMMUNITY: self.handle_get_simple_community, self.METHOD_AUTO_MATCHMAKE_WITH_GATHERING_ID_POSTPONE: self.handle_auto_matchmake_with_gathering_id_postpone, self.METHOD_UPDATE_PROGRESS_SCORE: self.handle_update_progress_score, self.METHOD_DEBUG_NOTIFY_EVENT: self.handle_debug_notify_event, self.METHOD_GENERATE_MATCHMAKE_SESSION_SYSTEM_PASSWORD: self.handle_generate_matchmake_session_system_password, self.METHOD_CLEAR_MATCHMAKE_SESSION_SYSTEM_PASSWORD: self.handle_clear_matchmake_session_system_password, self.METHOD_CREATE_MATCHMAKE_SESSION_WITH_PARAM: self.handle_create_matchmake_session_with_param, self.METHOD_JOIN_MATCHMAKE_SESSION_WITH_PARAM: self.handle_join_matchmake_session_with_param, self.METHOD_AUTO_MATCHMAKE_WITH_PARAM_POSTPONE: self.handle_auto_matchmake_with_param_postpone, self.METHOD_FIND_MATCHMAKE_SESSION_BY_GATHERING_ID_DETAIL: self.handle_find_matchmake_session_by_gathering_id_detail, self.METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER: self.handle_browse_matchmake_session_no_holder, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER: self.handle_browse_matchmake_session_with_host_urls_no_holder, self.METHOD_UPDATE_MATCHMAKE_SESSION_PART: self.handle_update_matchmake_session_part, self.METHOD_REQUEST_MATCHMAKING: self.handle_request_matchmaking, self.METHOD_WITHDRAW_MATCHMAKING: self.handle_withdraw_matchmaking, self.METHOD_WITHDRAW_MATCHMAKING_ALL: self.handle_withdraw_matchmaking_all, self.METHOD_FIND_MATCHMAKE_SESSION_BY_GATHERING_ID: self.handle_find_matchmake_session_by_gathering_id, self.METHOD_FIND_MATCHMAKE_SESSION_BY_SINGLE_GATHERING_ID: self.handle_find_matchmake_session_by_single_gathering_id, self.METHOD_FIND_MATCHMAKE_SESSION_BY_OWNER: self.handle_find_matchmake_session_by_owner, self.METHOD_FIND_MATCHMAKE_SESSION_BY_PARTICIPANT: self.handle_find_matchmake_session_by_participant, self.METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER_NO_RESULT_RANGE: self.handle_browse_matchmake_session_no_holder_no_result_range, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER_NO_RESULT_RANGE: self.handle_browse_matchmake_session_with_host_urls_no_holder_no_result_range, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on MatchmakeExtensionServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_close_participation(self, client, input, output): logger.info("MatchmakeExtensionServer.close_participation()") #--- request --- gid = input.u32() await self.close_participation(client, gid) async def handle_open_participation(self, client, input, output): logger.info("MatchmakeExtensionServer.open_participation()") #--- request --- gid = input.u32() await self.open_participation(client, gid) async def handle_auto_matchmake_postpone(self, client, input, output): logger.info("MatchmakeExtensionServer.auto_matchmake_postpone()") #--- request --- gathering = input.anydata() message = input.string() response = await self.auto_matchmake_postpone(client, gathering, message) #--- response --- if not isinstance(response, Gathering): raise RuntimeError("Expected Gathering, got %s" %response.__class__.__name__) output.anydata(response) async def handle_browse_matchmake_session(self, client, input, output): logger.info("MatchmakeExtensionServer.browse_matchmake_session()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) range = input.extract(common.ResultRange) response = await self.browse_matchmake_session(client, search_criteria, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_browse_matchmake_session_with_host_urls(self, client, input, output): logger.info("MatchmakeExtensionServer.browse_matchmake_session_with_host_urls()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) range = input.extract(common.ResultRange) response = await self.browse_matchmake_session_with_host_urls(client, search_criteria, range) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['gatherings', 'urls']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.gatherings, output.anydata) output.list(response.urls, output.add) async def handle_create_matchmake_session(self, client, input, output): logger.info("MatchmakeExtensionServer.create_matchmake_session()") #--- request --- gathering = input.anydata() description = input.string() num_participants = input.u16() response = await self.create_matchmake_session(client, gathering, description, num_participants) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['gid', 'session_key']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.u32(response.gid) output.buffer(response.session_key) async def handle_join_matchmake_session(self, client, input, output): logger.info("MatchmakeExtensionServer.join_matchmake_session()") #--- request --- gid = input.u32() message = input.string() response = await self.join_matchmake_session(client, gid, message) #--- response --- if not isinstance(response, bytes): raise RuntimeError("Expected bytes, got %s" %response.__class__.__name__) output.buffer(response) async def handle_modify_current_game_attribute(self, client, input, output): logger.info("MatchmakeExtensionServer.modify_current_game_attribute()") #--- request --- gid = input.u32() attrib = input.u32() value = input.u32() await self.modify_current_game_attribute(client, gid, attrib, value) async def handle_update_notification_data(self, client, input, output): logger.info("MatchmakeExtensionServer.update_notification_data()") #--- request --- type = input.u32() param1 = input.pid() param2 = input.pid() param3 = input.string() await self.update_notification_data(client, type, param1, param2, param3) async def handle_get_friend_notification_data(self, client, input, output): logger.info("MatchmakeExtensionServer.get_friend_notification_data()") #--- request --- type = input.s32() response = await self.get_friend_notification_data(client, type) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_update_application_buffer(self, client, input, output): logger.info("MatchmakeExtensionServer.update_application_buffer()") #--- request --- gid = input.u32() buffer = input.buffer() await self.update_application_buffer(client, gid, buffer) async def handle_update_matchmake_session_attribute(self, client, input, output): logger.info("MatchmakeExtensionServer.update_matchmake_session_attribute()") #--- request --- gid = input.u32() attribs = input.list(input.u32) await self.update_matchmake_session_attribute(client, gid, attribs) async def handle_get_friend_notification_data_list(self, client, input, output): logger.info("MatchmakeExtensionServer.get_friend_notification_data_list()") #--- request --- types = input.list(input.u32) response = await self.get_friend_notification_data_list(client, types) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_update_matchmake_session(self, client, input, output): logger.info("MatchmakeExtensionServer.update_matchmake_session()") #--- request --- gathering = input.anydata() await self.update_matchmake_session(client, gathering) async def handle_auto_matchmake_with_search_criteria_postpone(self, client, input, output): logger.info("MatchmakeExtensionServer.auto_matchmake_with_search_criteria_postpone()") #--- request --- search_criteria = input.list(MatchmakeSessionSearchCriteria) gathering = input.anydata() message = input.string() response = await self.auto_matchmake_with_search_criteria_postpone(client, search_criteria, gathering, message) #--- response --- if not isinstance(response, Gathering): raise RuntimeError("Expected Gathering, got %s" %response.__class__.__name__) output.anydata(response) async def handle_get_playing_session(self, client, input, output): logger.info("MatchmakeExtensionServer.get_playing_session()") #--- request --- pids = input.list(input.pid) response = await self.get_playing_session(client, pids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_create_community(self, client, input, output): logger.info("MatchmakeExtensionServer.create_community()") #--- request --- community = input.extract(PersistentGathering) message = input.string() response = await self.create_community(client, community, message) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u32(response) async def handle_update_community(self, client, input, output): logger.info("MatchmakeExtensionServer.update_community()") #--- request --- community = input.extract(PersistentGathering) await self.update_community(client, community) async def handle_join_community(self, client, input, output): logger.info("MatchmakeExtensionServer.join_community()") #--- request --- gid = input.u32() message = input.string() password = input.string() await self.join_community(client, gid, message, password) async def handle_find_community_by_gathering_id(self, client, input, output): logger.info("MatchmakeExtensionServer.find_community_by_gathering_id()") #--- request --- gids = input.list(input.u32) response = await self.find_community_by_gathering_id(client, gids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_find_official_community(self, client, input, output): logger.info("MatchmakeExtensionServer.find_official_community()") #--- request --- available_only = input.bool() range = input.extract(common.ResultRange) response = await self.find_official_community(client, available_only, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_find_community_by_participant(self, client, input, output): logger.info("MatchmakeExtensionServer.find_community_by_participant()") #--- request --- pid = input.pid() range = input.extract(common.ResultRange) response = await self.find_community_by_participant(client, pid, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_update_privacy_setting(self, client, input, output): logger.info("MatchmakeExtensionServer.update_privacy_setting()") #--- request --- online_status = input.bool() community_participation = input.bool() await self.update_privacy_setting(client, online_status, community_participation) async def handle_get_my_block_list(self, client, input, output): logger.info("MatchmakeExtensionServer.get_my_block_list()") #--- request --- response = await self.get_my_block_list(client) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.pid) async def handle_add_to_block_list(self, client, input, output): logger.info("MatchmakeExtensionServer.add_to_block_list()") #--- request --- pids = input.list(input.pid) await self.add_to_block_list(client, pids) async def handle_remove_from_block_list(self, client, input, output): logger.info("MatchmakeExtensionServer.remove_from_block_list()") #--- request --- pids = input.list(input.pid) await self.remove_from_block_list(client, pids) async def handle_clear_my_block_list(self, client, input, output): logger.info("MatchmakeExtensionServer.clear_my_block_list()") #--- request --- await self.clear_my_block_list(client) async def handle_report_violation(self, client, input, output): logger.info("MatchmakeExtensionServer.report_violation()") #--- request --- pid = input.pid() username = input.string() violation_code = input.u32() await self.report_violation(client, pid, username, violation_code) async def handle_is_violation_user(self, client, input, output): logger.info("MatchmakeExtensionServer.is_violation_user()") #--- request --- response = await self.is_violation_user(client) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['flag', 'score']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.flag) output.u32(response.score) async def handle_join_matchmake_session_ex(self, client, input, output): logger.info("MatchmakeExtensionServer.join_matchmake_session_ex()") #--- request --- gid = input.u32() gmessage = input.string() ignore_block_list = input.bool() num_participants = input.u16() response = await self.join_matchmake_session_ex(client, gid, gmessage, ignore_block_list, num_participants) #--- response --- if not isinstance(response, bytes): raise RuntimeError("Expected bytes, got %s" %response.__class__.__name__) output.buffer(response) async def handle_get_simple_playing_session(self, client, input, output): logger.info("MatchmakeExtensionServer.get_simple_playing_session()") #--- request --- pids = input.list(input.pid) include_login_user = input.bool() response = await self.get_simple_playing_session(client, pids, include_login_user) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_simple_community(self, client, input, output): logger.info("MatchmakeExtensionServer.get_simple_community()") #--- request --- gids = input.list(input.u32) response = await self.get_simple_community(client, gids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_auto_matchmake_with_gathering_id_postpone(self, client, input, output): logger.info("MatchmakeExtensionServer.auto_matchmake_with_gathering_id_postpone()") #--- request --- gids = input.list(input.u32) gathering = input.anydata() message = input.string() response = await self.auto_matchmake_with_gathering_id_postpone(client, gids, gathering, message) #--- response --- if not isinstance(response, Gathering): raise RuntimeError("Expected Gathering, got %s" %response.__class__.__name__) output.anydata(response) async def handle_update_progress_score(self, client, input, output): logger.info("MatchmakeExtensionServer.update_progress_score()") #--- request --- gid = input.u32() score = input.u8() await self.update_progress_score(client, gid, score) async def handle_debug_notify_event(self, client, input, output): logger.info("MatchmakeExtensionServer.debug_notify_event()") #--- request --- pid = input.pid() main_type = input.u32() sub_type = input.u32() param1 = input.u64() param2 = input.u64() param3 = input.string() await self.debug_notify_event(client, pid, main_type, sub_type, param1, param2, param3) async def handle_generate_matchmake_session_system_password(self, client, input, output): logger.info("MatchmakeExtensionServer.generate_matchmake_session_system_password()") #--- request --- gid = input.u32() response = await self.generate_matchmake_session_system_password(client, gid) #--- response --- if not isinstance(response, str): raise RuntimeError("Expected str, got %s" %response.__class__.__name__) output.string(response) async def handle_clear_matchmake_session_system_password(self, client, input, output): logger.info("MatchmakeExtensionServer.clear_matchmake_session_system_password()") #--- request --- gid = input.u32() await self.clear_matchmake_session_system_password(client, gid) async def handle_create_matchmake_session_with_param(self, client, input, output): logger.info("MatchmakeExtensionServer.create_matchmake_session_with_param()") #--- request --- param = input.extract(CreateMatchmakeSessionParam) response = await self.create_matchmake_session_with_param(client, param) #--- response --- if not isinstance(response, MatchmakeSession): raise RuntimeError("Expected MatchmakeSession, got %s" %response.__class__.__name__) output.add(response) async def handle_join_matchmake_session_with_param(self, client, input, output): logger.info("MatchmakeExtensionServer.join_matchmake_session_with_param()") #--- request --- param = input.extract(JoinMatchmakeSessionParam) response = await self.join_matchmake_session_with_param(client, param) #--- response --- if not isinstance(response, MatchmakeSession): raise RuntimeError("Expected MatchmakeSession, got %s" %response.__class__.__name__) output.add(response) async def handle_auto_matchmake_with_param_postpone(self, client, input, output): logger.info("MatchmakeExtensionServer.auto_matchmake_with_param_postpone()") #--- request --- param = input.extract(AutoMatchmakeParam) response = await self.auto_matchmake_with_param_postpone(client, param) #--- response --- if not isinstance(response, MatchmakeSession): raise RuntimeError("Expected MatchmakeSession, got %s" %response.__class__.__name__) output.add(response) async def handle_find_matchmake_session_by_gathering_id_detail(self, client, input, output): logger.info("MatchmakeExtensionServer.find_matchmake_session_by_gathering_id_detail()") #--- request --- gid = input.u32() response = await self.find_matchmake_session_by_gathering_id_detail(client, gid) #--- response --- if not isinstance(response, MatchmakeSession): raise RuntimeError("Expected MatchmakeSession, got %s" %response.__class__.__name__) output.add(response) async def handle_browse_matchmake_session_no_holder(self, client, input, output): logger.info("MatchmakeExtensionServer.browse_matchmake_session_no_holder()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) range = input.extract(common.ResultRange) response = await self.browse_matchmake_session_no_holder(client, search_criteria, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_browse_matchmake_session_with_host_urls_no_holder(self, client, input, output): logger.info("MatchmakeExtensionServer.browse_matchmake_session_with_host_urls_no_holder()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) range = input.extract(common.ResultRange) response = await self.browse_matchmake_session_with_host_urls_no_holder(client, search_criteria, range) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['sessions', 'urls']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.sessions, output.add) output.list(response.urls, output.add) async def handle_update_matchmake_session_part(self, client, input, output): logger.info("MatchmakeExtensionServer.update_matchmake_session_part()") #--- request --- param = input.extract(UpdateMatchmakeSessionParam) await self.update_matchmake_session_part(client, param) async def handle_request_matchmaking(self, client, input, output): logger.info("MatchmakeExtensionServer.request_matchmaking()") #--- request --- param = input.extract(AutoMatchmakeParam) response = await self.request_matchmaking(client, param) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u64(response) async def handle_withdraw_matchmaking(self, client, input, output): logger.info("MatchmakeExtensionServer.withdraw_matchmaking()") #--- request --- request_id = input.u64() await self.withdraw_matchmaking(client, request_id) async def handle_withdraw_matchmaking_all(self, client, input, output): logger.info("MatchmakeExtensionServer.withdraw_matchmaking_all()") #--- request --- await self.withdraw_matchmaking_all(client) async def handle_find_matchmake_session_by_gathering_id(self, client, input, output): logger.info("MatchmakeExtensionServer.find_matchmake_session_by_gathering_id()") #--- request --- gids = input.list(input.u32) response = await self.find_matchmake_session_by_gathering_id(client, gids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_find_matchmake_session_by_single_gathering_id(self, client, input, output): logger.info("MatchmakeExtensionServer.find_matchmake_session_by_single_gathering_id()") #--- request --- gid = input.u32() response = await self.find_matchmake_session_by_single_gathering_id(client, gid) #--- response --- if not isinstance(response, MatchmakeSession): raise RuntimeError("Expected MatchmakeSession, got %s" %response.__class__.__name__) output.add(response) async def handle_find_matchmake_session_by_owner(self, client, input, output): logger.info("MatchmakeExtensionServer.find_matchmake_session_by_owner()") #--- request --- pid = input.pid() range = input.extract(common.ResultRange) response = await self.find_matchmake_session_by_owner(client, pid, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_find_matchmake_session_by_participant(self, client, input, output): logger.info("MatchmakeExtensionServer.find_matchmake_session_by_participant()") #--- request --- param = input.extract(FindMatchmakeSessionByParticipantParam) response = await self.find_matchmake_session_by_participant(client, param) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_browse_matchmake_session_no_holder_no_result_range(self, client, input, output): logger.info("MatchmakeExtensionServer.browse_matchmake_session_no_holder_no_result_range()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) response = await self.browse_matchmake_session_no_holder_no_result_range(client, search_criteria) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_browse_matchmake_session_with_host_urls_no_holder_no_result_range(self, client, input, output): logger.info("MatchmakeExtensionServer.browse_matchmake_session_with_host_urls_no_holder_no_result_range()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) response = await self.browse_matchmake_session_with_host_urls_no_holder_no_result_range(client, search_criteria) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['sessions', 'urls']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.sessions, output.add) output.list(response.urls, output.add) async def close_participation(self, *args): logger.warning("MatchmakeExtensionServer.close_participation not implemented") raise common.RMCError("Core::NotImplemented") async def open_participation(self, *args): logger.warning("MatchmakeExtensionServer.open_participation not implemented") raise common.RMCError("Core::NotImplemented") async def auto_matchmake_postpone(self, *args): logger.warning("MatchmakeExtensionServer.auto_matchmake_postpone not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session(self, *args): logger.warning("MatchmakeExtensionServer.browse_matchmake_session not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session_with_host_urls(self, *args): logger.warning("MatchmakeExtensionServer.browse_matchmake_session_with_host_urls not implemented") raise common.RMCError("Core::NotImplemented") async def create_matchmake_session(self, *args): logger.warning("MatchmakeExtensionServer.create_matchmake_session not implemented") raise common.RMCError("Core::NotImplemented") async def join_matchmake_session(self, *args): logger.warning("MatchmakeExtensionServer.join_matchmake_session not implemented") raise common.RMCError("Core::NotImplemented") async def modify_current_game_attribute(self, *args): logger.warning("MatchmakeExtensionServer.modify_current_game_attribute not implemented") raise common.RMCError("Core::NotImplemented") async def update_notification_data(self, *args): logger.warning("MatchmakeExtensionServer.update_notification_data not implemented") raise common.RMCError("Core::NotImplemented") async def get_friend_notification_data(self, *args): logger.warning("MatchmakeExtensionServer.get_friend_notification_data not implemented") raise common.RMCError("Core::NotImplemented") async def update_application_buffer(self, *args): logger.warning("MatchmakeExtensionServer.update_application_buffer not implemented") raise common.RMCError("Core::NotImplemented") async def update_matchmake_session_attribute(self, *args): logger.warning("MatchmakeExtensionServer.update_matchmake_session_attribute not implemented") raise common.RMCError("Core::NotImplemented") async def get_friend_notification_data_list(self, *args): logger.warning("MatchmakeExtensionServer.get_friend_notification_data_list not implemented") raise common.RMCError("Core::NotImplemented") async def update_matchmake_session(self, *args): logger.warning("MatchmakeExtensionServer.update_matchmake_session not implemented") raise common.RMCError("Core::NotImplemented") async def auto_matchmake_with_search_criteria_postpone(self, *args): logger.warning("MatchmakeExtensionServer.auto_matchmake_with_search_criteria_postpone not implemented") raise common.RMCError("Core::NotImplemented") async def get_playing_session(self, *args): logger.warning("MatchmakeExtensionServer.get_playing_session not implemented") raise common.RMCError("Core::NotImplemented") async def create_community(self, *args): logger.warning("MatchmakeExtensionServer.create_community not implemented") raise common.RMCError("Core::NotImplemented") async def update_community(self, *args): logger.warning("MatchmakeExtensionServer.update_community not implemented") raise common.RMCError("Core::NotImplemented") async def join_community(self, *args): logger.warning("MatchmakeExtensionServer.join_community not implemented") raise common.RMCError("Core::NotImplemented") async def find_community_by_gathering_id(self, *args): logger.warning("MatchmakeExtensionServer.find_community_by_gathering_id not implemented") raise common.RMCError("Core::NotImplemented") async def find_official_community(self, *args): logger.warning("MatchmakeExtensionServer.find_official_community not implemented") raise common.RMCError("Core::NotImplemented") async def find_community_by_participant(self, *args): logger.warning("MatchmakeExtensionServer.find_community_by_participant not implemented") raise common.RMCError("Core::NotImplemented") async def update_privacy_setting(self, *args): logger.warning("MatchmakeExtensionServer.update_privacy_setting not implemented") raise common.RMCError("Core::NotImplemented") async def get_my_block_list(self, *args): logger.warning("MatchmakeExtensionServer.get_my_block_list not implemented") raise common.RMCError("Core::NotImplemented") async def add_to_block_list(self, *args): logger.warning("MatchmakeExtensionServer.add_to_block_list not implemented") raise common.RMCError("Core::NotImplemented") async def remove_from_block_list(self, *args): logger.warning("MatchmakeExtensionServer.remove_from_block_list not implemented") raise common.RMCError("Core::NotImplemented") async def clear_my_block_list(self, *args): logger.warning("MatchmakeExtensionServer.clear_my_block_list not implemented") raise common.RMCError("Core::NotImplemented") async def report_violation(self, *args): logger.warning("MatchmakeExtensionServer.report_violation not implemented") raise common.RMCError("Core::NotImplemented") async def is_violation_user(self, *args): logger.warning("MatchmakeExtensionServer.is_violation_user not implemented") raise common.RMCError("Core::NotImplemented") async def join_matchmake_session_ex(self, *args): logger.warning("MatchmakeExtensionServer.join_matchmake_session_ex not implemented") raise common.RMCError("Core::NotImplemented") async def get_simple_playing_session(self, *args): logger.warning("MatchmakeExtensionServer.get_simple_playing_session not implemented") raise common.RMCError("Core::NotImplemented") async def get_simple_community(self, *args): logger.warning("MatchmakeExtensionServer.get_simple_community not implemented") raise common.RMCError("Core::NotImplemented") async def auto_matchmake_with_gathering_id_postpone(self, *args): logger.warning("MatchmakeExtensionServer.auto_matchmake_with_gathering_id_postpone not implemented") raise common.RMCError("Core::NotImplemented") async def update_progress_score(self, *args): logger.warning("MatchmakeExtensionServer.update_progress_score not implemented") raise common.RMCError("Core::NotImplemented") async def debug_notify_event(self, *args): logger.warning("MatchmakeExtensionServer.debug_notify_event not implemented") raise common.RMCError("Core::NotImplemented") async def generate_matchmake_session_system_password(self, *args): logger.warning("MatchmakeExtensionServer.generate_matchmake_session_system_password not implemented") raise common.RMCError("Core::NotImplemented") async def clear_matchmake_session_system_password(self, *args): logger.warning("MatchmakeExtensionServer.clear_matchmake_session_system_password not implemented") raise common.RMCError("Core::NotImplemented") async def create_matchmake_session_with_param(self, *args): logger.warning("MatchmakeExtensionServer.create_matchmake_session_with_param not implemented") raise common.RMCError("Core::NotImplemented") async def join_matchmake_session_with_param(self, *args): logger.warning("MatchmakeExtensionServer.join_matchmake_session_with_param not implemented") raise common.RMCError("Core::NotImplemented") async def auto_matchmake_with_param_postpone(self, *args): logger.warning("MatchmakeExtensionServer.auto_matchmake_with_param_postpone not implemented") raise common.RMCError("Core::NotImplemented") async def find_matchmake_session_by_gathering_id_detail(self, *args): logger.warning("MatchmakeExtensionServer.find_matchmake_session_by_gathering_id_detail not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session_no_holder(self, *args): logger.warning("MatchmakeExtensionServer.browse_matchmake_session_no_holder not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session_with_host_urls_no_holder(self, *args): logger.warning("MatchmakeExtensionServer.browse_matchmake_session_with_host_urls_no_holder not implemented") raise common.RMCError("Core::NotImplemented") async def update_matchmake_session_part(self, *args): logger.warning("MatchmakeExtensionServer.update_matchmake_session_part not implemented") raise common.RMCError("Core::NotImplemented") async def request_matchmaking(self, *args): logger.warning("MatchmakeExtensionServer.request_matchmaking not implemented") raise common.RMCError("Core::NotImplemented") async def withdraw_matchmaking(self, *args): logger.warning("MatchmakeExtensionServer.withdraw_matchmaking not implemented") raise common.RMCError("Core::NotImplemented") async def withdraw_matchmaking_all(self, *args): logger.warning("MatchmakeExtensionServer.withdraw_matchmaking_all not implemented") raise common.RMCError("Core::NotImplemented") async def find_matchmake_session_by_gathering_id(self, *args): logger.warning("MatchmakeExtensionServer.find_matchmake_session_by_gathering_id not implemented") raise common.RMCError("Core::NotImplemented") async def find_matchmake_session_by_single_gathering_id(self, *args): logger.warning("MatchmakeExtensionServer.find_matchmake_session_by_single_gathering_id not implemented") raise common.RMCError("Core::NotImplemented") async def find_matchmake_session_by_owner(self, *args): logger.warning("MatchmakeExtensionServer.find_matchmake_session_by_owner not implemented") raise common.RMCError("Core::NotImplemented") async def find_matchmake_session_by_participant(self, *args): logger.warning("MatchmakeExtensionServer.find_matchmake_session_by_participant not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session_no_holder_no_result_range(self, *args): logger.warning("MatchmakeExtensionServer.browse_matchmake_session_no_holder_no_result_range not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session_with_host_urls_no_holder_no_result_range(self, *args): logger.warning("MatchmakeExtensionServer.browse_matchmake_session_with_host_urls_no_holder_no_result_range not implemented") raise common.RMCError("Core::NotImplemented") class MatchmakeRefereeServer(MatchmakeRefereeProtocol): def __init__(self): self.methods = { self.METHOD_START_ROUND: self.handle_start_round, self.METHOD_GET_START_ROUND_PARAM: self.handle_get_start_round_param, self.METHOD_END_ROUND: self.handle_end_round, self.METHOD_END_ROUND_WITHOUT_REPORT: self.handle_end_round_without_report, self.METHOD_GET_ROUND_PARTICIPANTS: self.handle_get_round_participants, self.METHOD_GET_NOT_SUMMARIZED_ROUND: self.handle_get_not_summarized_round, self.METHOD_GET_ROUND: self.handle_get_round, self.METHOD_GET_STATS_PRIMARY: self.handle_get_stats_primary, self.METHOD_GET_STATS_PRIMARIES: self.handle_get_stats_primaries, self.METHOD_GET_STATS_ALL: self.handle_get_stats_all, self.METHOD_CREATE_STATS: self.handle_create_stats, self.METHOD_GET_OR_CREATE_STATS: self.handle_get_or_create_stats, self.METHOD_RESET_STATS: self.handle_reset_stats, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on MatchmakeRefereeServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_start_round(self, client, input, output): logger.info("MatchmakeRefereeServer.start_round()") #--- request --- param = input.extract(MatchmakeRefereeStartRoundParam) response = await self.start_round(client, param) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u64(response) async def handle_get_start_round_param(self, client, input, output): logger.info("MatchmakeRefereeServer.get_start_round_param()") #--- request --- round_id = input.u64() response = await self.get_start_round_param(client, round_id) #--- response --- if not isinstance(response, MatchmakeRefereeStartRoundParam): raise RuntimeError("Expected MatchmakeRefereeStartRoundParam, got %s" %response.__class__.__name__) output.add(response) async def handle_end_round(self, client, input, output): logger.info("MatchmakeRefereeServer.end_round()") #--- request --- param = input.extract(MatchmakeRefereeEndRoundParam) await self.end_round(client, param) async def handle_end_round_without_report(self, client, input, output): logger.info("MatchmakeRefereeServer.end_round_without_report()") #--- request --- round_id = input.u64() await self.end_round_without_report(client, round_id) async def handle_get_round_participants(self, client, input, output): logger.info("MatchmakeRefereeServer.get_round_participants()") #--- request --- round_id = input.u64() response = await self.get_round_participants(client, round_id) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.pid) async def handle_get_not_summarized_round(self, client, input, output): logger.info("MatchmakeRefereeServer.get_not_summarized_round()") #--- request --- response = await self.get_not_summarized_round(client) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_round(self, client, input, output): logger.info("MatchmakeRefereeServer.get_round()") #--- request --- round = input.u64() response = await self.get_round(client, round) #--- response --- if not isinstance(response, MatchmakeRefereeRound): raise RuntimeError("Expected MatchmakeRefereeRound, got %s" %response.__class__.__name__) output.add(response) async def handle_get_stats_primary(self, client, input, output): logger.info("MatchmakeRefereeServer.get_stats_primary()") #--- request --- target = input.extract(MatchmakeRefereeStatsTarget) response = await self.get_stats_primary(client, target) #--- response --- if not isinstance(response, MatchmakeRefereeStats): raise RuntimeError("Expected MatchmakeRefereeStats, got %s" %response.__class__.__name__) output.add(response) async def handle_get_stats_primaries(self, client, input, output): logger.info("MatchmakeRefereeServer.get_stats_primaries()") #--- request --- targets = input.list(MatchmakeRefereeStatsTarget) response = await self.get_stats_primaries(client, targets) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['stats', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.stats, output.add) output.list(response.results, output.result) async def handle_get_stats_all(self, client, input, output): logger.info("MatchmakeRefereeServer.get_stats_all()") #--- request --- target = input.extract(MatchmakeRefereeStatsTarget) response = await self.get_stats_all(client, target) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_create_stats(self, client, input, output): logger.info("MatchmakeRefereeServer.create_stats()") #--- request --- param = input.extract(MatchmakeRefereeStatsInitParam) response = await self.create_stats(client, param) #--- response --- if not isinstance(response, MatchmakeRefereeStats): raise RuntimeError("Expected MatchmakeRefereeStats, got %s" %response.__class__.__name__) output.add(response) async def handle_get_or_create_stats(self, client, input, output): logger.info("MatchmakeRefereeServer.get_or_create_stats()") #--- request --- param = input.extract(MatchmakeRefereeStatsInitParam) response = await self.get_or_create_stats(client, param) #--- response --- if not isinstance(response, MatchmakeRefereeStats): raise RuntimeError("Expected MatchmakeRefereeStats, got %s" %response.__class__.__name__) output.add(response) async def handle_reset_stats(self, client, input, output): logger.info("MatchmakeRefereeServer.reset_stats()") #--- request --- await self.reset_stats(client) async def start_round(self, *args): logger.warning("MatchmakeRefereeServer.start_round not implemented") raise common.RMCError("Core::NotImplemented") async def get_start_round_param(self, *args): logger.warning("MatchmakeRefereeServer.get_start_round_param not implemented") raise common.RMCError("Core::NotImplemented") async def end_round(self, *args): logger.warning("MatchmakeRefereeServer.end_round not implemented") raise common.RMCError("Core::NotImplemented") async def end_round_without_report(self, *args): logger.warning("MatchmakeRefereeServer.end_round_without_report not implemented") raise common.RMCError("Core::NotImplemented") async def get_round_participants(self, *args): logger.warning("MatchmakeRefereeServer.get_round_participants not implemented") raise common.RMCError("Core::NotImplemented") async def get_not_summarized_round(self, *args): logger.warning("MatchmakeRefereeServer.get_not_summarized_round not implemented") raise common.RMCError("Core::NotImplemented") async def get_round(self, *args): logger.warning("MatchmakeRefereeServer.get_round not implemented") raise common.RMCError("Core::NotImplemented") async def get_stats_primary(self, *args): logger.warning("MatchmakeRefereeServer.get_stats_primary not implemented") raise common.RMCError("Core::NotImplemented") async def get_stats_primaries(self, *args): logger.warning("MatchmakeRefereeServer.get_stats_primaries not implemented") raise common.RMCError("Core::NotImplemented") async def get_stats_all(self, *args): logger.warning("MatchmakeRefereeServer.get_stats_all not implemented") raise common.RMCError("Core::NotImplemented") async def create_stats(self, *args): logger.warning("MatchmakeRefereeServer.create_stats not implemented") raise common.RMCError("Core::NotImplemented") async def get_or_create_stats(self, *args): logger.warning("MatchmakeRefereeServer.get_or_create_stats not implemented") raise common.RMCError("Core::NotImplemented") async def reset_stats(self, *args): logger.warning("MatchmakeRefereeServer.reset_stats not implemented") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/matchmaking_eagle.py ================================================ # This file was generated automatically by generate_protocols.py from nintendo.nex import notification, rmc, common, streams import logging logger = logging.getLogger(__name__) class MatchmakeSystem: GLOBAL = 1 FRIENDS = 2 class Gathering(common.Structure): def __init__(self): super().__init__() self.id = 0 self.owner = 0 self.host = 0 self.min_participants = 0 self.max_participants = 0 self.participation_policy = 1 self.policy_argument = 0 self.flags = 512 self.state = 0 self.description = "" def check_required(self, settings, version): pass def load(self, stream, version): self.id = stream.u32() self.owner = stream.pid() self.host = stream.pid() self.min_participants = stream.u16() self.max_participants = stream.u16() self.participation_policy = stream.u32() self.policy_argument = stream.u32() self.flags = stream.u32() self.state = stream.u32() self.description = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.id) stream.pid(self.owner) stream.pid(self.host) stream.u16(self.min_participants) stream.u16(self.max_participants) stream.u32(self.participation_policy) stream.u32(self.policy_argument) stream.u32(self.flags) stream.u32(self.state) stream.string(self.description) class GatheringURLs(common.Structure): def __init__(self): super().__init__() self.gid = None self.urls = None def check_required(self, settings, version): for field in ['gid', 'urls']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.gid = stream.u32() self.urls = stream.list(stream.stationurl) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.gid) stream.list(self.urls, stream.stationurl) class GatheringStats(common.Structure): def __init__(self): super().__init__() self.pid = None self.flags = None self.values = None def check_required(self, settings, version): for field in ['pid', 'flags', 'values']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.flags = stream.u32() self.values = stream.list(stream.float) def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.u32(self.flags) stream.list(self.values, stream.float) class Invitation(common.Structure): def __init__(self): super().__init__() self.gid = None self.guest = None self.message = None def check_required(self, settings, version): for field in ['gid', 'guest', 'message']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.gid = stream.u32() self.guest = stream.u32() self.message = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.gid) stream.u32(self.guest) stream.string(self.message) class ParticipantDetails(common.Structure): def __init__(self): super().__init__() self.pid = None self.name = None self.message = None self.participants = None def check_required(self, settings, version): for field in ['pid', 'name', 'message', 'participants']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.name = stream.string() self.message = stream.string() self.participants = stream.u16() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.string(self.name) stream.string(self.message) stream.u16(self.participants) class DeletionEntry(common.Structure): def __init__(self): super().__init__() self.gid = None self.pid = None self.reason = None def check_required(self, settings, version): for field in ['gid', 'pid', 'reason']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.gid = stream.u32() self.pid = stream.pid() self.reason = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.gid) stream.pid(self.pid) stream.u32(self.reason) class MatchmakeParam(common.Structure): def __init__(self): super().__init__() self.param = {} def check_required(self, settings, version): pass def load(self, stream, version): self.param = stream.map(stream.string, stream.variant) def save(self, stream, version): self.check_required(stream.settings, version) stream.map(self.param, stream.string, stream.variant) class MatchmakeSessionSearchCriteria(common.Structure): def __init__(self): super().__init__() self.attribs = ["", "", "", "", "", ""] self.game_mode = "" self.min_participants = "" self.max_participants = "" self.matchmake_system = "" self.vacant_only = True self.exclude_locked = True self.exclude_non_host_pid = False self.selection_method = 0 self.vacant_participants = 1 self.param = MatchmakeParam() self.exclude_user_password = False self.exclude_system_password = False self.refer_gid = 0 self.codeword = "" self.range = common.ResultRange() def check_required(self, settings, version): if settings["nex.version"] >= 30500: pass if settings["nex.version"] >= 40000: pass def load(self, stream, version): self.attribs = stream.list(stream.string) self.game_mode = stream.string() self.min_participants = stream.string() self.max_participants = stream.string() self.matchmake_system = stream.string() self.vacant_only = stream.bool() self.exclude_locked = stream.bool() self.exclude_non_host_pid = stream.bool() self.selection_method = stream.u32() if stream.settings["nex.version"] >= 30500: self.vacant_participants = stream.u16() if stream.settings["nex.version"] >= 40000: self.param = stream.extract(MatchmakeParam) self.exclude_user_password = stream.bool() self.exclude_system_password = stream.bool() self.refer_gid = stream.u32() self.codeword = stream.string() self.range = stream.extract(common.ResultRange) def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.attribs, stream.string) stream.string(self.game_mode) stream.string(self.min_participants) stream.string(self.max_participants) stream.string(self.matchmake_system) stream.bool(self.vacant_only) stream.bool(self.exclude_locked) stream.bool(self.exclude_non_host_pid) stream.u32(self.selection_method) if stream.settings["nex.version"] >= 30500: stream.u16(self.vacant_participants) if stream.settings["nex.version"] >= 40000: stream.add(self.param) stream.bool(self.exclude_user_password) stream.bool(self.exclude_system_password) stream.u32(self.refer_gid) stream.string(self.codeword) stream.add(self.range) class MatchmakeSession(Gathering): def __init__(self): super().__init__() self.game_mode = 0 self.attribs = [0, 0, 0, 0, 0, 0] self.open_participation = True self.matchmake_system = 0 self.application_data = b"" self.num_participants = 0 self.progress_score = 100 self.session_key = b"" self.option = 0 self.param = MatchmakeParam() self.started_time = common.DateTime(0) self.user_password = "" self.refer_gid = 0 self.user_password_enabled = False self.system_password_enabled = False self.codeword = "" def max_version(self, settings): version = 0 if 30000 <= settings["nex.version"] < 40000: if settings["nex.version"] >= 30600: version = 1 if settings["nex.version"] >= 30700: version = 2 if settings["nex.version"] >= 30800: version = 3 return version def check_required(self, settings, version): if 30000 <= settings["nex.version"] < 40000: if settings["nex.version"] >= 30500: pass if settings["nex.version"] >= 30000: pass if settings["nex.version"] >= 30500: pass if settings["nex.version"] >= 30600: if version >= 1: pass if settings["nex.version"] >= 30700: if version >= 2: pass if settings["nex.version"] >= 30800: if version >= 3: pass if settings["nex.version"] >= 40000: pass def load(self, stream, version): self.game_mode = stream.u32() self.attribs = stream.list(stream.u32) self.open_participation = stream.bool() self.matchmake_system = stream.u32() self.application_data = stream.buffer() self.num_participants = stream.u32() if 30000 <= stream.settings["nex.version"] < 40000: if stream.settings["nex.version"] >= 30500: self.progress_score = stream.u8() if stream.settings["nex.version"] >= 30000: self.session_key = stream.buffer() if stream.settings["nex.version"] >= 30500: self.option = stream.u32() if stream.settings["nex.version"] >= 30600: if version >= 1: self.param = stream.extract(MatchmakeParam) self.started_time = stream.datetime() if stream.settings["nex.version"] >= 30700: if version >= 2: self.user_password = stream.string() if stream.settings["nex.version"] >= 30800: if version >= 3: self.refer_gid = stream.u32() self.user_password_enabled = stream.bool() self.system_password_enabled = stream.bool() if stream.settings["nex.version"] >= 40000: self.progress_score = stream.u8() self.session_key = stream.buffer() self.option = stream.u32() self.param = stream.extract(MatchmakeParam) self.started_time = stream.datetime() self.user_password = stream.string() self.refer_gid = stream.u32() self.user_password_enabled = stream.bool() self.system_password_enabled = stream.bool() self.codeword = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.game_mode) stream.list(self.attribs, stream.u32) stream.bool(self.open_participation) stream.u32(self.matchmake_system) stream.buffer(self.application_data) stream.u32(self.num_participants) if 30000 <= stream.settings["nex.version"] < 40000: if stream.settings["nex.version"] >= 30500: stream.u8(self.progress_score) if stream.settings["nex.version"] >= 30000: stream.buffer(self.session_key) if stream.settings["nex.version"] >= 30500: stream.u32(self.option) if stream.settings["nex.version"] >= 30600: if version >= 1: stream.add(self.param) stream.datetime(self.started_time) if stream.settings["nex.version"] >= 30700: if version >= 2: stream.string(self.user_password) if stream.settings["nex.version"] >= 30800: if version >= 3: stream.u32(self.refer_gid) stream.bool(self.user_password_enabled) stream.bool(self.system_password_enabled) if stream.settings["nex.version"] >= 40000: stream.u8(self.progress_score) stream.buffer(self.session_key) stream.u32(self.option) stream.add(self.param) stream.datetime(self.started_time) stream.string(self.user_password) stream.u32(self.refer_gid) stream.bool(self.user_password_enabled) stream.bool(self.system_password_enabled) stream.string(self.codeword) common.DataHolder.register(MatchmakeSession, "MatchmakeSession") class MatchmakeBlockListParam(common.Structure): def __init__(self): super().__init__() self.options = 0 def check_required(self, settings, version): pass def load(self, stream, version): self.options = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.options) class CreateMatchmakeSessionParam(common.Structure): def __init__(self): super().__init__() self.session = MatchmakeSession() self.additional_participants = None self.gid_for_participation_check = None self.options = None self.join_message = None self.num_participants = None def check_required(self, settings, version): for field in ['additional_participants', 'gid_for_participation_check', 'options', 'join_message', 'num_participants']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.session = stream.extract(MatchmakeSession) self.additional_participants = stream.list(stream.pid) self.gid_for_participation_check = stream.u32() self.options = stream.u32() self.join_message = stream.string() self.num_participants = stream.u16() def save(self, stream, version): self.check_required(stream.settings, version) stream.add(self.session) stream.list(self.additional_participants, stream.pid) stream.u32(self.gid_for_participation_check) stream.u32(self.options) stream.string(self.join_message) stream.u16(self.num_participants) class JoinMatchmakeSessionParam(common.Structure): def __init__(self): super().__init__() self.gid = None self.participants = None self.gid_for_participation_check = None self.options = None self.behavior = None self.user_password = None self.system_password = None self.join_message = None self.num_participants = None self.extra_participants = None self.block_list = MatchmakeBlockListParam() def check_required(self, settings, version): for field in ['gid', 'participants', 'gid_for_participation_check', 'options', 'behavior', 'user_password', 'system_password', 'join_message', 'num_participants', 'extra_participants']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.gid = stream.u32() self.participants = stream.list(stream.pid) self.gid_for_participation_check = stream.u32() self.options = stream.u32() self.behavior = stream.u8() self.user_password = stream.string() self.system_password = stream.string() self.join_message = stream.string() self.num_participants = stream.u16() self.extra_participants = stream.u16() self.block_list = stream.extract(MatchmakeBlockListParam) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.gid) stream.list(self.participants, stream.pid) stream.u32(self.gid_for_participation_check) stream.u32(self.options) stream.u8(self.behavior) stream.string(self.user_password) stream.string(self.system_password) stream.string(self.join_message) stream.u16(self.num_participants) stream.u16(self.extra_participants) stream.add(self.block_list) class UpdateMatchmakeSessionParam(common.Structure): def __init__(self): super().__init__() self.gid = None self.modification_flags = None self.attributes = None self.open_participation = None self.application_buffer = None self.progress_score = None self.param = MatchmakeParam() self.started_time = None self.user_password = None self.game_mode = None self.description = None self.min_participants = None self.max_participants = None self.matchmake_system = None self.participation_policy = None self.policy_argument = None self.codeword = None def check_required(self, settings, version): for field in ['gid', 'modification_flags', 'attributes', 'open_participation', 'application_buffer', 'progress_score', 'started_time', 'user_password', 'game_mode', 'description', 'min_participants', 'max_participants', 'matchmake_system', 'participation_policy', 'policy_argument', 'codeword']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.gid = stream.u32() self.modification_flags = stream.u32() self.attributes = stream.list(stream.u32) self.open_participation = stream.bool() self.application_buffer = stream.buffer() self.progress_score = stream.u8() self.param = stream.extract(MatchmakeParam) self.started_time = stream.datetime() self.user_password = stream.string() self.game_mode = stream.u32() self.description = stream.string() self.min_participants = stream.u16() self.max_participants = stream.u16() self.matchmake_system = stream.u32() self.participation_policy = stream.u32() self.policy_argument = stream.u32() self.codeword = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.gid) stream.u32(self.modification_flags) stream.list(self.attributes, stream.u32) stream.bool(self.open_participation) stream.buffer(self.application_buffer) stream.u8(self.progress_score) stream.add(self.param) stream.datetime(self.started_time) stream.string(self.user_password) stream.u32(self.game_mode) stream.string(self.description) stream.u16(self.min_participants) stream.u16(self.max_participants) stream.u32(self.matchmake_system) stream.u32(self.participation_policy) stream.u32(self.policy_argument) stream.string(self.codeword) class AutoMatchmakeParam(common.Structure): def __init__(self): super().__init__() self.session = MatchmakeSession() self.participants = None self.gid_for_participation_check = None self.options = None self.join_message = None self.num_participants = None self.search_criteria = None self.target_gids = None self.block_list = MatchmakeBlockListParam() def check_required(self, settings, version): for field in ['participants', 'gid_for_participation_check', 'options', 'join_message', 'num_participants', 'search_criteria', 'target_gids']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.session = stream.extract(MatchmakeSession) self.participants = stream.list(stream.pid) self.gid_for_participation_check = stream.u32() self.options = stream.u32() self.join_message = stream.string() self.num_participants = stream.u16() self.search_criteria = stream.list(MatchmakeSessionSearchCriteria) self.target_gids = stream.list(stream.u32) self.block_list = stream.extract(MatchmakeBlockListParam) def save(self, stream, version): self.check_required(stream.settings, version) stream.add(self.session) stream.list(self.participants, stream.pid) stream.u32(self.gid_for_participation_check) stream.u32(self.options) stream.string(self.join_message) stream.u16(self.num_participants) stream.list(self.search_criteria, stream.add) stream.list(self.target_gids, stream.u32) stream.add(self.block_list) class FindMatchmakeSessionByParticipantParam(common.Structure): def __init__(self): super().__init__() self.pids = None self.options = None self.block_list = MatchmakeBlockListParam() def check_required(self, settings, version): for field in ['pids', 'options']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pids = stream.list(stream.pid) self.options = stream.u32() self.block_list = stream.extract(MatchmakeBlockListParam) def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.pids, stream.pid) stream.u32(self.options) stream.add(self.block_list) class FindMatchmakeSessionByParticipantResult(common.Structure): def __init__(self): super().__init__() self.pid = None self.session = MatchmakeSession() def check_required(self, settings, version): for field in ['pid']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.session = stream.extract(MatchmakeSession) def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.add(self.session) class PersistentGathering(Gathering): def __init__(self): super().__init__() self.type = None self.password = None self.attribs = None self.application_buffer = None self.participation_start = None self.participation_end = None self.matchmake_session_count = None self.num_participants = None def check_required(self, settings, version): for field in ['type', 'password', 'attribs', 'application_buffer', 'participation_start', 'participation_end', 'matchmake_session_count', 'num_participants']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.type = stream.u32() self.password = stream.string() self.attribs = stream.list(stream.u32) self.application_buffer = stream.buffer() self.participation_start = stream.datetime() self.participation_end = stream.datetime() self.matchmake_session_count = stream.u32() self.num_participants = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.type) stream.string(self.password) stream.list(self.attribs, stream.u32) stream.buffer(self.application_buffer) stream.datetime(self.participation_start) stream.datetime(self.participation_end) stream.u32(self.matchmake_session_count) stream.u32(self.num_participants) common.DataHolder.register(PersistentGathering, "PersistentGathering") class SimpleCommunity(common.Structure): def __init__(self): super().__init__() self.gid = None self.matchmake_session_count = None def check_required(self, settings, version): for field in ['gid', 'matchmake_session_count']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.gid = stream.u32() self.matchmake_session_count = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.gid) stream.u32(self.matchmake_session_count) class PlayingSession(common.Structure): def __init__(self): super().__init__() self.pid = None self.gathering = None def check_required(self, settings, version): for field in ['pid', 'gathering']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.gathering = stream.anydata() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.anydata(self.gathering) class SimplePlayingSession(common.Structure): def __init__(self): super().__init__() self.pid = None self.gid = None self.game_mode = None self.attribute = None def check_required(self, settings, version): for field in ['pid', 'gid', 'game_mode', 'attribute']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.gid = stream.u32() self.game_mode = stream.u32() self.attribute = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.u32(self.gid) stream.u32(self.game_mode) stream.u32(self.attribute) class MatchmakeRefereeRound(common.Structure): def __init__(self): super().__init__() self.id = None self.gid = None self.state = None self.personal_data_category = None self.results = None def check_required(self, settings, version): for field in ['id', 'gid', 'state', 'personal_data_category', 'results']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.id = stream.u64() self.gid = stream.u32() self.state = stream.u32() self.personal_data_category = stream.u32() self.results = stream.list(MatchmakeRefereePersonalRoundResult) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.id) stream.u32(self.gid) stream.u32(self.state) stream.u32(self.personal_data_category) stream.list(self.results, stream.add) class MatchmakeRefereeStartRoundParam(common.Structure): def __init__(self): super().__init__() self.personal_data_category = None self.gid = None self.pids = None self.report_summary_mode = None self.event_id = None def check_required(self, settings, version): for field in ['personal_data_category', 'gid', 'pids', 'report_summary_mode', 'event_id']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.personal_data_category = stream.u32() self.gid = stream.u32() self.pids = stream.list(stream.pid) self.report_summary_mode = stream.u8() self.event_id = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.personal_data_category) stream.u32(self.gid) stream.list(self.pids, stream.pid) stream.u8(self.report_summary_mode) stream.u32(self.event_id) class MatchmakeRefereeEndRoundParam(common.Structure): def __init__(self): super().__init__() self.round_id = None self.results = None def check_required(self, settings, version): for field in ['round_id', 'results']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.round_id = stream.u64() self.results = stream.list(MatchmakeRefereePersonalRoundResult) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.round_id) stream.list(self.results, stream.add) class MatchmakeRefereePersonalRoundResult(common.Structure): def __init__(self): super().__init__() self.pid = None self.personal_round_result_flag = None self.round_win_loss = None self.rating_value_change = None self.buffer = None self.report_summary_mode = None self.event_id = None def check_required(self, settings, version): for field in ['pid', 'personal_round_result_flag', 'round_win_loss', 'rating_value_change', 'buffer', 'report_summary_mode', 'event_id']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.personal_round_result_flag = stream.u32() self.round_win_loss = stream.u32() self.rating_value_change = stream.s32() self.buffer = stream.qbuffer() self.report_summary_mode = stream.u8() self.event_id = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.u32(self.personal_round_result_flag) stream.u32(self.round_win_loss) stream.s32(self.rating_value_change) stream.qbuffer(self.buffer) stream.u8(self.report_summary_mode) stream.u32(self.event_id) class MatchmakeRefereeStats(common.Structure): def __init__(self): super().__init__() self.unique_id = None self.category = None self.pid = None self.recent_disconnection = None self.recent_violation = None self.recent_mismatch = None self.recent_win = None self.recent_loss = None self.recent_draw = None self.total_disconnect = None self.total_violation = None self.total_mismatch = None self.total_win = None self.total_loss = None self.total_draw = None self.rating_value = None def check_required(self, settings, version): for field in ['unique_id', 'category', 'pid', 'recent_disconnection', 'recent_violation', 'recent_mismatch', 'recent_win', 'recent_loss', 'recent_draw', 'total_disconnect', 'total_violation', 'total_mismatch', 'total_win', 'total_loss', 'total_draw', 'rating_value']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.unique_id = stream.u64() self.category = stream.u32() self.pid = stream.pid() self.recent_disconnection = stream.u32() self.recent_violation = stream.u32() self.recent_mismatch = stream.u32() self.recent_win = stream.u32() self.recent_loss = stream.u32() self.recent_draw = stream.u32() self.total_disconnect = stream.u32() self.total_violation = stream.u32() self.total_mismatch = stream.u32() self.total_win = stream.u32() self.total_loss = stream.u32() self.total_draw = stream.u32() self.rating_value = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.unique_id) stream.u32(self.category) stream.pid(self.pid) stream.u32(self.recent_disconnection) stream.u32(self.recent_violation) stream.u32(self.recent_mismatch) stream.u32(self.recent_win) stream.u32(self.recent_loss) stream.u32(self.recent_draw) stream.u32(self.total_disconnect) stream.u32(self.total_violation) stream.u32(self.total_mismatch) stream.u32(self.total_win) stream.u32(self.total_loss) stream.u32(self.total_draw) stream.u32(self.rating_value) class MatchmakeRefereeStatsTarget(common.Structure): def __init__(self): super().__init__() self.pid = None self.category = None def check_required(self, settings, version): for field in ['pid', 'category']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.category = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.u32(self.category) class MatchmakeRefereeStatsInitParam(common.Structure): def __init__(self): super().__init__() self.category = None self.initial_rating = None def check_required(self, settings, version): for field in ['category', 'initial_rating']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.category = stream.u32() self.initial_rating = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.category) stream.u32(self.initial_rating) class MatchMakingProtocol: METHOD_REGISTER_GATHERING = 1 METHOD_UNREGISTER_GATHERING = 2 METHOD_UNREGISTER_GATHERINGS = 3 METHOD_UPDATE_GATHERING = 4 METHOD_INVITE = 5 METHOD_ACCEPT_INVITATION = 6 METHOD_DECLINE_INVITATION = 7 METHOD_CANCEL_INVITATION = 8 METHOD_GET_INVITATIONS_SENT = 9 METHOD_GET_INVITATIONS_RECEIVED = 10 METHOD_PARTICIPATE = 11 METHOD_CANCEL_PARTICIPATION = 12 METHOD_GET_PARTICIPANTS = 13 METHOD_ADD_PARTICIPANTS = 14 METHOD_GET_DETAILED_PARTICIPANTS = 15 METHOD_GET_PARTICIPANTS_URLS = 16 METHOD_FIND_BY_TYPE = 17 METHOD_FIND_BY_DESCRIPTION = 18 METHOD_FIND_BY_DESCRIPTION_REGEX = 19 METHOD_FIND_BY_ID = 20 METHOD_FIND_BY_SINGLE_ID = 21 METHOD_FIND_BY_OWNER = 22 METHOD_FIND_BY_PARTICIPANTS = 23 METHOD_FIND_INVITATIONS = 24 METHOD_FIND_BY_SQL_QUERY = 25 METHOD_LAUNCH_SESSION = 26 METHOD_UPDATE_SESSION_URL = 27 METHOD_GET_SESSION_URL = 28 METHOD_GET_STATE = 29 METHOD_SET_STATE = 30 METHOD_REPORT_STATS = 31 METHOD_GET_STATS = 32 METHOD_DELETE_GATHERING = 33 METHOD_GET_PENDING_DELETIONS = 34 METHOD_DELETE_FROM_DELETIONS = 35 METHOD_MIGRATE_GATHERING_OWNERSHIP_V1 = 36 METHOD_FIND_BY_DESCRIPTION_LIKE = 37 METHOD_REGISTER_LOCAL_URL = 38 METHOD_REGISTER_LOCAL_URLS = 39 METHOD_UPDATE_SESSION_HOST_V1 = 40 METHOD_GET_SESSION_URLS = 41 METHOD_UPDATE_SESSION_HOST = 42 METHOD_UPDATE_GATHERING_OWNERSHIP = 43 METHOD_MIGRATE_GATHERING_OWNERSHIP = 44 PROTOCOL_ID = 0x15 class MatchMakingProtocolExt: METHOD_END_PARTICIPATION = 1 METHOD_GET_PARTICIPANTS = 2 METHOD_GET_DETAILED_PARTICIPANTS = 3 METHOD_GET_PARTICIPANTS_URLS = 4 METHOD_GET_GATHERING_RELATIONS = 5 METHOD_DELETE_FROM_DELETIONS = 6 PROTOCOL_ID = 0x32 class MatchmakeExtensionProtocol: METHOD_CLOSE_PARTICIPATION = 1 METHOD_OPEN_PARTICIPATION = 2 METHOD_AUTO_MATCHMAKE_POSTPONE = 3 METHOD_BROWSE_MATCHMAKE_SESSION = 4 METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS = 5 METHOD_CREATE_MATCHMAKE_SESSION = 6 METHOD_JOIN_MATCHMAKE_SESSION = 7 METHOD_MODIFY_CURRENT_GAME_ATTRIBUTE = 8 METHOD_UPDATE_NOTIFICATION_DATA = 9 METHOD_GET_FRIEND_NOTIFICATION_DATA = 10 METHOD_UPDATE_APPLICATION_BUFFER = 11 METHOD_UPDATE_MATCHMAKE_SESSION_ATTRIBUTE = 12 METHOD_GET_FRIEND_NOTIFICATION_DATA_LIST = 13 METHOD_UPDATE_MATCHMAKE_SESSION = 14 METHOD_AUTO_MATCHMAKE_WITH_SEARCH_CRITERIA_POSTPONE = 15 METHOD_GET_PLAYING_SESSION = 16 METHOD_CREATE_COMMUNITY = 17 METHOD_UPDATE_COMMUNITY = 18 METHOD_JOIN_COMMUNITY = 19 METHOD_FIND_COMMUNITY_BY_GATHERING_ID = 20 METHOD_FIND_OFFICIAL_COMMUNITY = 21 METHOD_FIND_COMMUNITY_BY_PARTICIPANT = 22 METHOD_UPDATE_PRIVACY_SETTING = 23 METHOD_GET_MY_BLOCK_LIST = 24 METHOD_ADD_TO_BLOCK_LIST = 25 METHOD_REMOVE_FROM_BLOCK_LIST = 26 METHOD_CLEAR_MY_BLOCK_LIST = 27 METHOD_REPORT_VIOLATION = 28 METHOD_IS_VIOLATION_USER = 29 METHOD_JOIN_MATCHMAKE_SESSION_EX = 30 METHOD_GET_SIMPLE_PLAYING_SESSION = 31 METHOD_GET_SIMPLE_COMMUNITY = 32 METHOD_AUTO_MATCHMAKE_WITH_GATHERING_ID_POSTPONE = 33 METHOD_UPDATE_PROGRESS_SCORE = 34 METHOD_DEBUG_NOTIFY_EVENT = 35 METHOD_GENERATE_MATCHMAKE_SESSION_SYSTEM_PASSWORD = 36 METHOD_CLEAR_MATCHMAKE_SESSION_SYSTEM_PASSWORD = 37 METHOD_CREATE_MATCHMAKE_SESSION_WITH_PARAM = 38 METHOD_JOIN_MATCHMAKE_SESSION_WITH_PARAM = 39 METHOD_AUTO_MATCHMAKE_WITH_PARAM_POSTPONE = 40 METHOD_FIND_MATCHMAKE_SESSION_BY_GATHERING_ID_DETAIL = 41 METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER = 42 METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER = 43 METHOD_UPDATE_MATCHMAKE_SESSION_PART = 44 METHOD_REQUEST_MATCHMAKING = 45 METHOD_WITHDRAW_MATCHMAKING = 46 METHOD_WITHDRAW_MATCHMAKING_ALL = 47 METHOD_FIND_MATCHMAKE_SESSION_BY_GATHERING_ID = 48 METHOD_FIND_MATCHMAKE_SESSION_BY_SINGLE_GATHERING_ID = 49 METHOD_FIND_MATCHMAKE_SESSION_BY_OWNER = 50 METHOD_FIND_MATCHMAKE_SESSION_BY_PARTICIPANT = 51 METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER_NO_RESULT_RANGE = 52 METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER_NO_RESULT_RANGE = 53 PROTOCOL_ID = 0x6D class MatchmakeRefereeProtocol: METHOD_START_ROUND = 1 METHOD_GET_START_ROUND_PARAM = 2 METHOD_END_ROUND = 3 METHOD_END_ROUND_WITH_PARTIAL_REPORT = 4 METHOD_END_ROUND_WITHOUT_REPORT = 5 METHOD_GET_ROUND_PARTICIPANTS = 6 METHOD_GET_NOT_SUMMARIZED_ROUND = 7 METHOD_GET_ROUND = 8 METHOD_GET_STATS_PRIMARY = 9 METHOD_GET_STATS_PRIMARIES = 10 METHOD_GET_STATS_ALL = 11 METHOD_CREATE_STATS = 12 METHOD_GET_OR_CREATE_STATS = 13 METHOD_RESET_STATS = 14 METHOD_GET_EVENT_POINT = 15 METHOD_RESET_EVENT_POINT = 16 PROTOCOL_ID = 0x78 class MatchMakingClient(MatchMakingProtocol): def __init__(self, client): self.settings = client.settings self.client = client async def register_gathering(self, gathering): logger.info("MatchMakingClient.register_gathering()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(gathering) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REGISTER_GATHERING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gid = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.register_gathering -> done") return gid async def unregister_gathering(self, gid): logger.info("MatchMakingClient.unregister_gathering()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UNREGISTER_GATHERING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.unregister_gathering -> done") return result async def unregister_gatherings(self, gids): logger.info("MatchMakingClient.unregister_gatherings()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UNREGISTER_GATHERINGS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.unregister_gatherings -> done") return result async def update_gathering(self, gathering): logger.info("MatchMakingClient.update_gathering()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(gathering) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_GATHERING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.update_gathering -> done") return result async def invite(self, gid, pids, message): logger.info("MatchMakingClient.invite()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(pids, stream.pid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_INVITE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.invite -> done") return result async def accept_invitation(self, gid, message): logger.info("MatchMakingClient.accept_invitation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_ACCEPT_INVITATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.accept_invitation -> done") return result async def decline_invitation(self, gid, message): logger.info("MatchMakingClient.decline_invitation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DECLINE_INVITATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.decline_invitation -> done") return result async def cancel_invitation(self, gid, pids, message): logger.info("MatchMakingClient.cancel_invitation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(pids, stream.pid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CANCEL_INVITATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.cancel_invitation -> done") return result async def get_invitations_sent(self, gid): logger.info("MatchMakingClient.get_invitations_sent()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_INVITATIONS_SENT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) invitations = stream.list(Invitation) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_invitations_sent -> done") return invitations async def get_invitations_received(self): logger.info("MatchMakingClient.get_invitations_received()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_INVITATIONS_RECEIVED, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) invitations = stream.list(Invitation) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_invitations_received -> done") return invitations async def participate(self, gid, message): logger.info("MatchMakingClient.participate()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PARTICIPATE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.participate -> done") return result async def cancel_participation(self, gid, message): logger.info("MatchMakingClient.cancel_participation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CANCEL_PARTICIPATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.cancel_participation -> done") return result async def get_participants(self, gid): logger.info("MatchMakingClient.get_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) participants = stream.list(stream.pid) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_participants -> done") return participants async def add_participants(self, gid, pids, message): logger.info("MatchMakingClient.add_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(pids, stream.pid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_ADD_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.add_participants -> done") return result async def get_detailed_participants(self, gid): logger.info("MatchMakingClient.get_detailed_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_DETAILED_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) details = stream.list(ParticipantDetails) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_detailed_participants -> done") return details async def get_participants_urls(self, gid): logger.info("MatchMakingClient.get_participants_urls()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PARTICIPANTS_URLS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) urls = stream.list(stream.stationurl) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_participants_urls -> done") return urls async def find_by_type(self, type, range): logger.info("MatchMakingClient.find_by_type()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(type) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_TYPE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_type -> done") return gatherings async def find_by_description(self, description, range): logger.info("MatchMakingClient.find_by_description()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(description) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_DESCRIPTION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_description -> done") return gatherings async def find_by_description_regex(self, regex, range): logger.info("MatchMakingClient.find_by_description_regex()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(regex) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_DESCRIPTION_REGEX, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_description_regex -> done") return gatherings async def find_by_id(self, ids): logger.info("MatchMakingClient.find_by_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(ids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_id -> done") return gatherings async def find_by_single_id(self, gid): logger.info("MatchMakingClient.find_by_single_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_SINGLE_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.gathering = stream.anydata() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_single_id -> done") return obj async def find_by_owner(self, owner, range): logger.info("MatchMakingClient.find_by_owner()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(owner) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_OWNER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_owner -> done") return gatherings async def find_by_participants(self, pids): logger.info("MatchMakingClient.find_by_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_participants -> done") return gatherings async def find_invitations(self, range): logger.info("MatchMakingClient.find_invitations()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_INVITATIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_invitations -> done") return gatherings async def find_by_sql_query(self, query, range): logger.info("MatchMakingClient.find_by_sql_query()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(query) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_SQL_QUERY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_sql_query -> done") return gatherings async def launch_session(self, gid, url): logger.info("MatchMakingClient.launch_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(url) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_LAUNCH_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.launch_session -> done") return result async def update_session_url(self, gid, url): logger.info("MatchMakingClient.update_session_url()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(url) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_SESSION_URL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.update_session_url -> done") return result async def get_session_url(self, gid): logger.info("MatchMakingClient.get_session_url()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SESSION_URL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.url = stream.string() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_session_url -> done") return obj async def get_state(self, gid): logger.info("MatchMakingClient.get_state()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.state = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_state -> done") return obj async def set_state(self, gid, state): logger.info("MatchMakingClient.set_state()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.u32(state) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SET_STATE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.set_state -> done") return result async def report_stats(self, gid, stats): logger.info("MatchMakingClient.report_stats()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(stats, stream.add) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REPORT_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.report_stats -> done") return result async def get_stats(self, gid, pids, columns): logger.info("MatchMakingClient.get_stats()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(pids, stream.pid) stream.list(columns, stream.u8) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.stats = stream.list(GatheringStats) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_stats -> done") return obj async def delete_gathering(self, gid): logger.info("MatchMakingClient.delete_gathering()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_GATHERING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.delete_gathering -> done") return result async def get_pending_deletions(self, reason, range): logger.info("MatchMakingClient.get_pending_deletions()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(reason) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PENDING_DELETIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.deletions = stream.list(DeletionEntry) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_pending_deletions -> done") return obj async def delete_from_deletions(self, deletions): logger.info("MatchMakingClient.delete_from_deletions()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(deletions, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_FROM_DELETIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.delete_from_deletions -> done") return result async def migrate_gathering_ownership_v1(self, gid, potential_owners): logger.info("MatchMakingClient.migrate_gathering_ownership_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(potential_owners, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_MIGRATE_GATHERING_OWNERSHIP_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.migrate_gathering_ownership_v1 -> done") return result async def find_by_description_like(self, description, range): logger.info("MatchMakingClient.find_by_description_like()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(description) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_DESCRIPTION_LIKE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_description_like -> done") return gatherings async def register_local_url(self, gid, url): logger.info("MatchMakingClient.register_local_url()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.stationurl(url) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REGISTER_LOCAL_URL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.register_local_url -> done") async def register_local_urls(self, gid, urls): logger.info("MatchMakingClient.register_local_urls()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(urls, stream.stationurl) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REGISTER_LOCAL_URLS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.register_local_urls -> done") async def update_session_host_v1(self, gid): logger.info("MatchMakingClient.update_session_host_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_SESSION_HOST_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.update_session_host_v1 -> done") async def get_session_urls(self, gid): logger.info("MatchMakingClient.get_session_urls()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SESSION_URLS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) urls = stream.list(stream.stationurl) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_session_urls -> done") return urls async def update_session_host(self, gid, is_migrate_owner): logger.info("MatchMakingClient.update_session_host()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.bool(is_migrate_owner) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_SESSION_HOST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.update_session_host -> done") async def update_gathering_ownership(self, gid, participants_only): logger.info("MatchMakingClient.update_gathering_ownership()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.bool(participants_only) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_GATHERING_OWNERSHIP, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.update_gathering_ownership -> done") return result async def migrate_gathering_ownership(self, gid, potential_owners, participants_only): logger.info("MatchMakingClient.migrate_gathering_ownership()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(potential_owners, stream.pid) stream.bool(participants_only) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_MIGRATE_GATHERING_OWNERSHIP, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.migrate_gathering_ownership -> done") class MatchMakingClientExt(MatchMakingProtocolExt): def __init__(self, client): self.settings = client.settings self.client = client async def end_participation(self, gid, message): logger.info("MatchMakingClientExt.end_participation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_END_PARTICIPATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.end_participation -> done") return result async def get_participants(self, gid, only_active): logger.info("MatchMakingClientExt.get_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.bool(only_active) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) participants = stream.list(stream.pid) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.get_participants -> done") return participants async def get_detailed_participants(self, gid, only_active): logger.info("MatchMakingClientExt.get_detailed_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.bool(only_active) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_DETAILED_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) details = stream.list(ParticipantDetails) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.get_detailed_participants -> done") return details async def get_participants_urls(self, gids): logger.info("MatchMakingClientExt.get_participants_urls()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PARTICIPANTS_URLS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) urls = stream.list(GatheringURLs) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.get_participants_urls -> done") return urls async def get_gathering_relations(self, id, descr): logger.info("MatchMakingClientExt.get_gathering_relations()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(id) stream.string(descr) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_GATHERING_RELATIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.string() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.get_gathering_relations -> done") return result async def delete_from_deletions(self, deletions, pid): logger.info("MatchMakingClientExt.delete_from_deletions()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(deletions, stream.u32) stream.pid(pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_FROM_DELETIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.delete_from_deletions -> done") class MatchmakeExtensionClient(MatchmakeExtensionProtocol): def __init__(self, client): self.settings = client.settings self.client = client async def close_participation(self, gid): logger.info("MatchmakeExtensionClient.close_participation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CLOSE_PARTICIPATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.close_participation -> done") async def open_participation(self, gid): logger.info("MatchmakeExtensionClient.open_participation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_OPEN_PARTICIPATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.open_participation -> done") async def auto_matchmake_postpone(self, gathering, message): logger.info("MatchmakeExtensionClient.auto_matchmake_postpone()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(gathering) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_AUTO_MATCHMAKE_POSTPONE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gathering = stream.anydata() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.auto_matchmake_postpone -> done") return gathering async def browse_matchmake_session(self, search_criteria, range): logger.info("MatchmakeExtensionClient.browse_matchmake_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.browse_matchmake_session -> done") return gatherings async def browse_matchmake_session_with_host_urls(self, search_criteria, range): logger.info("MatchmakeExtensionClient.browse_matchmake_session_with_host_urls()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.gatherings = stream.list(stream.anydata) obj.urls = stream.list(GatheringURLs) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.browse_matchmake_session_with_host_urls -> done") return obj async def create_matchmake_session(self, gathering, description, num_participants): logger.info("MatchmakeExtensionClient.create_matchmake_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(gathering) stream.string(description) stream.u16(num_participants) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CREATE_MATCHMAKE_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.gid = stream.u32() obj.session_key = stream.buffer() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.create_matchmake_session -> done") return obj async def join_matchmake_session(self, gid, message): logger.info("MatchmakeExtensionClient.join_matchmake_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_JOIN_MATCHMAKE_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session_key = stream.buffer() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.join_matchmake_session -> done") return session_key async def modify_current_game_attribute(self, gid, attrib, value): logger.info("MatchmakeExtensionClient.modify_current_game_attribute()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.u32(attrib) stream.u32(value) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_MODIFY_CURRENT_GAME_ATTRIBUTE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.modify_current_game_attribute -> done") async def update_notification_data(self, type, param1, param2, param3): logger.info("MatchmakeExtensionClient.update_notification_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(type) stream.pid(param1) stream.pid(param2) stream.string(param3) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_NOTIFICATION_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.update_notification_data -> done") async def get_friend_notification_data(self, type): logger.info("MatchmakeExtensionClient.get_friend_notification_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.s32(type) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_FRIEND_NOTIFICATION_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) notifications = stream.list(notification.NotificationEvent) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.get_friend_notification_data -> done") return notifications async def update_application_buffer(self, gid, buffer): logger.info("MatchmakeExtensionClient.update_application_buffer()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.buffer(buffer) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_APPLICATION_BUFFER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.update_application_buffer -> done") async def update_matchmake_session_attribute(self, gid, attribs): logger.info("MatchmakeExtensionClient.update_matchmake_session_attribute()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(attribs, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_MATCHMAKE_SESSION_ATTRIBUTE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.update_matchmake_session_attribute -> done") async def get_friend_notification_data_list(self, types): logger.info("MatchmakeExtensionClient.get_friend_notification_data_list()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(types, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_FRIEND_NOTIFICATION_DATA_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) notifications = stream.list(notification.NotificationEvent) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.get_friend_notification_data_list -> done") return notifications async def update_matchmake_session(self, gathering): logger.info("MatchmakeExtensionClient.update_matchmake_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(gathering) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_MATCHMAKE_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.update_matchmake_session -> done") async def auto_matchmake_with_search_criteria_postpone(self, search_criteria, gathering, message): logger.info("MatchmakeExtensionClient.auto_matchmake_with_search_criteria_postpone()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(search_criteria, stream.add) stream.anydata(gathering) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_AUTO_MATCHMAKE_WITH_SEARCH_CRITERIA_POSTPONE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gathering = stream.anydata() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.auto_matchmake_with_search_criteria_postpone -> done") return gathering async def get_playing_session(self, pids): logger.info("MatchmakeExtensionClient.get_playing_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PLAYING_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) sessions = stream.list(PlayingSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.get_playing_session -> done") return sessions async def create_community(self, community, message): logger.info("MatchmakeExtensionClient.create_community()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(community) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CREATE_COMMUNITY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gid = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.create_community -> done") return gid async def update_community(self, community): logger.info("MatchmakeExtensionClient.update_community()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(community) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_COMMUNITY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.update_community -> done") async def join_community(self, gid, message, password): logger.info("MatchmakeExtensionClient.join_community()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) stream.string(password) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_JOIN_COMMUNITY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.join_community -> done") async def find_community_by_gathering_id(self, gids): logger.info("MatchmakeExtensionClient.find_community_by_gathering_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_COMMUNITY_BY_GATHERING_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) communities = stream.list(PersistentGathering) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.find_community_by_gathering_id -> done") return communities async def find_official_community(self, available_only, range): logger.info("MatchmakeExtensionClient.find_official_community()") #--- request --- stream = streams.StreamOut(self.settings) stream.bool(available_only) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_OFFICIAL_COMMUNITY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) communities = stream.list(PersistentGathering) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.find_official_community -> done") return communities async def find_community_by_participant(self, pid, range): logger.info("MatchmakeExtensionClient.find_community_by_participant()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_COMMUNITY_BY_PARTICIPANT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) communities = stream.list(PersistentGathering) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.find_community_by_participant -> done") return communities async def update_privacy_setting(self, online_status, community_participation): logger.info("MatchmakeExtensionClient.update_privacy_setting()") #--- request --- stream = streams.StreamOut(self.settings) stream.bool(online_status) stream.bool(community_participation) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_PRIVACY_SETTING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.update_privacy_setting -> done") async def get_my_block_list(self): logger.info("MatchmakeExtensionClient.get_my_block_list()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_MY_BLOCK_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) pids = stream.list(stream.pid) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.get_my_block_list -> done") return pids async def add_to_block_list(self, pids): logger.info("MatchmakeExtensionClient.add_to_block_list()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_ADD_TO_BLOCK_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.add_to_block_list -> done") async def remove_from_block_list(self, pids): logger.info("MatchmakeExtensionClient.remove_from_block_list()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REMOVE_FROM_BLOCK_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.remove_from_block_list -> done") async def clear_my_block_list(self): logger.info("MatchmakeExtensionClient.clear_my_block_list()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CLEAR_MY_BLOCK_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.clear_my_block_list -> done") async def report_violation(self, pid, username, violation_code): logger.info("MatchmakeExtensionClient.report_violation()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) stream.string(username) stream.u32(violation_code) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REPORT_VIOLATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.report_violation -> done") async def is_violation_user(self): logger.info("MatchmakeExtensionClient.is_violation_user()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_IS_VIOLATION_USER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.flag = stream.bool() obj.score = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.is_violation_user -> done") return obj async def join_matchmake_session_ex(self, gid, gmessage, ignore_block_list, num_participants): logger.info("MatchmakeExtensionClient.join_matchmake_session_ex()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(gmessage) stream.bool(ignore_block_list) stream.u16(num_participants) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_JOIN_MATCHMAKE_SESSION_EX, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session_key = stream.buffer() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.join_matchmake_session_ex -> done") return session_key async def get_simple_playing_session(self, pids, include_login_user): logger.info("MatchmakeExtensionClient.get_simple_playing_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) stream.bool(include_login_user) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SIMPLE_PLAYING_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session = stream.list(SimplePlayingSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.get_simple_playing_session -> done") return session async def get_simple_community(self, gids): logger.info("MatchmakeExtensionClient.get_simple_community()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SIMPLE_COMMUNITY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) communities = stream.list(SimpleCommunity) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.get_simple_community -> done") return communities async def auto_matchmake_with_gathering_id_postpone(self, gids, gathering, message): logger.info("MatchmakeExtensionClient.auto_matchmake_with_gathering_id_postpone()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) stream.anydata(gathering) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_AUTO_MATCHMAKE_WITH_GATHERING_ID_POSTPONE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) joined_gathering = stream.anydata() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.auto_matchmake_with_gathering_id_postpone -> done") return joined_gathering async def update_progress_score(self, gid, score): logger.info("MatchmakeExtensionClient.update_progress_score()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.u8(score) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_PROGRESS_SCORE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.update_progress_score -> done") async def debug_notify_event(self, pid, main_type, sub_type, param1, param2, param3): logger.info("MatchmakeExtensionClient.debug_notify_event()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) stream.u32(main_type) stream.u32(sub_type) stream.u64(param1) stream.u64(param2) stream.string(param3) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DEBUG_NOTIFY_EVENT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.debug_notify_event -> done") async def generate_matchmake_session_system_password(self, gid): logger.info("MatchmakeExtensionClient.generate_matchmake_session_system_password()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GENERATE_MATCHMAKE_SESSION_SYSTEM_PASSWORD, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) password = stream.string() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.generate_matchmake_session_system_password -> done") return password async def clear_matchmake_session_system_password(self, gid): logger.info("MatchmakeExtensionClient.clear_matchmake_session_system_password()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CLEAR_MATCHMAKE_SESSION_SYSTEM_PASSWORD, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.clear_matchmake_session_system_password -> done") async def create_matchmake_session_with_param(self, param): logger.info("MatchmakeExtensionClient.create_matchmake_session_with_param()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CREATE_MATCHMAKE_SESSION_WITH_PARAM, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session = stream.extract(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.create_matchmake_session_with_param -> done") return session async def join_matchmake_session_with_param(self, param): logger.info("MatchmakeExtensionClient.join_matchmake_session_with_param()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_JOIN_MATCHMAKE_SESSION_WITH_PARAM, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session = stream.extract(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.join_matchmake_session_with_param -> done") return session async def auto_matchmake_with_param_postpone(self, param): logger.info("MatchmakeExtensionClient.auto_matchmake_with_param_postpone()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_AUTO_MATCHMAKE_WITH_PARAM_POSTPONE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session = stream.extract(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.auto_matchmake_with_param_postpone -> done") return session async def find_matchmake_session_by_gathering_id_detail(self, gid): logger.info("MatchmakeExtensionClient.find_matchmake_session_by_gathering_id_detail()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_MATCHMAKE_SESSION_BY_GATHERING_ID_DETAIL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session = stream.extract(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.find_matchmake_session_by_gathering_id_detail -> done") return session async def browse_matchmake_session_no_holder(self, search_criteria, range): logger.info("MatchmakeExtensionClient.browse_matchmake_session_no_holder()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) sessions = stream.list(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.browse_matchmake_session_no_holder -> done") return sessions async def browse_matchmake_session_with_host_urls_no_holder(self, search_criteria, range): logger.info("MatchmakeExtensionClient.browse_matchmake_session_with_host_urls_no_holder()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.sessions = stream.list(MatchmakeSession) obj.urls = stream.list(GatheringURLs) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.browse_matchmake_session_with_host_urls_no_holder -> done") return obj async def update_matchmake_session_part(self, param): logger.info("MatchmakeExtensionClient.update_matchmake_session_part()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_MATCHMAKE_SESSION_PART, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.update_matchmake_session_part -> done") async def request_matchmaking(self, param): logger.info("MatchmakeExtensionClient.request_matchmaking()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REQUEST_MATCHMAKING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) request_id = stream.u64() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.request_matchmaking -> done") return request_id async def withdraw_matchmaking(self, request_id): logger.info("MatchmakeExtensionClient.withdraw_matchmaking()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(request_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_WITHDRAW_MATCHMAKING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.withdraw_matchmaking -> done") async def withdraw_matchmaking_all(self): logger.info("MatchmakeExtensionClient.withdraw_matchmaking_all()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_WITHDRAW_MATCHMAKING_ALL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.withdraw_matchmaking_all -> done") async def find_matchmake_session_by_gathering_id(self, gids): logger.info("MatchmakeExtensionClient.find_matchmake_session_by_gathering_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_MATCHMAKE_SESSION_BY_GATHERING_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) sessions = stream.list(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.find_matchmake_session_by_gathering_id -> done") return sessions async def find_matchmake_session_by_single_gathering_id(self, gid): logger.info("MatchmakeExtensionClient.find_matchmake_session_by_single_gathering_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_MATCHMAKE_SESSION_BY_SINGLE_GATHERING_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session = stream.extract(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.find_matchmake_session_by_single_gathering_id -> done") return session async def find_matchmake_session_by_owner(self, pid, range): logger.info("MatchmakeExtensionClient.find_matchmake_session_by_owner()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_MATCHMAKE_SESSION_BY_OWNER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) sessions = stream.list(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.find_matchmake_session_by_owner -> done") return sessions async def find_matchmake_session_by_participant(self, param): logger.info("MatchmakeExtensionClient.find_matchmake_session_by_participant()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_MATCHMAKE_SESSION_BY_PARTICIPANT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.list(FindMatchmakeSessionByParticipantResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.find_matchmake_session_by_participant -> done") return result async def browse_matchmake_session_no_holder_no_result_range(self, search_criteria): logger.info("MatchmakeExtensionClient.browse_matchmake_session_no_holder_no_result_range()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER_NO_RESULT_RANGE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) sessions = stream.list(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.browse_matchmake_session_no_holder_no_result_range -> done") return sessions async def browse_matchmake_session_with_host_urls_no_holder_no_result_range(self, search_criteria): logger.info("MatchmakeExtensionClient.browse_matchmake_session_with_host_urls_no_holder_no_result_range()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER_NO_RESULT_RANGE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.sessions = stream.list(MatchmakeSession) obj.urls = stream.list(GatheringURLs) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClient.browse_matchmake_session_with_host_urls_no_holder_no_result_range -> done") return obj class MatchmakeRefereeClient(MatchmakeRefereeProtocol): def __init__(self, client): self.settings = client.settings self.client = client async def start_round(self, param): logger.info("MatchmakeRefereeClient.start_round()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_START_ROUND, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) round_id = stream.u64() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.start_round -> done") return round_id async def get_start_round_param(self, round_id): logger.info("MatchmakeRefereeClient.get_start_round_param()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(round_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_START_ROUND_PARAM, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) param = stream.extract(MatchmakeRefereeStartRoundParam) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_start_round_param -> done") return param async def end_round(self, param): logger.info("MatchmakeRefereeClient.end_round()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_END_ROUND, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.end_round -> done") async def end_round_with_partial_report(self, param): logger.info("MatchmakeRefereeClient.end_round_with_partial_report()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_END_ROUND_WITH_PARTIAL_REPORT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.end_round_with_partial_report -> done") async def end_round_without_report(self, round_id): logger.info("MatchmakeRefereeClient.end_round_without_report()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(round_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_END_ROUND_WITHOUT_REPORT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.end_round_without_report -> done") async def get_round_participants(self, round_id): logger.info("MatchmakeRefereeClient.get_round_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(round_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_ROUND_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) pids = stream.list(stream.pid) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_round_participants -> done") return pids async def get_not_summarized_round(self): logger.info("MatchmakeRefereeClient.get_not_summarized_round()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_NOT_SUMMARIZED_ROUND, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) rounds = stream.list(MatchmakeRefereeRound) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_not_summarized_round -> done") return rounds async def get_round(self, round): logger.info("MatchmakeRefereeClient.get_round()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(round) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_ROUND, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) round = stream.extract(MatchmakeRefereeRound) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_round -> done") return round async def get_stats_primary(self, target): logger.info("MatchmakeRefereeClient.get_stats_primary()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATS_PRIMARY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) stats = stream.extract(MatchmakeRefereeStats) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_stats_primary -> done") return stats async def get_stats_primaries(self, targets): logger.info("MatchmakeRefereeClient.get_stats_primaries()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(targets, stream.add) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATS_PRIMARIES, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.stats = stream.list(MatchmakeRefereeStats) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_stats_primaries -> done") return obj async def get_stats_all(self, target): logger.info("MatchmakeRefereeClient.get_stats_all()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATS_ALL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) stats = stream.list(MatchmakeRefereeStats) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_stats_all -> done") return stats async def create_stats(self, param): logger.info("MatchmakeRefereeClient.create_stats()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CREATE_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) stats = stream.extract(MatchmakeRefereeStats) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.create_stats -> done") return stats async def get_or_create_stats(self, param): logger.info("MatchmakeRefereeClient.get_or_create_stats()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_OR_CREATE_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) stats = stream.extract(MatchmakeRefereeStats) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_or_create_stats -> done") return stats async def reset_stats(self): logger.info("MatchmakeRefereeClient.reset_stats()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RESET_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.reset_stats -> done") class MatchMakingServer(MatchMakingProtocol): def __init__(self): self.methods = { self.METHOD_REGISTER_GATHERING: self.handle_register_gathering, self.METHOD_UNREGISTER_GATHERING: self.handle_unregister_gathering, self.METHOD_UNREGISTER_GATHERINGS: self.handle_unregister_gatherings, self.METHOD_UPDATE_GATHERING: self.handle_update_gathering, self.METHOD_INVITE: self.handle_invite, self.METHOD_ACCEPT_INVITATION: self.handle_accept_invitation, self.METHOD_DECLINE_INVITATION: self.handle_decline_invitation, self.METHOD_CANCEL_INVITATION: self.handle_cancel_invitation, self.METHOD_GET_INVITATIONS_SENT: self.handle_get_invitations_sent, self.METHOD_GET_INVITATIONS_RECEIVED: self.handle_get_invitations_received, self.METHOD_PARTICIPATE: self.handle_participate, self.METHOD_CANCEL_PARTICIPATION: self.handle_cancel_participation, self.METHOD_GET_PARTICIPANTS: self.handle_get_participants, self.METHOD_ADD_PARTICIPANTS: self.handle_add_participants, self.METHOD_GET_DETAILED_PARTICIPANTS: self.handle_get_detailed_participants, self.METHOD_GET_PARTICIPANTS_URLS: self.handle_get_participants_urls, self.METHOD_FIND_BY_TYPE: self.handle_find_by_type, self.METHOD_FIND_BY_DESCRIPTION: self.handle_find_by_description, self.METHOD_FIND_BY_DESCRIPTION_REGEX: self.handle_find_by_description_regex, self.METHOD_FIND_BY_ID: self.handle_find_by_id, self.METHOD_FIND_BY_SINGLE_ID: self.handle_find_by_single_id, self.METHOD_FIND_BY_OWNER: self.handle_find_by_owner, self.METHOD_FIND_BY_PARTICIPANTS: self.handle_find_by_participants, self.METHOD_FIND_INVITATIONS: self.handle_find_invitations, self.METHOD_FIND_BY_SQL_QUERY: self.handle_find_by_sql_query, self.METHOD_LAUNCH_SESSION: self.handle_launch_session, self.METHOD_UPDATE_SESSION_URL: self.handle_update_session_url, self.METHOD_GET_SESSION_URL: self.handle_get_session_url, self.METHOD_GET_STATE: self.handle_get_state, self.METHOD_SET_STATE: self.handle_set_state, self.METHOD_REPORT_STATS: self.handle_report_stats, self.METHOD_GET_STATS: self.handle_get_stats, self.METHOD_DELETE_GATHERING: self.handle_delete_gathering, self.METHOD_GET_PENDING_DELETIONS: self.handle_get_pending_deletions, self.METHOD_DELETE_FROM_DELETIONS: self.handle_delete_from_deletions, self.METHOD_MIGRATE_GATHERING_OWNERSHIP_V1: self.handle_migrate_gathering_ownership_v1, self.METHOD_FIND_BY_DESCRIPTION_LIKE: self.handle_find_by_description_like, self.METHOD_REGISTER_LOCAL_URL: self.handle_register_local_url, self.METHOD_REGISTER_LOCAL_URLS: self.handle_register_local_urls, self.METHOD_UPDATE_SESSION_HOST_V1: self.handle_update_session_host_v1, self.METHOD_GET_SESSION_URLS: self.handle_get_session_urls, self.METHOD_UPDATE_SESSION_HOST: self.handle_update_session_host, self.METHOD_UPDATE_GATHERING_OWNERSHIP: self.handle_update_gathering_ownership, self.METHOD_MIGRATE_GATHERING_OWNERSHIP: self.handle_migrate_gathering_ownership, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on MatchMakingServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_register_gathering(self, client, input, output): logger.info("MatchMakingServer.register_gathering()") #--- request --- gathering = input.anydata() response = await self.register_gathering(client, gathering) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u32(response) async def handle_unregister_gathering(self, client, input, output): logger.info("MatchMakingServer.unregister_gathering()") #--- request --- gid = input.u32() response = await self.unregister_gathering(client, gid) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_unregister_gatherings(self, client, input, output): logger.info("MatchMakingServer.unregister_gatherings()") #--- request --- gids = input.list(input.u32) response = await self.unregister_gatherings(client, gids) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_update_gathering(self, client, input, output): logger.info("MatchMakingServer.update_gathering()") #--- request --- gathering = input.anydata() response = await self.update_gathering(client, gathering) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_invite(self, client, input, output): logger.info("MatchMakingServer.invite()") #--- request --- gid = input.u32() pids = input.list(input.pid) message = input.string() response = await self.invite(client, gid, pids, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_accept_invitation(self, client, input, output): logger.info("MatchMakingServer.accept_invitation()") #--- request --- gid = input.u32() message = input.string() response = await self.accept_invitation(client, gid, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_decline_invitation(self, client, input, output): logger.info("MatchMakingServer.decline_invitation()") #--- request --- gid = input.u32() message = input.string() response = await self.decline_invitation(client, gid, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_cancel_invitation(self, client, input, output): logger.info("MatchMakingServer.cancel_invitation()") #--- request --- gid = input.u32() pids = input.list(input.pid) message = input.string() response = await self.cancel_invitation(client, gid, pids, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_invitations_sent(self, client, input, output): logger.info("MatchMakingServer.get_invitations_sent()") #--- request --- gid = input.u32() response = await self.get_invitations_sent(client, gid) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_invitations_received(self, client, input, output): logger.info("MatchMakingServer.get_invitations_received()") #--- request --- response = await self.get_invitations_received(client) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_participate(self, client, input, output): logger.info("MatchMakingServer.participate()") #--- request --- gid = input.u32() message = input.string() response = await self.participate(client, gid, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_cancel_participation(self, client, input, output): logger.info("MatchMakingServer.cancel_participation()") #--- request --- gid = input.u32() message = input.string() response = await self.cancel_participation(client, gid, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_participants(self, client, input, output): logger.info("MatchMakingServer.get_participants()") #--- request --- gid = input.u32() response = await self.get_participants(client, gid) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.pid) async def handle_add_participants(self, client, input, output): logger.info("MatchMakingServer.add_participants()") #--- request --- gid = input.u32() pids = input.list(input.pid) message = input.string() response = await self.add_participants(client, gid, pids, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_detailed_participants(self, client, input, output): logger.info("MatchMakingServer.get_detailed_participants()") #--- request --- gid = input.u32() response = await self.get_detailed_participants(client, gid) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_participants_urls(self, client, input, output): logger.info("MatchMakingServer.get_participants_urls()") #--- request --- gid = input.u32() response = await self.get_participants_urls(client, gid) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.stationurl) async def handle_find_by_type(self, client, input, output): logger.info("MatchMakingServer.find_by_type()") #--- request --- type = input.string() range = input.extract(common.ResultRange) response = await self.find_by_type(client, type, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_description(self, client, input, output): logger.info("MatchMakingServer.find_by_description()") #--- request --- description = input.string() range = input.extract(common.ResultRange) response = await self.find_by_description(client, description, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_description_regex(self, client, input, output): logger.info("MatchMakingServer.find_by_description_regex()") #--- request --- regex = input.string() range = input.extract(common.ResultRange) response = await self.find_by_description_regex(client, regex, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_id(self, client, input, output): logger.info("MatchMakingServer.find_by_id()") #--- request --- ids = input.list(input.u32) response = await self.find_by_id(client, ids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_single_id(self, client, input, output): logger.info("MatchMakingServer.find_by_single_id()") #--- request --- gid = input.u32() response = await self.find_by_single_id(client, gid) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'gathering']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.anydata(response.gathering) async def handle_find_by_owner(self, client, input, output): logger.info("MatchMakingServer.find_by_owner()") #--- request --- owner = input.pid() range = input.extract(common.ResultRange) response = await self.find_by_owner(client, owner, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_participants(self, client, input, output): logger.info("MatchMakingServer.find_by_participants()") #--- request --- pids = input.list(input.pid) response = await self.find_by_participants(client, pids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_invitations(self, client, input, output): logger.info("MatchMakingServer.find_invitations()") #--- request --- range = input.extract(common.ResultRange) response = await self.find_invitations(client, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_sql_query(self, client, input, output): logger.info("MatchMakingServer.find_by_sql_query()") #--- request --- query = input.string() range = input.extract(common.ResultRange) response = await self.find_by_sql_query(client, query, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_launch_session(self, client, input, output): logger.info("MatchMakingServer.launch_session()") #--- request --- gid = input.u32() url = input.string() response = await self.launch_session(client, gid, url) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_update_session_url(self, client, input, output): logger.info("MatchMakingServer.update_session_url()") #--- request --- gid = input.u32() url = input.string() response = await self.update_session_url(client, gid, url) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_session_url(self, client, input, output): logger.info("MatchMakingServer.get_session_url()") #--- request --- gid = input.u32() response = await self.get_session_url(client, gid) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'url']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.string(response.url) async def handle_get_state(self, client, input, output): logger.info("MatchMakingServer.get_state()") #--- request --- gid = input.u32() response = await self.get_state(client, gid) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'state']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.u32(response.state) async def handle_set_state(self, client, input, output): logger.info("MatchMakingServer.set_state()") #--- request --- gid = input.u32() state = input.u32() response = await self.set_state(client, gid, state) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_report_stats(self, client, input, output): logger.info("MatchMakingServer.report_stats()") #--- request --- gid = input.u32() stats = input.list(GatheringStats) response = await self.report_stats(client, gid, stats) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_stats(self, client, input, output): logger.info("MatchMakingServer.get_stats()") #--- request --- gid = input.u32() pids = input.list(input.pid) columns = input.list(input.u8) response = await self.get_stats(client, gid, pids, columns) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'stats']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.list(response.stats, output.add) async def handle_delete_gathering(self, client, input, output): logger.info("MatchMakingServer.delete_gathering()") #--- request --- gid = input.u32() response = await self.delete_gathering(client, gid) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_pending_deletions(self, client, input, output): logger.info("MatchMakingServer.get_pending_deletions()") #--- request --- reason = input.u32() range = input.extract(common.ResultRange) response = await self.get_pending_deletions(client, reason, range) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'deletions']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.list(response.deletions, output.add) async def handle_delete_from_deletions(self, client, input, output): logger.info("MatchMakingServer.delete_from_deletions()") #--- request --- deletions = input.list(input.u32) response = await self.delete_from_deletions(client, deletions) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_migrate_gathering_ownership_v1(self, client, input, output): logger.info("MatchMakingServer.migrate_gathering_ownership_v1()") #--- request --- gid = input.u32() potential_owners = input.list(input.pid) response = await self.migrate_gathering_ownership_v1(client, gid, potential_owners) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_find_by_description_like(self, client, input, output): logger.info("MatchMakingServer.find_by_description_like()") #--- request --- description = input.string() range = input.extract(common.ResultRange) response = await self.find_by_description_like(client, description, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_register_local_url(self, client, input, output): logger.info("MatchMakingServer.register_local_url()") #--- request --- gid = input.u32() url = input.stationurl() await self.register_local_url(client, gid, url) async def handle_register_local_urls(self, client, input, output): logger.info("MatchMakingServer.register_local_urls()") #--- request --- gid = input.u32() urls = input.list(input.stationurl) await self.register_local_urls(client, gid, urls) async def handle_update_session_host_v1(self, client, input, output): logger.info("MatchMakingServer.update_session_host_v1()") #--- request --- gid = input.u32() await self.update_session_host_v1(client, gid) async def handle_get_session_urls(self, client, input, output): logger.info("MatchMakingServer.get_session_urls()") #--- request --- gid = input.u32() response = await self.get_session_urls(client, gid) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.stationurl) async def handle_update_session_host(self, client, input, output): logger.info("MatchMakingServer.update_session_host()") #--- request --- gid = input.u32() is_migrate_owner = input.bool() await self.update_session_host(client, gid, is_migrate_owner) async def handle_update_gathering_ownership(self, client, input, output): logger.info("MatchMakingServer.update_gathering_ownership()") #--- request --- gid = input.u32() participants_only = input.bool() response = await self.update_gathering_ownership(client, gid, participants_only) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_migrate_gathering_ownership(self, client, input, output): logger.info("MatchMakingServer.migrate_gathering_ownership()") #--- request --- gid = input.u32() potential_owners = input.list(input.pid) participants_only = input.bool() await self.migrate_gathering_ownership(client, gid, potential_owners, participants_only) async def register_gathering(self, *args): logger.warning("MatchMakingServer.register_gathering not implemented") raise common.RMCError("Core::NotImplemented") async def unregister_gathering(self, *args): logger.warning("MatchMakingServer.unregister_gathering not implemented") raise common.RMCError("Core::NotImplemented") async def unregister_gatherings(self, *args): logger.warning("MatchMakingServer.unregister_gatherings not implemented") raise common.RMCError("Core::NotImplemented") async def update_gathering(self, *args): logger.warning("MatchMakingServer.update_gathering not implemented") raise common.RMCError("Core::NotImplemented") async def invite(self, *args): logger.warning("MatchMakingServer.invite not implemented") raise common.RMCError("Core::NotImplemented") async def accept_invitation(self, *args): logger.warning("MatchMakingServer.accept_invitation not implemented") raise common.RMCError("Core::NotImplemented") async def decline_invitation(self, *args): logger.warning("MatchMakingServer.decline_invitation not implemented") raise common.RMCError("Core::NotImplemented") async def cancel_invitation(self, *args): logger.warning("MatchMakingServer.cancel_invitation not implemented") raise common.RMCError("Core::NotImplemented") async def get_invitations_sent(self, *args): logger.warning("MatchMakingServer.get_invitations_sent not implemented") raise common.RMCError("Core::NotImplemented") async def get_invitations_received(self, *args): logger.warning("MatchMakingServer.get_invitations_received not implemented") raise common.RMCError("Core::NotImplemented") async def participate(self, *args): logger.warning("MatchMakingServer.participate not implemented") raise common.RMCError("Core::NotImplemented") async def cancel_participation(self, *args): logger.warning("MatchMakingServer.cancel_participation not implemented") raise common.RMCError("Core::NotImplemented") async def get_participants(self, *args): logger.warning("MatchMakingServer.get_participants not implemented") raise common.RMCError("Core::NotImplemented") async def add_participants(self, *args): logger.warning("MatchMakingServer.add_participants not implemented") raise common.RMCError("Core::NotImplemented") async def get_detailed_participants(self, *args): logger.warning("MatchMakingServer.get_detailed_participants not implemented") raise common.RMCError("Core::NotImplemented") async def get_participants_urls(self, *args): logger.warning("MatchMakingServer.get_participants_urls not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_type(self, *args): logger.warning("MatchMakingServer.find_by_type not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_description(self, *args): logger.warning("MatchMakingServer.find_by_description not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_description_regex(self, *args): logger.warning("MatchMakingServer.find_by_description_regex not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_id(self, *args): logger.warning("MatchMakingServer.find_by_id not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_single_id(self, *args): logger.warning("MatchMakingServer.find_by_single_id not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_owner(self, *args): logger.warning("MatchMakingServer.find_by_owner not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_participants(self, *args): logger.warning("MatchMakingServer.find_by_participants not implemented") raise common.RMCError("Core::NotImplemented") async def find_invitations(self, *args): logger.warning("MatchMakingServer.find_invitations not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_sql_query(self, *args): logger.warning("MatchMakingServer.find_by_sql_query not implemented") raise common.RMCError("Core::NotImplemented") async def launch_session(self, *args): logger.warning("MatchMakingServer.launch_session not implemented") raise common.RMCError("Core::NotImplemented") async def update_session_url(self, *args): logger.warning("MatchMakingServer.update_session_url not implemented") raise common.RMCError("Core::NotImplemented") async def get_session_url(self, *args): logger.warning("MatchMakingServer.get_session_url not implemented") raise common.RMCError("Core::NotImplemented") async def get_state(self, *args): logger.warning("MatchMakingServer.get_state not implemented") raise common.RMCError("Core::NotImplemented") async def set_state(self, *args): logger.warning("MatchMakingServer.set_state not implemented") raise common.RMCError("Core::NotImplemented") async def report_stats(self, *args): logger.warning("MatchMakingServer.report_stats not implemented") raise common.RMCError("Core::NotImplemented") async def get_stats(self, *args): logger.warning("MatchMakingServer.get_stats not implemented") raise common.RMCError("Core::NotImplemented") async def delete_gathering(self, *args): logger.warning("MatchMakingServer.delete_gathering not implemented") raise common.RMCError("Core::NotImplemented") async def get_pending_deletions(self, *args): logger.warning("MatchMakingServer.get_pending_deletions not implemented") raise common.RMCError("Core::NotImplemented") async def delete_from_deletions(self, *args): logger.warning("MatchMakingServer.delete_from_deletions not implemented") raise common.RMCError("Core::NotImplemented") async def migrate_gathering_ownership_v1(self, *args): logger.warning("MatchMakingServer.migrate_gathering_ownership_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_description_like(self, *args): logger.warning("MatchMakingServer.find_by_description_like not implemented") raise common.RMCError("Core::NotImplemented") async def register_local_url(self, *args): logger.warning("MatchMakingServer.register_local_url not implemented") raise common.RMCError("Core::NotImplemented") async def register_local_urls(self, *args): logger.warning("MatchMakingServer.register_local_urls not implemented") raise common.RMCError("Core::NotImplemented") async def update_session_host_v1(self, *args): logger.warning("MatchMakingServer.update_session_host_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def get_session_urls(self, *args): logger.warning("MatchMakingServer.get_session_urls not implemented") raise common.RMCError("Core::NotImplemented") async def update_session_host(self, *args): logger.warning("MatchMakingServer.update_session_host not implemented") raise common.RMCError("Core::NotImplemented") async def update_gathering_ownership(self, *args): logger.warning("MatchMakingServer.update_gathering_ownership not implemented") raise common.RMCError("Core::NotImplemented") async def migrate_gathering_ownership(self, *args): logger.warning("MatchMakingServer.migrate_gathering_ownership not implemented") raise common.RMCError("Core::NotImplemented") class MatchMakingServerExt(MatchMakingProtocolExt): def __init__(self): self.methods = { self.METHOD_END_PARTICIPATION: self.handle_end_participation, self.METHOD_GET_PARTICIPANTS: self.handle_get_participants, self.METHOD_GET_DETAILED_PARTICIPANTS: self.handle_get_detailed_participants, self.METHOD_GET_PARTICIPANTS_URLS: self.handle_get_participants_urls, self.METHOD_GET_GATHERING_RELATIONS: self.handle_get_gathering_relations, self.METHOD_DELETE_FROM_DELETIONS: self.handle_delete_from_deletions, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on MatchMakingServerExt: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_end_participation(self, client, input, output): logger.info("MatchMakingServerExt.end_participation()") #--- request --- gid = input.u32() message = input.string() response = await self.end_participation(client, gid, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_participants(self, client, input, output): logger.info("MatchMakingServerExt.get_participants()") #--- request --- gid = input.u32() only_active = input.bool() response = await self.get_participants(client, gid, only_active) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.pid) async def handle_get_detailed_participants(self, client, input, output): logger.info("MatchMakingServerExt.get_detailed_participants()") #--- request --- gid = input.u32() only_active = input.bool() response = await self.get_detailed_participants(client, gid, only_active) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_participants_urls(self, client, input, output): logger.info("MatchMakingServerExt.get_participants_urls()") #--- request --- gids = input.list(input.u32) response = await self.get_participants_urls(client, gids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_gathering_relations(self, client, input, output): logger.info("MatchMakingServerExt.get_gathering_relations()") #--- request --- id = input.u32() descr = input.string() response = await self.get_gathering_relations(client, id, descr) #--- response --- if not isinstance(response, str): raise RuntimeError("Expected str, got %s" %response.__class__.__name__) output.string(response) async def handle_delete_from_deletions(self, client, input, output): logger.info("MatchMakingServerExt.delete_from_deletions()") #--- request --- deletions = input.list(input.u32) pid = input.pid() await self.delete_from_deletions(client, deletions, pid) async def end_participation(self, *args): logger.warning("MatchMakingServerExt.end_participation not implemented") raise common.RMCError("Core::NotImplemented") async def get_participants(self, *args): logger.warning("MatchMakingServerExt.get_participants not implemented") raise common.RMCError("Core::NotImplemented") async def get_detailed_participants(self, *args): logger.warning("MatchMakingServerExt.get_detailed_participants not implemented") raise common.RMCError("Core::NotImplemented") async def get_participants_urls(self, *args): logger.warning("MatchMakingServerExt.get_participants_urls not implemented") raise common.RMCError("Core::NotImplemented") async def get_gathering_relations(self, *args): logger.warning("MatchMakingServerExt.get_gathering_relations not implemented") raise common.RMCError("Core::NotImplemented") async def delete_from_deletions(self, *args): logger.warning("MatchMakingServerExt.delete_from_deletions not implemented") raise common.RMCError("Core::NotImplemented") class MatchmakeExtensionServer(MatchmakeExtensionProtocol): def __init__(self): self.methods = { self.METHOD_CLOSE_PARTICIPATION: self.handle_close_participation, self.METHOD_OPEN_PARTICIPATION: self.handle_open_participation, self.METHOD_AUTO_MATCHMAKE_POSTPONE: self.handle_auto_matchmake_postpone, self.METHOD_BROWSE_MATCHMAKE_SESSION: self.handle_browse_matchmake_session, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS: self.handle_browse_matchmake_session_with_host_urls, self.METHOD_CREATE_MATCHMAKE_SESSION: self.handle_create_matchmake_session, self.METHOD_JOIN_MATCHMAKE_SESSION: self.handle_join_matchmake_session, self.METHOD_MODIFY_CURRENT_GAME_ATTRIBUTE: self.handle_modify_current_game_attribute, self.METHOD_UPDATE_NOTIFICATION_DATA: self.handle_update_notification_data, self.METHOD_GET_FRIEND_NOTIFICATION_DATA: self.handle_get_friend_notification_data, self.METHOD_UPDATE_APPLICATION_BUFFER: self.handle_update_application_buffer, self.METHOD_UPDATE_MATCHMAKE_SESSION_ATTRIBUTE: self.handle_update_matchmake_session_attribute, self.METHOD_GET_FRIEND_NOTIFICATION_DATA_LIST: self.handle_get_friend_notification_data_list, self.METHOD_UPDATE_MATCHMAKE_SESSION: self.handle_update_matchmake_session, self.METHOD_AUTO_MATCHMAKE_WITH_SEARCH_CRITERIA_POSTPONE: self.handle_auto_matchmake_with_search_criteria_postpone, self.METHOD_GET_PLAYING_SESSION: self.handle_get_playing_session, self.METHOD_CREATE_COMMUNITY: self.handle_create_community, self.METHOD_UPDATE_COMMUNITY: self.handle_update_community, self.METHOD_JOIN_COMMUNITY: self.handle_join_community, self.METHOD_FIND_COMMUNITY_BY_GATHERING_ID: self.handle_find_community_by_gathering_id, self.METHOD_FIND_OFFICIAL_COMMUNITY: self.handle_find_official_community, self.METHOD_FIND_COMMUNITY_BY_PARTICIPANT: self.handle_find_community_by_participant, self.METHOD_UPDATE_PRIVACY_SETTING: self.handle_update_privacy_setting, self.METHOD_GET_MY_BLOCK_LIST: self.handle_get_my_block_list, self.METHOD_ADD_TO_BLOCK_LIST: self.handle_add_to_block_list, self.METHOD_REMOVE_FROM_BLOCK_LIST: self.handle_remove_from_block_list, self.METHOD_CLEAR_MY_BLOCK_LIST: self.handle_clear_my_block_list, self.METHOD_REPORT_VIOLATION: self.handle_report_violation, self.METHOD_IS_VIOLATION_USER: self.handle_is_violation_user, self.METHOD_JOIN_MATCHMAKE_SESSION_EX: self.handle_join_matchmake_session_ex, self.METHOD_GET_SIMPLE_PLAYING_SESSION: self.handle_get_simple_playing_session, self.METHOD_GET_SIMPLE_COMMUNITY: self.handle_get_simple_community, self.METHOD_AUTO_MATCHMAKE_WITH_GATHERING_ID_POSTPONE: self.handle_auto_matchmake_with_gathering_id_postpone, self.METHOD_UPDATE_PROGRESS_SCORE: self.handle_update_progress_score, self.METHOD_DEBUG_NOTIFY_EVENT: self.handle_debug_notify_event, self.METHOD_GENERATE_MATCHMAKE_SESSION_SYSTEM_PASSWORD: self.handle_generate_matchmake_session_system_password, self.METHOD_CLEAR_MATCHMAKE_SESSION_SYSTEM_PASSWORD: self.handle_clear_matchmake_session_system_password, self.METHOD_CREATE_MATCHMAKE_SESSION_WITH_PARAM: self.handle_create_matchmake_session_with_param, self.METHOD_JOIN_MATCHMAKE_SESSION_WITH_PARAM: self.handle_join_matchmake_session_with_param, self.METHOD_AUTO_MATCHMAKE_WITH_PARAM_POSTPONE: self.handle_auto_matchmake_with_param_postpone, self.METHOD_FIND_MATCHMAKE_SESSION_BY_GATHERING_ID_DETAIL: self.handle_find_matchmake_session_by_gathering_id_detail, self.METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER: self.handle_browse_matchmake_session_no_holder, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER: self.handle_browse_matchmake_session_with_host_urls_no_holder, self.METHOD_UPDATE_MATCHMAKE_SESSION_PART: self.handle_update_matchmake_session_part, self.METHOD_REQUEST_MATCHMAKING: self.handle_request_matchmaking, self.METHOD_WITHDRAW_MATCHMAKING: self.handle_withdraw_matchmaking, self.METHOD_WITHDRAW_MATCHMAKING_ALL: self.handle_withdraw_matchmaking_all, self.METHOD_FIND_MATCHMAKE_SESSION_BY_GATHERING_ID: self.handle_find_matchmake_session_by_gathering_id, self.METHOD_FIND_MATCHMAKE_SESSION_BY_SINGLE_GATHERING_ID: self.handle_find_matchmake_session_by_single_gathering_id, self.METHOD_FIND_MATCHMAKE_SESSION_BY_OWNER: self.handle_find_matchmake_session_by_owner, self.METHOD_FIND_MATCHMAKE_SESSION_BY_PARTICIPANT: self.handle_find_matchmake_session_by_participant, self.METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER_NO_RESULT_RANGE: self.handle_browse_matchmake_session_no_holder_no_result_range, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER_NO_RESULT_RANGE: self.handle_browse_matchmake_session_with_host_urls_no_holder_no_result_range, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on MatchmakeExtensionServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_close_participation(self, client, input, output): logger.info("MatchmakeExtensionServer.close_participation()") #--- request --- gid = input.u32() await self.close_participation(client, gid) async def handle_open_participation(self, client, input, output): logger.info("MatchmakeExtensionServer.open_participation()") #--- request --- gid = input.u32() await self.open_participation(client, gid) async def handle_auto_matchmake_postpone(self, client, input, output): logger.info("MatchmakeExtensionServer.auto_matchmake_postpone()") #--- request --- gathering = input.anydata() message = input.string() response = await self.auto_matchmake_postpone(client, gathering, message) #--- response --- if not isinstance(response, Gathering): raise RuntimeError("Expected Gathering, got %s" %response.__class__.__name__) output.anydata(response) async def handle_browse_matchmake_session(self, client, input, output): logger.info("MatchmakeExtensionServer.browse_matchmake_session()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) range = input.extract(common.ResultRange) response = await self.browse_matchmake_session(client, search_criteria, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_browse_matchmake_session_with_host_urls(self, client, input, output): logger.info("MatchmakeExtensionServer.browse_matchmake_session_with_host_urls()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) range = input.extract(common.ResultRange) response = await self.browse_matchmake_session_with_host_urls(client, search_criteria, range) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['gatherings', 'urls']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.gatherings, output.anydata) output.list(response.urls, output.add) async def handle_create_matchmake_session(self, client, input, output): logger.info("MatchmakeExtensionServer.create_matchmake_session()") #--- request --- gathering = input.anydata() description = input.string() num_participants = input.u16() response = await self.create_matchmake_session(client, gathering, description, num_participants) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['gid', 'session_key']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.u32(response.gid) output.buffer(response.session_key) async def handle_join_matchmake_session(self, client, input, output): logger.info("MatchmakeExtensionServer.join_matchmake_session()") #--- request --- gid = input.u32() message = input.string() response = await self.join_matchmake_session(client, gid, message) #--- response --- if not isinstance(response, bytes): raise RuntimeError("Expected bytes, got %s" %response.__class__.__name__) output.buffer(response) async def handle_modify_current_game_attribute(self, client, input, output): logger.info("MatchmakeExtensionServer.modify_current_game_attribute()") #--- request --- gid = input.u32() attrib = input.u32() value = input.u32() await self.modify_current_game_attribute(client, gid, attrib, value) async def handle_update_notification_data(self, client, input, output): logger.info("MatchmakeExtensionServer.update_notification_data()") #--- request --- type = input.u32() param1 = input.pid() param2 = input.pid() param3 = input.string() await self.update_notification_data(client, type, param1, param2, param3) async def handle_get_friend_notification_data(self, client, input, output): logger.info("MatchmakeExtensionServer.get_friend_notification_data()") #--- request --- type = input.s32() response = await self.get_friend_notification_data(client, type) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_update_application_buffer(self, client, input, output): logger.info("MatchmakeExtensionServer.update_application_buffer()") #--- request --- gid = input.u32() buffer = input.buffer() await self.update_application_buffer(client, gid, buffer) async def handle_update_matchmake_session_attribute(self, client, input, output): logger.info("MatchmakeExtensionServer.update_matchmake_session_attribute()") #--- request --- gid = input.u32() attribs = input.list(input.u32) await self.update_matchmake_session_attribute(client, gid, attribs) async def handle_get_friend_notification_data_list(self, client, input, output): logger.info("MatchmakeExtensionServer.get_friend_notification_data_list()") #--- request --- types = input.list(input.u32) response = await self.get_friend_notification_data_list(client, types) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_update_matchmake_session(self, client, input, output): logger.info("MatchmakeExtensionServer.update_matchmake_session()") #--- request --- gathering = input.anydata() await self.update_matchmake_session(client, gathering) async def handle_auto_matchmake_with_search_criteria_postpone(self, client, input, output): logger.info("MatchmakeExtensionServer.auto_matchmake_with_search_criteria_postpone()") #--- request --- search_criteria = input.list(MatchmakeSessionSearchCriteria) gathering = input.anydata() message = input.string() response = await self.auto_matchmake_with_search_criteria_postpone(client, search_criteria, gathering, message) #--- response --- if not isinstance(response, Gathering): raise RuntimeError("Expected Gathering, got %s" %response.__class__.__name__) output.anydata(response) async def handle_get_playing_session(self, client, input, output): logger.info("MatchmakeExtensionServer.get_playing_session()") #--- request --- pids = input.list(input.pid) response = await self.get_playing_session(client, pids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_create_community(self, client, input, output): logger.info("MatchmakeExtensionServer.create_community()") #--- request --- community = input.extract(PersistentGathering) message = input.string() response = await self.create_community(client, community, message) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u32(response) async def handle_update_community(self, client, input, output): logger.info("MatchmakeExtensionServer.update_community()") #--- request --- community = input.extract(PersistentGathering) await self.update_community(client, community) async def handle_join_community(self, client, input, output): logger.info("MatchmakeExtensionServer.join_community()") #--- request --- gid = input.u32() message = input.string() password = input.string() await self.join_community(client, gid, message, password) async def handle_find_community_by_gathering_id(self, client, input, output): logger.info("MatchmakeExtensionServer.find_community_by_gathering_id()") #--- request --- gids = input.list(input.u32) response = await self.find_community_by_gathering_id(client, gids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_find_official_community(self, client, input, output): logger.info("MatchmakeExtensionServer.find_official_community()") #--- request --- available_only = input.bool() range = input.extract(common.ResultRange) response = await self.find_official_community(client, available_only, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_find_community_by_participant(self, client, input, output): logger.info("MatchmakeExtensionServer.find_community_by_participant()") #--- request --- pid = input.pid() range = input.extract(common.ResultRange) response = await self.find_community_by_participant(client, pid, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_update_privacy_setting(self, client, input, output): logger.info("MatchmakeExtensionServer.update_privacy_setting()") #--- request --- online_status = input.bool() community_participation = input.bool() await self.update_privacy_setting(client, online_status, community_participation) async def handle_get_my_block_list(self, client, input, output): logger.info("MatchmakeExtensionServer.get_my_block_list()") #--- request --- response = await self.get_my_block_list(client) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.pid) async def handle_add_to_block_list(self, client, input, output): logger.info("MatchmakeExtensionServer.add_to_block_list()") #--- request --- pids = input.list(input.pid) await self.add_to_block_list(client, pids) async def handle_remove_from_block_list(self, client, input, output): logger.info("MatchmakeExtensionServer.remove_from_block_list()") #--- request --- pids = input.list(input.pid) await self.remove_from_block_list(client, pids) async def handle_clear_my_block_list(self, client, input, output): logger.info("MatchmakeExtensionServer.clear_my_block_list()") #--- request --- await self.clear_my_block_list(client) async def handle_report_violation(self, client, input, output): logger.info("MatchmakeExtensionServer.report_violation()") #--- request --- pid = input.pid() username = input.string() violation_code = input.u32() await self.report_violation(client, pid, username, violation_code) async def handle_is_violation_user(self, client, input, output): logger.info("MatchmakeExtensionServer.is_violation_user()") #--- request --- response = await self.is_violation_user(client) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['flag', 'score']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.flag) output.u32(response.score) async def handle_join_matchmake_session_ex(self, client, input, output): logger.info("MatchmakeExtensionServer.join_matchmake_session_ex()") #--- request --- gid = input.u32() gmessage = input.string() ignore_block_list = input.bool() num_participants = input.u16() response = await self.join_matchmake_session_ex(client, gid, gmessage, ignore_block_list, num_participants) #--- response --- if not isinstance(response, bytes): raise RuntimeError("Expected bytes, got %s" %response.__class__.__name__) output.buffer(response) async def handle_get_simple_playing_session(self, client, input, output): logger.info("MatchmakeExtensionServer.get_simple_playing_session()") #--- request --- pids = input.list(input.pid) include_login_user = input.bool() response = await self.get_simple_playing_session(client, pids, include_login_user) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_simple_community(self, client, input, output): logger.info("MatchmakeExtensionServer.get_simple_community()") #--- request --- gids = input.list(input.u32) response = await self.get_simple_community(client, gids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_auto_matchmake_with_gathering_id_postpone(self, client, input, output): logger.info("MatchmakeExtensionServer.auto_matchmake_with_gathering_id_postpone()") #--- request --- gids = input.list(input.u32) gathering = input.anydata() message = input.string() response = await self.auto_matchmake_with_gathering_id_postpone(client, gids, gathering, message) #--- response --- if not isinstance(response, Gathering): raise RuntimeError("Expected Gathering, got %s" %response.__class__.__name__) output.anydata(response) async def handle_update_progress_score(self, client, input, output): logger.info("MatchmakeExtensionServer.update_progress_score()") #--- request --- gid = input.u32() score = input.u8() await self.update_progress_score(client, gid, score) async def handle_debug_notify_event(self, client, input, output): logger.info("MatchmakeExtensionServer.debug_notify_event()") #--- request --- pid = input.pid() main_type = input.u32() sub_type = input.u32() param1 = input.u64() param2 = input.u64() param3 = input.string() await self.debug_notify_event(client, pid, main_type, sub_type, param1, param2, param3) async def handle_generate_matchmake_session_system_password(self, client, input, output): logger.info("MatchmakeExtensionServer.generate_matchmake_session_system_password()") #--- request --- gid = input.u32() response = await self.generate_matchmake_session_system_password(client, gid) #--- response --- if not isinstance(response, str): raise RuntimeError("Expected str, got %s" %response.__class__.__name__) output.string(response) async def handle_clear_matchmake_session_system_password(self, client, input, output): logger.info("MatchmakeExtensionServer.clear_matchmake_session_system_password()") #--- request --- gid = input.u32() await self.clear_matchmake_session_system_password(client, gid) async def handle_create_matchmake_session_with_param(self, client, input, output): logger.info("MatchmakeExtensionServer.create_matchmake_session_with_param()") #--- request --- param = input.extract(CreateMatchmakeSessionParam) response = await self.create_matchmake_session_with_param(client, param) #--- response --- if not isinstance(response, MatchmakeSession): raise RuntimeError("Expected MatchmakeSession, got %s" %response.__class__.__name__) output.add(response) async def handle_join_matchmake_session_with_param(self, client, input, output): logger.info("MatchmakeExtensionServer.join_matchmake_session_with_param()") #--- request --- param = input.extract(JoinMatchmakeSessionParam) response = await self.join_matchmake_session_with_param(client, param) #--- response --- if not isinstance(response, MatchmakeSession): raise RuntimeError("Expected MatchmakeSession, got %s" %response.__class__.__name__) output.add(response) async def handle_auto_matchmake_with_param_postpone(self, client, input, output): logger.info("MatchmakeExtensionServer.auto_matchmake_with_param_postpone()") #--- request --- param = input.extract(AutoMatchmakeParam) response = await self.auto_matchmake_with_param_postpone(client, param) #--- response --- if not isinstance(response, MatchmakeSession): raise RuntimeError("Expected MatchmakeSession, got %s" %response.__class__.__name__) output.add(response) async def handle_find_matchmake_session_by_gathering_id_detail(self, client, input, output): logger.info("MatchmakeExtensionServer.find_matchmake_session_by_gathering_id_detail()") #--- request --- gid = input.u32() response = await self.find_matchmake_session_by_gathering_id_detail(client, gid) #--- response --- if not isinstance(response, MatchmakeSession): raise RuntimeError("Expected MatchmakeSession, got %s" %response.__class__.__name__) output.add(response) async def handle_browse_matchmake_session_no_holder(self, client, input, output): logger.info("MatchmakeExtensionServer.browse_matchmake_session_no_holder()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) range = input.extract(common.ResultRange) response = await self.browse_matchmake_session_no_holder(client, search_criteria, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_browse_matchmake_session_with_host_urls_no_holder(self, client, input, output): logger.info("MatchmakeExtensionServer.browse_matchmake_session_with_host_urls_no_holder()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) range = input.extract(common.ResultRange) response = await self.browse_matchmake_session_with_host_urls_no_holder(client, search_criteria, range) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['sessions', 'urls']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.sessions, output.add) output.list(response.urls, output.add) async def handle_update_matchmake_session_part(self, client, input, output): logger.info("MatchmakeExtensionServer.update_matchmake_session_part()") #--- request --- param = input.extract(UpdateMatchmakeSessionParam) await self.update_matchmake_session_part(client, param) async def handle_request_matchmaking(self, client, input, output): logger.info("MatchmakeExtensionServer.request_matchmaking()") #--- request --- param = input.extract(AutoMatchmakeParam) response = await self.request_matchmaking(client, param) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u64(response) async def handle_withdraw_matchmaking(self, client, input, output): logger.info("MatchmakeExtensionServer.withdraw_matchmaking()") #--- request --- request_id = input.u64() await self.withdraw_matchmaking(client, request_id) async def handle_withdraw_matchmaking_all(self, client, input, output): logger.info("MatchmakeExtensionServer.withdraw_matchmaking_all()") #--- request --- await self.withdraw_matchmaking_all(client) async def handle_find_matchmake_session_by_gathering_id(self, client, input, output): logger.info("MatchmakeExtensionServer.find_matchmake_session_by_gathering_id()") #--- request --- gids = input.list(input.u32) response = await self.find_matchmake_session_by_gathering_id(client, gids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_find_matchmake_session_by_single_gathering_id(self, client, input, output): logger.info("MatchmakeExtensionServer.find_matchmake_session_by_single_gathering_id()") #--- request --- gid = input.u32() response = await self.find_matchmake_session_by_single_gathering_id(client, gid) #--- response --- if not isinstance(response, MatchmakeSession): raise RuntimeError("Expected MatchmakeSession, got %s" %response.__class__.__name__) output.add(response) async def handle_find_matchmake_session_by_owner(self, client, input, output): logger.info("MatchmakeExtensionServer.find_matchmake_session_by_owner()") #--- request --- pid = input.pid() range = input.extract(common.ResultRange) response = await self.find_matchmake_session_by_owner(client, pid, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_find_matchmake_session_by_participant(self, client, input, output): logger.info("MatchmakeExtensionServer.find_matchmake_session_by_participant()") #--- request --- param = input.extract(FindMatchmakeSessionByParticipantParam) response = await self.find_matchmake_session_by_participant(client, param) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_browse_matchmake_session_no_holder_no_result_range(self, client, input, output): logger.info("MatchmakeExtensionServer.browse_matchmake_session_no_holder_no_result_range()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) response = await self.browse_matchmake_session_no_holder_no_result_range(client, search_criteria) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_browse_matchmake_session_with_host_urls_no_holder_no_result_range(self, client, input, output): logger.info("MatchmakeExtensionServer.browse_matchmake_session_with_host_urls_no_holder_no_result_range()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) response = await self.browse_matchmake_session_with_host_urls_no_holder_no_result_range(client, search_criteria) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['sessions', 'urls']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.sessions, output.add) output.list(response.urls, output.add) async def close_participation(self, *args): logger.warning("MatchmakeExtensionServer.close_participation not implemented") raise common.RMCError("Core::NotImplemented") async def open_participation(self, *args): logger.warning("MatchmakeExtensionServer.open_participation not implemented") raise common.RMCError("Core::NotImplemented") async def auto_matchmake_postpone(self, *args): logger.warning("MatchmakeExtensionServer.auto_matchmake_postpone not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session(self, *args): logger.warning("MatchmakeExtensionServer.browse_matchmake_session not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session_with_host_urls(self, *args): logger.warning("MatchmakeExtensionServer.browse_matchmake_session_with_host_urls not implemented") raise common.RMCError("Core::NotImplemented") async def create_matchmake_session(self, *args): logger.warning("MatchmakeExtensionServer.create_matchmake_session not implemented") raise common.RMCError("Core::NotImplemented") async def join_matchmake_session(self, *args): logger.warning("MatchmakeExtensionServer.join_matchmake_session not implemented") raise common.RMCError("Core::NotImplemented") async def modify_current_game_attribute(self, *args): logger.warning("MatchmakeExtensionServer.modify_current_game_attribute not implemented") raise common.RMCError("Core::NotImplemented") async def update_notification_data(self, *args): logger.warning("MatchmakeExtensionServer.update_notification_data not implemented") raise common.RMCError("Core::NotImplemented") async def get_friend_notification_data(self, *args): logger.warning("MatchmakeExtensionServer.get_friend_notification_data not implemented") raise common.RMCError("Core::NotImplemented") async def update_application_buffer(self, *args): logger.warning("MatchmakeExtensionServer.update_application_buffer not implemented") raise common.RMCError("Core::NotImplemented") async def update_matchmake_session_attribute(self, *args): logger.warning("MatchmakeExtensionServer.update_matchmake_session_attribute not implemented") raise common.RMCError("Core::NotImplemented") async def get_friend_notification_data_list(self, *args): logger.warning("MatchmakeExtensionServer.get_friend_notification_data_list not implemented") raise common.RMCError("Core::NotImplemented") async def update_matchmake_session(self, *args): logger.warning("MatchmakeExtensionServer.update_matchmake_session not implemented") raise common.RMCError("Core::NotImplemented") async def auto_matchmake_with_search_criteria_postpone(self, *args): logger.warning("MatchmakeExtensionServer.auto_matchmake_with_search_criteria_postpone not implemented") raise common.RMCError("Core::NotImplemented") async def get_playing_session(self, *args): logger.warning("MatchmakeExtensionServer.get_playing_session not implemented") raise common.RMCError("Core::NotImplemented") async def create_community(self, *args): logger.warning("MatchmakeExtensionServer.create_community not implemented") raise common.RMCError("Core::NotImplemented") async def update_community(self, *args): logger.warning("MatchmakeExtensionServer.update_community not implemented") raise common.RMCError("Core::NotImplemented") async def join_community(self, *args): logger.warning("MatchmakeExtensionServer.join_community not implemented") raise common.RMCError("Core::NotImplemented") async def find_community_by_gathering_id(self, *args): logger.warning("MatchmakeExtensionServer.find_community_by_gathering_id not implemented") raise common.RMCError("Core::NotImplemented") async def find_official_community(self, *args): logger.warning("MatchmakeExtensionServer.find_official_community not implemented") raise common.RMCError("Core::NotImplemented") async def find_community_by_participant(self, *args): logger.warning("MatchmakeExtensionServer.find_community_by_participant not implemented") raise common.RMCError("Core::NotImplemented") async def update_privacy_setting(self, *args): logger.warning("MatchmakeExtensionServer.update_privacy_setting not implemented") raise common.RMCError("Core::NotImplemented") async def get_my_block_list(self, *args): logger.warning("MatchmakeExtensionServer.get_my_block_list not implemented") raise common.RMCError("Core::NotImplemented") async def add_to_block_list(self, *args): logger.warning("MatchmakeExtensionServer.add_to_block_list not implemented") raise common.RMCError("Core::NotImplemented") async def remove_from_block_list(self, *args): logger.warning("MatchmakeExtensionServer.remove_from_block_list not implemented") raise common.RMCError("Core::NotImplemented") async def clear_my_block_list(self, *args): logger.warning("MatchmakeExtensionServer.clear_my_block_list not implemented") raise common.RMCError("Core::NotImplemented") async def report_violation(self, *args): logger.warning("MatchmakeExtensionServer.report_violation not implemented") raise common.RMCError("Core::NotImplemented") async def is_violation_user(self, *args): logger.warning("MatchmakeExtensionServer.is_violation_user not implemented") raise common.RMCError("Core::NotImplemented") async def join_matchmake_session_ex(self, *args): logger.warning("MatchmakeExtensionServer.join_matchmake_session_ex not implemented") raise common.RMCError("Core::NotImplemented") async def get_simple_playing_session(self, *args): logger.warning("MatchmakeExtensionServer.get_simple_playing_session not implemented") raise common.RMCError("Core::NotImplemented") async def get_simple_community(self, *args): logger.warning("MatchmakeExtensionServer.get_simple_community not implemented") raise common.RMCError("Core::NotImplemented") async def auto_matchmake_with_gathering_id_postpone(self, *args): logger.warning("MatchmakeExtensionServer.auto_matchmake_with_gathering_id_postpone not implemented") raise common.RMCError("Core::NotImplemented") async def update_progress_score(self, *args): logger.warning("MatchmakeExtensionServer.update_progress_score not implemented") raise common.RMCError("Core::NotImplemented") async def debug_notify_event(self, *args): logger.warning("MatchmakeExtensionServer.debug_notify_event not implemented") raise common.RMCError("Core::NotImplemented") async def generate_matchmake_session_system_password(self, *args): logger.warning("MatchmakeExtensionServer.generate_matchmake_session_system_password not implemented") raise common.RMCError("Core::NotImplemented") async def clear_matchmake_session_system_password(self, *args): logger.warning("MatchmakeExtensionServer.clear_matchmake_session_system_password not implemented") raise common.RMCError("Core::NotImplemented") async def create_matchmake_session_with_param(self, *args): logger.warning("MatchmakeExtensionServer.create_matchmake_session_with_param not implemented") raise common.RMCError("Core::NotImplemented") async def join_matchmake_session_with_param(self, *args): logger.warning("MatchmakeExtensionServer.join_matchmake_session_with_param not implemented") raise common.RMCError("Core::NotImplemented") async def auto_matchmake_with_param_postpone(self, *args): logger.warning("MatchmakeExtensionServer.auto_matchmake_with_param_postpone not implemented") raise common.RMCError("Core::NotImplemented") async def find_matchmake_session_by_gathering_id_detail(self, *args): logger.warning("MatchmakeExtensionServer.find_matchmake_session_by_gathering_id_detail not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session_no_holder(self, *args): logger.warning("MatchmakeExtensionServer.browse_matchmake_session_no_holder not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session_with_host_urls_no_holder(self, *args): logger.warning("MatchmakeExtensionServer.browse_matchmake_session_with_host_urls_no_holder not implemented") raise common.RMCError("Core::NotImplemented") async def update_matchmake_session_part(self, *args): logger.warning("MatchmakeExtensionServer.update_matchmake_session_part not implemented") raise common.RMCError("Core::NotImplemented") async def request_matchmaking(self, *args): logger.warning("MatchmakeExtensionServer.request_matchmaking not implemented") raise common.RMCError("Core::NotImplemented") async def withdraw_matchmaking(self, *args): logger.warning("MatchmakeExtensionServer.withdraw_matchmaking not implemented") raise common.RMCError("Core::NotImplemented") async def withdraw_matchmaking_all(self, *args): logger.warning("MatchmakeExtensionServer.withdraw_matchmaking_all not implemented") raise common.RMCError("Core::NotImplemented") async def find_matchmake_session_by_gathering_id(self, *args): logger.warning("MatchmakeExtensionServer.find_matchmake_session_by_gathering_id not implemented") raise common.RMCError("Core::NotImplemented") async def find_matchmake_session_by_single_gathering_id(self, *args): logger.warning("MatchmakeExtensionServer.find_matchmake_session_by_single_gathering_id not implemented") raise common.RMCError("Core::NotImplemented") async def find_matchmake_session_by_owner(self, *args): logger.warning("MatchmakeExtensionServer.find_matchmake_session_by_owner not implemented") raise common.RMCError("Core::NotImplemented") async def find_matchmake_session_by_participant(self, *args): logger.warning("MatchmakeExtensionServer.find_matchmake_session_by_participant not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session_no_holder_no_result_range(self, *args): logger.warning("MatchmakeExtensionServer.browse_matchmake_session_no_holder_no_result_range not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session_with_host_urls_no_holder_no_result_range(self, *args): logger.warning("MatchmakeExtensionServer.browse_matchmake_session_with_host_urls_no_holder_no_result_range not implemented") raise common.RMCError("Core::NotImplemented") class MatchmakeRefereeServer(MatchmakeRefereeProtocol): def __init__(self): self.methods = { self.METHOD_START_ROUND: self.handle_start_round, self.METHOD_GET_START_ROUND_PARAM: self.handle_get_start_round_param, self.METHOD_END_ROUND: self.handle_end_round, self.METHOD_END_ROUND_WITH_PARTIAL_REPORT: self.handle_end_round_with_partial_report, self.METHOD_END_ROUND_WITHOUT_REPORT: self.handle_end_round_without_report, self.METHOD_GET_ROUND_PARTICIPANTS: self.handle_get_round_participants, self.METHOD_GET_NOT_SUMMARIZED_ROUND: self.handle_get_not_summarized_round, self.METHOD_GET_ROUND: self.handle_get_round, self.METHOD_GET_STATS_PRIMARY: self.handle_get_stats_primary, self.METHOD_GET_STATS_PRIMARIES: self.handle_get_stats_primaries, self.METHOD_GET_STATS_ALL: self.handle_get_stats_all, self.METHOD_CREATE_STATS: self.handle_create_stats, self.METHOD_GET_OR_CREATE_STATS: self.handle_get_or_create_stats, self.METHOD_RESET_STATS: self.handle_reset_stats, self.METHOD_GET_EVENT_POINT: self.handle_get_event_point, self.METHOD_RESET_EVENT_POINT: self.handle_reset_event_point, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on MatchmakeRefereeServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_start_round(self, client, input, output): logger.info("MatchmakeRefereeServer.start_round()") #--- request --- param = input.extract(MatchmakeRefereeStartRoundParam) response = await self.start_round(client, param) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u64(response) async def handle_get_start_round_param(self, client, input, output): logger.info("MatchmakeRefereeServer.get_start_round_param()") #--- request --- round_id = input.u64() response = await self.get_start_round_param(client, round_id) #--- response --- if not isinstance(response, MatchmakeRefereeStartRoundParam): raise RuntimeError("Expected MatchmakeRefereeStartRoundParam, got %s" %response.__class__.__name__) output.add(response) async def handle_end_round(self, client, input, output): logger.info("MatchmakeRefereeServer.end_round()") #--- request --- param = input.extract(MatchmakeRefereeEndRoundParam) await self.end_round(client, param) async def handle_end_round_with_partial_report(self, client, input, output): logger.info("MatchmakeRefereeServer.end_round_with_partial_report()") #--- request --- param = input.extract(MatchmakeRefereeEndRoundParam) await self.end_round_with_partial_report(client, param) async def handle_end_round_without_report(self, client, input, output): logger.info("MatchmakeRefereeServer.end_round_without_report()") #--- request --- round_id = input.u64() await self.end_round_without_report(client, round_id) async def handle_get_round_participants(self, client, input, output): logger.info("MatchmakeRefereeServer.get_round_participants()") #--- request --- round_id = input.u64() response = await self.get_round_participants(client, round_id) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.pid) async def handle_get_not_summarized_round(self, client, input, output): logger.info("MatchmakeRefereeServer.get_not_summarized_round()") #--- request --- response = await self.get_not_summarized_round(client) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_round(self, client, input, output): logger.info("MatchmakeRefereeServer.get_round()") #--- request --- round = input.u64() response = await self.get_round(client, round) #--- response --- if not isinstance(response, MatchmakeRefereeRound): raise RuntimeError("Expected MatchmakeRefereeRound, got %s" %response.__class__.__name__) output.add(response) async def handle_get_stats_primary(self, client, input, output): logger.info("MatchmakeRefereeServer.get_stats_primary()") #--- request --- target = input.extract(MatchmakeRefereeStatsTarget) response = await self.get_stats_primary(client, target) #--- response --- if not isinstance(response, MatchmakeRefereeStats): raise RuntimeError("Expected MatchmakeRefereeStats, got %s" %response.__class__.__name__) output.add(response) async def handle_get_stats_primaries(self, client, input, output): logger.info("MatchmakeRefereeServer.get_stats_primaries()") #--- request --- targets = input.list(MatchmakeRefereeStatsTarget) response = await self.get_stats_primaries(client, targets) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['stats', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.stats, output.add) output.list(response.results, output.result) async def handle_get_stats_all(self, client, input, output): logger.info("MatchmakeRefereeServer.get_stats_all()") #--- request --- target = input.extract(MatchmakeRefereeStatsTarget) response = await self.get_stats_all(client, target) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_create_stats(self, client, input, output): logger.info("MatchmakeRefereeServer.create_stats()") #--- request --- param = input.extract(MatchmakeRefereeStatsInitParam) response = await self.create_stats(client, param) #--- response --- if not isinstance(response, MatchmakeRefereeStats): raise RuntimeError("Expected MatchmakeRefereeStats, got %s" %response.__class__.__name__) output.add(response) async def handle_get_or_create_stats(self, client, input, output): logger.info("MatchmakeRefereeServer.get_or_create_stats()") #--- request --- param = input.extract(MatchmakeRefereeStatsInitParam) response = await self.get_or_create_stats(client, param) #--- response --- if not isinstance(response, MatchmakeRefereeStats): raise RuntimeError("Expected MatchmakeRefereeStats, got %s" %response.__class__.__name__) output.add(response) async def handle_reset_stats(self, client, input, output): logger.info("MatchmakeRefereeServer.reset_stats()") #--- request --- await self.reset_stats(client) async def handle_get_event_point(self, client, input, output): logger.warning("MatchmakeRefereeServer.get_event_point is not supported") raise common.RMCError("Core::NotImplemented") async def handle_reset_event_point(self, client, input, output): logger.warning("MatchmakeRefereeServer.reset_event_point is not supported") raise common.RMCError("Core::NotImplemented") async def start_round(self, *args): logger.warning("MatchmakeRefereeServer.start_round not implemented") raise common.RMCError("Core::NotImplemented") async def get_start_round_param(self, *args): logger.warning("MatchmakeRefereeServer.get_start_round_param not implemented") raise common.RMCError("Core::NotImplemented") async def end_round(self, *args): logger.warning("MatchmakeRefereeServer.end_round not implemented") raise common.RMCError("Core::NotImplemented") async def end_round_with_partial_report(self, *args): logger.warning("MatchmakeRefereeServer.end_round_with_partial_report not implemented") raise common.RMCError("Core::NotImplemented") async def end_round_without_report(self, *args): logger.warning("MatchmakeRefereeServer.end_round_without_report not implemented") raise common.RMCError("Core::NotImplemented") async def get_round_participants(self, *args): logger.warning("MatchmakeRefereeServer.get_round_participants not implemented") raise common.RMCError("Core::NotImplemented") async def get_not_summarized_round(self, *args): logger.warning("MatchmakeRefereeServer.get_not_summarized_round not implemented") raise common.RMCError("Core::NotImplemented") async def get_round(self, *args): logger.warning("MatchmakeRefereeServer.get_round not implemented") raise common.RMCError("Core::NotImplemented") async def get_stats_primary(self, *args): logger.warning("MatchmakeRefereeServer.get_stats_primary not implemented") raise common.RMCError("Core::NotImplemented") async def get_stats_primaries(self, *args): logger.warning("MatchmakeRefereeServer.get_stats_primaries not implemented") raise common.RMCError("Core::NotImplemented") async def get_stats_all(self, *args): logger.warning("MatchmakeRefereeServer.get_stats_all not implemented") raise common.RMCError("Core::NotImplemented") async def create_stats(self, *args): logger.warning("MatchmakeRefereeServer.create_stats not implemented") raise common.RMCError("Core::NotImplemented") async def get_or_create_stats(self, *args): logger.warning("MatchmakeRefereeServer.get_or_create_stats not implemented") raise common.RMCError("Core::NotImplemented") async def reset_stats(self, *args): logger.warning("MatchmakeRefereeServer.reset_stats not implemented") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/matchmaking_mhxx.py ================================================ # This file was generated automatically by generate_protocols.py from nintendo.nex import notification, rmc, common, streams import logging logger = logging.getLogger(__name__) class MatchmakeSystem: GLOBAL = 1 FRIENDS = 2 class Gathering(common.Structure): def __init__(self): super().__init__() self.id = 0 self.owner = 0 self.host = 0 self.min_participants = 0 self.max_participants = 0 self.participation_policy = 1 self.policy_argument = 0 self.flags = 512 self.state = 0 self.description = "" def check_required(self, settings, version): pass def load(self, stream, version): self.id = stream.u32() self.owner = stream.pid() self.host = stream.pid() self.min_participants = stream.u16() self.max_participants = stream.u16() self.participation_policy = stream.u32() self.policy_argument = stream.u32() self.flags = stream.u32() self.state = stream.u32() self.description = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.id) stream.pid(self.owner) stream.pid(self.host) stream.u16(self.min_participants) stream.u16(self.max_participants) stream.u32(self.participation_policy) stream.u32(self.policy_argument) stream.u32(self.flags) stream.u32(self.state) stream.string(self.description) class GatheringURLs(common.Structure): def __init__(self): super().__init__() self.gid = None self.urls = None def check_required(self, settings, version): for field in ['gid', 'urls']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.gid = stream.u32() self.urls = stream.list(stream.stationurl) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.gid) stream.list(self.urls, stream.stationurl) class GatheringStats(common.Structure): def __init__(self): super().__init__() self.pid = None self.flags = None self.values = None def check_required(self, settings, version): for field in ['pid', 'flags', 'values']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.flags = stream.u32() self.values = stream.list(stream.float) def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.u32(self.flags) stream.list(self.values, stream.float) class Invitation(common.Structure): def __init__(self): super().__init__() self.gid = None self.guest = None self.message = None def check_required(self, settings, version): for field in ['gid', 'guest', 'message']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.gid = stream.u32() self.guest = stream.u32() self.message = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.gid) stream.u32(self.guest) stream.string(self.message) class ParticipantDetails(common.Structure): def __init__(self): super().__init__() self.pid = None self.name = None self.message = None self.participants = None def check_required(self, settings, version): for field in ['pid', 'name', 'message', 'participants']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.name = stream.string() self.message = stream.string() self.participants = stream.u16() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.string(self.name) stream.string(self.message) stream.u16(self.participants) class DeletionEntry(common.Structure): def __init__(self): super().__init__() self.gid = None self.pid = None self.reason = None def check_required(self, settings, version): for field in ['gid', 'pid', 'reason']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.gid = stream.u32() self.pid = stream.pid() self.reason = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.gid) stream.pid(self.pid) stream.u32(self.reason) class MatchmakeParam(common.Structure): def __init__(self): super().__init__() self.param = {} def check_required(self, settings, version): pass def load(self, stream, version): self.param = stream.map(stream.string, stream.variant) def save(self, stream, version): self.check_required(stream.settings, version) stream.map(self.param, stream.string, stream.variant) class MatchmakeSessionSearchCriteria(common.Structure): def __init__(self): super().__init__() self.attribs = ["", "", "", "", "", ""] self.game_mode = "" self.min_participants = "" self.max_participants = "" self.matchmake_system = "" self.vacant_only = True self.exclude_locked = True self.exclude_non_host_pid = False self.selection_method = 0 self.vacant_participants = 1 self.param = MatchmakeParam() self.exclude_user_password = False self.exclude_system_password = False self.refer_gid = 0 self.codeword = "" self.range = common.ResultRange() def check_required(self, settings, version): if settings["nex.version"] >= 30500: pass if settings["nex.version"] >= 40000: pass def load(self, stream, version): self.attribs = stream.list(stream.string) self.game_mode = stream.string() self.min_participants = stream.string() self.max_participants = stream.string() self.matchmake_system = stream.string() self.vacant_only = stream.bool() self.exclude_locked = stream.bool() self.exclude_non_host_pid = stream.bool() self.selection_method = stream.u32() if stream.settings["nex.version"] >= 30500: self.vacant_participants = stream.u16() if stream.settings["nex.version"] >= 40000: self.param = stream.extract(MatchmakeParam) self.exclude_user_password = stream.bool() self.exclude_system_password = stream.bool() self.refer_gid = stream.u32() self.codeword = stream.string() self.range = stream.extract(common.ResultRange) def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.attribs, stream.string) stream.string(self.game_mode) stream.string(self.min_participants) stream.string(self.max_participants) stream.string(self.matchmake_system) stream.bool(self.vacant_only) stream.bool(self.exclude_locked) stream.bool(self.exclude_non_host_pid) stream.u32(self.selection_method) if stream.settings["nex.version"] >= 30500: stream.u16(self.vacant_participants) if stream.settings["nex.version"] >= 40000: stream.add(self.param) stream.bool(self.exclude_user_password) stream.bool(self.exclude_system_password) stream.u32(self.refer_gid) stream.string(self.codeword) stream.add(self.range) class MatchmakeSession(Gathering): def __init__(self): super().__init__() self.game_mode = 0 self.attribs = [0, 0, 0, 0, 0, 0] self.open_participation = True self.matchmake_system = 0 self.application_data = b"" self.num_participants = 0 self.progress_score = 100 self.session_key = b"" self.option = 0 self.param = MatchmakeParam() self.started_time = common.DateTime(0) self.user_password = "" self.refer_gid = 0 self.user_password_enabled = False self.system_password_enabled = False self.codeword = "" def max_version(self, settings): version = 0 if 30000 <= settings["nex.version"] < 40000: if settings["nex.version"] >= 30600: version = 1 if settings["nex.version"] >= 30700: version = 2 if settings["nex.version"] >= 30800: version = 3 return version def check_required(self, settings, version): if 30000 <= settings["nex.version"] < 40000: if settings["nex.version"] >= 30500: pass if settings["nex.version"] >= 30000: pass if settings["nex.version"] >= 30500: pass if settings["nex.version"] >= 30600: if version >= 1: pass if settings["nex.version"] >= 30700: if version >= 2: pass if settings["nex.version"] >= 30800: if version >= 3: pass if settings["nex.version"] >= 40000: pass def load(self, stream, version): self.game_mode = stream.u32() self.attribs = stream.list(stream.u32) self.open_participation = stream.bool() self.matchmake_system = stream.u32() self.application_data = stream.buffer() self.num_participants = stream.u32() if 30000 <= stream.settings["nex.version"] < 40000: if stream.settings["nex.version"] >= 30500: self.progress_score = stream.u8() if stream.settings["nex.version"] >= 30000: self.session_key = stream.buffer() if stream.settings["nex.version"] >= 30500: self.option = stream.u32() if stream.settings["nex.version"] >= 30600: if version >= 1: self.param = stream.extract(MatchmakeParam) self.started_time = stream.datetime() if stream.settings["nex.version"] >= 30700: if version >= 2: self.user_password = stream.string() if stream.settings["nex.version"] >= 30800: if version >= 3: self.refer_gid = stream.u32() self.user_password_enabled = stream.bool() self.system_password_enabled = stream.bool() if stream.settings["nex.version"] >= 40000: self.progress_score = stream.u8() self.session_key = stream.buffer() self.option = stream.u32() self.param = stream.extract(MatchmakeParam) self.started_time = stream.datetime() self.user_password = stream.string() self.refer_gid = stream.u32() self.user_password_enabled = stream.bool() self.system_password_enabled = stream.bool() self.codeword = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.game_mode) stream.list(self.attribs, stream.u32) stream.bool(self.open_participation) stream.u32(self.matchmake_system) stream.buffer(self.application_data) stream.u32(self.num_participants) if 30000 <= stream.settings["nex.version"] < 40000: if stream.settings["nex.version"] >= 30500: stream.u8(self.progress_score) if stream.settings["nex.version"] >= 30000: stream.buffer(self.session_key) if stream.settings["nex.version"] >= 30500: stream.u32(self.option) if stream.settings["nex.version"] >= 30600: if version >= 1: stream.add(self.param) stream.datetime(self.started_time) if stream.settings["nex.version"] >= 30700: if version >= 2: stream.string(self.user_password) if stream.settings["nex.version"] >= 30800: if version >= 3: stream.u32(self.refer_gid) stream.bool(self.user_password_enabled) stream.bool(self.system_password_enabled) if stream.settings["nex.version"] >= 40000: stream.u8(self.progress_score) stream.buffer(self.session_key) stream.u32(self.option) stream.add(self.param) stream.datetime(self.started_time) stream.string(self.user_password) stream.u32(self.refer_gid) stream.bool(self.user_password_enabled) stream.bool(self.system_password_enabled) stream.string(self.codeword) common.DataHolder.register(MatchmakeSession, "MatchmakeSession") class MatchmakeBlockListParam(common.Structure): def __init__(self): super().__init__() self.options = 0 def check_required(self, settings, version): pass def load(self, stream, version): self.options = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.options) class CreateMatchmakeSessionParam(common.Structure): def __init__(self): super().__init__() self.session = MatchmakeSession() self.additional_participants = None self.gid_for_participation_check = None self.options = None self.join_message = None self.num_participants = None def check_required(self, settings, version): for field in ['additional_participants', 'gid_for_participation_check', 'options', 'join_message', 'num_participants']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.session = stream.extract(MatchmakeSession) self.additional_participants = stream.list(stream.pid) self.gid_for_participation_check = stream.u32() self.options = stream.u32() self.join_message = stream.string() self.num_participants = stream.u16() def save(self, stream, version): self.check_required(stream.settings, version) stream.add(self.session) stream.list(self.additional_participants, stream.pid) stream.u32(self.gid_for_participation_check) stream.u32(self.options) stream.string(self.join_message) stream.u16(self.num_participants) class JoinMatchmakeSessionParam(common.Structure): def __init__(self): super().__init__() self.gid = None self.participants = None self.gid_for_participation_check = None self.options = None self.behavior = None self.user_password = None self.system_password = None self.join_message = None self.num_participants = None self.extra_participants = None self.block_list = MatchmakeBlockListParam() def check_required(self, settings, version): for field in ['gid', 'participants', 'gid_for_participation_check', 'options', 'behavior', 'user_password', 'system_password', 'join_message', 'num_participants', 'extra_participants']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.gid = stream.u32() self.participants = stream.list(stream.pid) self.gid_for_participation_check = stream.u32() self.options = stream.u32() self.behavior = stream.u8() self.user_password = stream.string() self.system_password = stream.string() self.join_message = stream.string() self.num_participants = stream.u16() self.extra_participants = stream.u16() self.block_list = stream.extract(MatchmakeBlockListParam) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.gid) stream.list(self.participants, stream.pid) stream.u32(self.gid_for_participation_check) stream.u32(self.options) stream.u8(self.behavior) stream.string(self.user_password) stream.string(self.system_password) stream.string(self.join_message) stream.u16(self.num_participants) stream.u16(self.extra_participants) stream.add(self.block_list) class UpdateMatchmakeSessionParam(common.Structure): def __init__(self): super().__init__() self.gid = None self.modification_flags = None self.attributes = None self.open_participation = None self.application_buffer = None self.progress_score = None self.param = MatchmakeParam() self.started_time = None self.user_password = None self.game_mode = None self.description = None self.min_participants = None self.max_participants = None self.matchmake_system = None self.participation_policy = None self.policy_argument = None self.codeword = None def check_required(self, settings, version): for field in ['gid', 'modification_flags', 'attributes', 'open_participation', 'application_buffer', 'progress_score', 'started_time', 'user_password', 'game_mode', 'description', 'min_participants', 'max_participants', 'matchmake_system', 'participation_policy', 'policy_argument', 'codeword']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.gid = stream.u32() self.modification_flags = stream.u32() self.attributes = stream.list(stream.u32) self.open_participation = stream.bool() self.application_buffer = stream.buffer() self.progress_score = stream.u8() self.param = stream.extract(MatchmakeParam) self.started_time = stream.datetime() self.user_password = stream.string() self.game_mode = stream.u32() self.description = stream.string() self.min_participants = stream.u16() self.max_participants = stream.u16() self.matchmake_system = stream.u32() self.participation_policy = stream.u32() self.policy_argument = stream.u32() self.codeword = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.gid) stream.u32(self.modification_flags) stream.list(self.attributes, stream.u32) stream.bool(self.open_participation) stream.buffer(self.application_buffer) stream.u8(self.progress_score) stream.add(self.param) stream.datetime(self.started_time) stream.string(self.user_password) stream.u32(self.game_mode) stream.string(self.description) stream.u16(self.min_participants) stream.u16(self.max_participants) stream.u32(self.matchmake_system) stream.u32(self.participation_policy) stream.u32(self.policy_argument) stream.string(self.codeword) class AutoMatchmakeParam(common.Structure): def __init__(self): super().__init__() self.session = MatchmakeSession() self.participants = None self.gid_for_participation_check = None self.options = None self.join_message = None self.num_participants = None self.search_criteria = None self.target_gids = None self.block_list = MatchmakeBlockListParam() def check_required(self, settings, version): for field in ['participants', 'gid_for_participation_check', 'options', 'join_message', 'num_participants', 'search_criteria', 'target_gids']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.session = stream.extract(MatchmakeSession) self.participants = stream.list(stream.pid) self.gid_for_participation_check = stream.u32() self.options = stream.u32() self.join_message = stream.string() self.num_participants = stream.u16() self.search_criteria = stream.list(MatchmakeSessionSearchCriteria) self.target_gids = stream.list(stream.u32) self.block_list = stream.extract(MatchmakeBlockListParam) def save(self, stream, version): self.check_required(stream.settings, version) stream.add(self.session) stream.list(self.participants, stream.pid) stream.u32(self.gid_for_participation_check) stream.u32(self.options) stream.string(self.join_message) stream.u16(self.num_participants) stream.list(self.search_criteria, stream.add) stream.list(self.target_gids, stream.u32) stream.add(self.block_list) class FindMatchmakeSessionByParticipantParam(common.Structure): def __init__(self): super().__init__() self.pids = None self.options = None self.block_list = MatchmakeBlockListParam() def check_required(self, settings, version): for field in ['pids', 'options']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pids = stream.list(stream.pid) self.options = stream.u32() self.block_list = stream.extract(MatchmakeBlockListParam) def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.pids, stream.pid) stream.u32(self.options) stream.add(self.block_list) class FindMatchmakeSessionByParticipantResult(common.Structure): def __init__(self): super().__init__() self.pid = None self.session = MatchmakeSession() def check_required(self, settings, version): for field in ['pid']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.session = stream.extract(MatchmakeSession) def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.add(self.session) class PersistentGathering(Gathering): def __init__(self): super().__init__() self.type = None self.password = None self.attribs = None self.application_buffer = None self.participation_start = None self.participation_end = None self.matchmake_session_count = None self.num_participants = None def check_required(self, settings, version): for field in ['type', 'password', 'attribs', 'application_buffer', 'participation_start', 'participation_end', 'matchmake_session_count', 'num_participants']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.type = stream.u32() self.password = stream.string() self.attribs = stream.list(stream.u32) self.application_buffer = stream.buffer() self.participation_start = stream.datetime() self.participation_end = stream.datetime() self.matchmake_session_count = stream.u32() self.num_participants = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.type) stream.string(self.password) stream.list(self.attribs, stream.u32) stream.buffer(self.application_buffer) stream.datetime(self.participation_start) stream.datetime(self.participation_end) stream.u32(self.matchmake_session_count) stream.u32(self.num_participants) common.DataHolder.register(PersistentGathering, "PersistentGathering") class SimpleCommunity(common.Structure): def __init__(self): super().__init__() self.gid = None self.matchmake_session_count = None def check_required(self, settings, version): for field in ['gid', 'matchmake_session_count']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.gid = stream.u32() self.matchmake_session_count = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.gid) stream.u32(self.matchmake_session_count) class PlayingSession(common.Structure): def __init__(self): super().__init__() self.pid = None self.gathering = None def check_required(self, settings, version): for field in ['pid', 'gathering']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.gathering = stream.anydata() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.anydata(self.gathering) class SimplePlayingSession(common.Structure): def __init__(self): super().__init__() self.pid = None self.gid = None self.game_mode = None self.attribute = None def check_required(self, settings, version): for field in ['pid', 'gid', 'game_mode', 'attribute']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.gid = stream.u32() self.game_mode = stream.u32() self.attribute = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.u32(self.gid) stream.u32(self.game_mode) stream.u32(self.attribute) class MatchmakeRefereeRound(common.Structure): def __init__(self): super().__init__() self.id = None self.gid = None self.state = None self.personal_data_category = None self.results = None def check_required(self, settings, version): for field in ['id', 'gid', 'state', 'personal_data_category', 'results']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.id = stream.u64() self.gid = stream.u32() self.state = stream.u32() self.personal_data_category = stream.u32() self.results = stream.list(MatchmakeRefereePersonalRoundResult) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.id) stream.u32(self.gid) stream.u32(self.state) stream.u32(self.personal_data_category) stream.list(self.results, stream.add) class MatchmakeRefereeStartRoundParam(common.Structure): def __init__(self): super().__init__() self.personal_data_category = None self.gid = None self.pids = None def check_required(self, settings, version): for field in ['personal_data_category', 'gid', 'pids']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.personal_data_category = stream.u32() self.gid = stream.u32() self.pids = stream.list(stream.pid) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.personal_data_category) stream.u32(self.gid) stream.list(self.pids, stream.pid) class MatchmakeRefereeEndRoundParam(common.Structure): def __init__(self): super().__init__() self.round_id = None self.results = None def check_required(self, settings, version): for field in ['round_id', 'results']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.round_id = stream.u64() self.results = stream.list(MatchmakeRefereePersonalRoundResult) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.round_id) stream.list(self.results, stream.add) class MatchmakeRefereePersonalRoundResult(common.Structure): def __init__(self): super().__init__() self.pid = None self.personal_round_result_flag = None self.round_win_loss = None self.rating_change = None self.buffer = None def check_required(self, settings, version): for field in ['pid', 'personal_round_result_flag', 'round_win_loss', 'rating_change', 'buffer']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.personal_round_result_flag = stream.u32() self.round_win_loss = stream.u32() self.rating_change = stream.s32() self.buffer = stream.qbuffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.u32(self.personal_round_result_flag) stream.u32(self.round_win_loss) stream.s32(self.rating_change) stream.qbuffer(self.buffer) class MatchmakeRefereeStats(common.Structure): def __init__(self): super().__init__() self.unique_id = None self.category = None self.pid = None self.recent_disconnection = None self.recent_violation = None self.recent_mismatch = None self.recent_win = None self.recent_loss = None self.recent_draw = None self.total_disconnect = None self.total_violation = None self.total_mismatch = None self.total_win = None self.total_loss = None self.total_draw = None self.rating_value = None def check_required(self, settings, version): for field in ['unique_id', 'category', 'pid', 'recent_disconnection', 'recent_violation', 'recent_mismatch', 'recent_win', 'recent_loss', 'recent_draw', 'total_disconnect', 'total_violation', 'total_mismatch', 'total_win', 'total_loss', 'total_draw', 'rating_value']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.unique_id = stream.u64() self.category = stream.u32() self.pid = stream.pid() self.recent_disconnection = stream.u32() self.recent_violation = stream.u32() self.recent_mismatch = stream.u32() self.recent_win = stream.u32() self.recent_loss = stream.u32() self.recent_draw = stream.u32() self.total_disconnect = stream.u32() self.total_violation = stream.u32() self.total_mismatch = stream.u32() self.total_win = stream.u32() self.total_loss = stream.u32() self.total_draw = stream.u32() self.rating_value = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.unique_id) stream.u32(self.category) stream.pid(self.pid) stream.u32(self.recent_disconnection) stream.u32(self.recent_violation) stream.u32(self.recent_mismatch) stream.u32(self.recent_win) stream.u32(self.recent_loss) stream.u32(self.recent_draw) stream.u32(self.total_disconnect) stream.u32(self.total_violation) stream.u32(self.total_mismatch) stream.u32(self.total_win) stream.u32(self.total_loss) stream.u32(self.total_draw) stream.u32(self.rating_value) class MatchmakeRefereeStatsTarget(common.Structure): def __init__(self): super().__init__() self.pid = None self.category = None def check_required(self, settings, version): for field in ['pid', 'category']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.category = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.u32(self.category) class MatchmakeRefereeStatsInitParam(common.Structure): def __init__(self): super().__init__() self.category = None self.initial_rating = None def check_required(self, settings, version): for field in ['category', 'initial_rating']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.category = stream.u32() self.initial_rating = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.category) stream.u32(self.initial_rating) class FriendUserParam(common.Structure): def __init__(self): super().__init__() self.name = None def check_required(self, settings, version): for field in ['name']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.name = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.name) class FriendUserInfo(common.Structure): def __init__(self): super().__init__() self.pid = None self.name = None self.presence = None def check_required(self, settings, version): for field in ['pid', 'name', 'presence']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.u64() self.name = stream.string() self.presence = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.pid) stream.string(self.name) stream.u32(self.presence) class MatchMakingProtocol: METHOD_REGISTER_GATHERING = 1 METHOD_UNREGISTER_GATHERING = 2 METHOD_UNREGISTER_GATHERINGS = 3 METHOD_UPDATE_GATHERING = 4 METHOD_INVITE = 5 METHOD_ACCEPT_INVITATION = 6 METHOD_DECLINE_INVITATION = 7 METHOD_CANCEL_INVITATION = 8 METHOD_GET_INVITATIONS_SENT = 9 METHOD_GET_INVITATIONS_RECEIVED = 10 METHOD_PARTICIPATE = 11 METHOD_CANCEL_PARTICIPATION = 12 METHOD_GET_PARTICIPANTS = 13 METHOD_ADD_PARTICIPANTS = 14 METHOD_GET_DETAILED_PARTICIPANTS = 15 METHOD_GET_PARTICIPANTS_URLS = 16 METHOD_FIND_BY_TYPE = 17 METHOD_FIND_BY_DESCRIPTION = 18 METHOD_FIND_BY_DESCRIPTION_REGEX = 19 METHOD_FIND_BY_ID = 20 METHOD_FIND_BY_SINGLE_ID = 21 METHOD_FIND_BY_OWNER = 22 METHOD_FIND_BY_PARTICIPANTS = 23 METHOD_FIND_INVITATIONS = 24 METHOD_FIND_BY_SQL_QUERY = 25 METHOD_LAUNCH_SESSION = 26 METHOD_UPDATE_SESSION_URL = 27 METHOD_GET_SESSION_URL = 28 METHOD_GET_STATE = 29 METHOD_SET_STATE = 30 METHOD_REPORT_STATS = 31 METHOD_GET_STATS = 32 METHOD_DELETE_GATHERING = 33 METHOD_GET_PENDING_DELETIONS = 34 METHOD_DELETE_FROM_DELETIONS = 35 METHOD_MIGRATE_GATHERING_OWNERSHIP_V1 = 36 METHOD_FIND_BY_DESCRIPTION_LIKE = 37 METHOD_REGISTER_LOCAL_URL = 38 METHOD_REGISTER_LOCAL_URLS = 39 METHOD_UPDATE_SESSION_HOST_V1 = 40 METHOD_GET_SESSION_URLS = 41 METHOD_UPDATE_SESSION_HOST = 42 METHOD_UPDATE_GATHERING_OWNERSHIP = 43 METHOD_MIGRATE_GATHERING_OWNERSHIP = 44 PROTOCOL_ID = 0x15 class MatchMakingProtocolExt: METHOD_END_PARTICIPATION = 1 METHOD_GET_PARTICIPANTS = 2 METHOD_GET_DETAILED_PARTICIPANTS = 3 METHOD_GET_PARTICIPANTS_URLS = 4 METHOD_GET_GATHERING_RELATIONS = 5 METHOD_DELETE_FROM_DELETIONS = 6 PROTOCOL_ID = 0x32 class MatchmakeRefereeProtocol: METHOD_START_ROUND = 1 METHOD_GET_START_ROUND_PARAM = 2 METHOD_END_ROUND = 3 METHOD_END_ROUND_WITHOUT_REPORT = 4 METHOD_GET_ROUND_PARTICIPANTS = 5 METHOD_GET_NOT_SUMMARIZED_ROUND = 6 METHOD_GET_ROUND = 7 METHOD_GET_STATS_PRIMARY = 8 METHOD_GET_STATS_PRIMARIES = 9 METHOD_GET_STATS_ALL = 10 METHOD_CREATE_STATS = 11 METHOD_GET_OR_CREATE_STATS = 12 METHOD_RESET_STATS = 13 PROTOCOL_ID = 0x78 class MatchmakeExtensionProtocolMHXX: METHOD_CLOSE_PARTICIPATION = 1 METHOD_OPEN_PARTICIPATION = 2 METHOD_AUTO_MATCHMAKE_POSTPONE = 3 METHOD_BROWSE_MATCHMAKE_SESSION = 4 METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS = 5 METHOD_CREATE_MATCHMAKE_SESSION = 6 METHOD_JOIN_MATCHMAKE_SESSION = 7 METHOD_MODIFY_CURRENT_GAME_ATTRIBUTE = 8 METHOD_UPDATE_NOTIFICATION_DATA = 9 METHOD_GET_FRIEND_NOTIFICATION_DATA = 10 METHOD_UPDATE_APPLICATION_BUFFER = 11 METHOD_UPDATE_MATCHMAKE_SESSION_ATTRIBUTE = 12 METHOD_GET_FRIEND_NOTIFICATION_DATA_LIST = 13 METHOD_UPDATE_MATCHMAKE_SESSION = 14 METHOD_AUTO_MATCHMAKE_WITH_SEARCH_CRITERIA_POSTPONE = 15 METHOD_GET_PLAYING_SESSION = 16 METHOD_CREATE_COMMUNITY = 17 METHOD_UPDATE_COMMUNITY = 18 METHOD_JOIN_COMMUNITY = 19 METHOD_FIND_COMMUNITY_BY_GATHERING_ID = 20 METHOD_FIND_OFFICIAL_COMMUNITY = 21 METHOD_FIND_COMMUNITY_BY_PARTICIPANT = 22 METHOD_UPDATE_PRIVACY_SETTING = 23 METHOD_GET_MY_BLOCK_LIST = 24 METHOD_ADD_TO_BLOCK_LIST = 25 METHOD_REMOVE_FROM_BLOCK_LIST = 26 METHOD_CLEAR_MY_BLOCK_LIST = 27 METHOD_REPORT_VIOLATION = 28 METHOD_IS_VIOLATION_USER = 29 METHOD_JOIN_MATCHMAKE_SESSION_EX = 30 METHOD_GET_SIMPLE_PLAYING_SESSION = 31 METHOD_GET_SIMPLE_COMMUNITY = 32 METHOD_AUTO_MATCHMAKE_WITH_GATHERING_ID_POSTPONE = 33 METHOD_UPDATE_PROGRESS_SCORE = 34 METHOD_DEBUG_NOTIFY_EVENT = 35 METHOD_GENERATE_MATCHMAKE_SESSION_SYSTEM_PASSWORD = 36 METHOD_CLEAR_MATCHMAKE_SESSION_SYSTEM_PASSWORD = 37 METHOD_CREATE_MATCHMAKE_SESSION_WITH_PARAM = 38 METHOD_JOIN_MATCHMAKE_SESSION_WITH_PARAM = 39 METHOD_AUTO_MATCHMAKE_WITH_PARAM_POSTPONE = 40 METHOD_FIND_MATCHMAKE_SESSION_BY_GATHERING_ID_DETAIL = 41 METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER = 42 METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER = 43 METHOD_UPDATE_MATCHMAKE_SESSION_PART = 44 METHOD_REQUEST_MATCHMAKING = 45 METHOD_WITHDRAW_MATCHMAKING = 46 METHOD_WITHDRAW_MATCHMAKING_ALL = 47 METHOD_FIND_MATCHMAKE_SESSION_BY_GATHERING_ID = 48 METHOD_FIND_MATCHMAKE_SESSION_BY_SINGLE_GATHERING_ID = 49 METHOD_FIND_MATCHMAKE_SESSION_BY_OWNER = 50 METHOD_FIND_MATCHMAKE_SESSION_BY_PARTICIPANT = 51 METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER_NO_RESULT_RANGE = 52 METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER_NO_RESULT_RANGE = 53 METHOD_UPDATE_FRIEND_USER_PROFILE = 54 METHOD_GET_FRIEND_USER_PROFILES = 55 METHOD_GET_FRIENDS = 56 METHOD_ADD_FRIENDS = 57 METHOD_REMOVE_FRIEND = 58 METHOD_FIND_COMMUNITY_BY_OWNER = 59 PROTOCOL_ID = 0x6D class MatchMakingClient(MatchMakingProtocol): def __init__(self, client): self.settings = client.settings self.client = client async def register_gathering(self, gathering): logger.info("MatchMakingClient.register_gathering()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(gathering) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REGISTER_GATHERING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gid = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.register_gathering -> done") return gid async def unregister_gathering(self, gid): logger.info("MatchMakingClient.unregister_gathering()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UNREGISTER_GATHERING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.unregister_gathering -> done") return result async def unregister_gatherings(self, gids): logger.info("MatchMakingClient.unregister_gatherings()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UNREGISTER_GATHERINGS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.unregister_gatherings -> done") return result async def update_gathering(self, gathering): logger.info("MatchMakingClient.update_gathering()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(gathering) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_GATHERING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.update_gathering -> done") return result async def invite(self, gid, pids, message): logger.info("MatchMakingClient.invite()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(pids, stream.pid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_INVITE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.invite -> done") return result async def accept_invitation(self, gid, message): logger.info("MatchMakingClient.accept_invitation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_ACCEPT_INVITATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.accept_invitation -> done") return result async def decline_invitation(self, gid, message): logger.info("MatchMakingClient.decline_invitation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DECLINE_INVITATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.decline_invitation -> done") return result async def cancel_invitation(self, gid, pids, message): logger.info("MatchMakingClient.cancel_invitation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(pids, stream.pid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CANCEL_INVITATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.cancel_invitation -> done") return result async def get_invitations_sent(self, gid): logger.info("MatchMakingClient.get_invitations_sent()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_INVITATIONS_SENT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) invitations = stream.list(Invitation) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_invitations_sent -> done") return invitations async def get_invitations_received(self): logger.info("MatchMakingClient.get_invitations_received()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_INVITATIONS_RECEIVED, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) invitations = stream.list(Invitation) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_invitations_received -> done") return invitations async def participate(self, gid, message): logger.info("MatchMakingClient.participate()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PARTICIPATE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.participate -> done") return result async def cancel_participation(self, gid, message): logger.info("MatchMakingClient.cancel_participation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CANCEL_PARTICIPATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.cancel_participation -> done") return result async def get_participants(self, gid): logger.info("MatchMakingClient.get_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) participants = stream.list(stream.pid) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_participants -> done") return participants async def add_participants(self, gid, pids, message): logger.info("MatchMakingClient.add_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(pids, stream.pid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_ADD_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.add_participants -> done") return result async def get_detailed_participants(self, gid): logger.info("MatchMakingClient.get_detailed_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_DETAILED_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) details = stream.list(ParticipantDetails) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_detailed_participants -> done") return details async def get_participants_urls(self, gid): logger.info("MatchMakingClient.get_participants_urls()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PARTICIPANTS_URLS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) urls = stream.list(stream.stationurl) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_participants_urls -> done") return urls async def find_by_type(self, type, range): logger.info("MatchMakingClient.find_by_type()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(type) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_TYPE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_type -> done") return gatherings async def find_by_description(self, description, range): logger.info("MatchMakingClient.find_by_description()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(description) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_DESCRIPTION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_description -> done") return gatherings async def find_by_description_regex(self, regex, range): logger.info("MatchMakingClient.find_by_description_regex()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(regex) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_DESCRIPTION_REGEX, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_description_regex -> done") return gatherings async def find_by_id(self, ids): logger.info("MatchMakingClient.find_by_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(ids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_id -> done") return gatherings async def find_by_single_id(self, gid): logger.info("MatchMakingClient.find_by_single_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_SINGLE_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.gathering = stream.anydata() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_single_id -> done") return obj async def find_by_owner(self, owner, range): logger.info("MatchMakingClient.find_by_owner()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(owner) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_OWNER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_owner -> done") return gatherings async def find_by_participants(self, pids): logger.info("MatchMakingClient.find_by_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_participants -> done") return gatherings async def find_invitations(self, range): logger.info("MatchMakingClient.find_invitations()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_INVITATIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_invitations -> done") return gatherings async def find_by_sql_query(self, query, range): logger.info("MatchMakingClient.find_by_sql_query()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(query) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_SQL_QUERY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_sql_query -> done") return gatherings async def launch_session(self, gid, url): logger.info("MatchMakingClient.launch_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(url) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_LAUNCH_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.launch_session -> done") return result async def update_session_url(self, gid, url): logger.info("MatchMakingClient.update_session_url()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(url) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_SESSION_URL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.update_session_url -> done") return result async def get_session_url(self, gid): logger.info("MatchMakingClient.get_session_url()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SESSION_URL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.url = stream.string() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_session_url -> done") return obj async def get_state(self, gid): logger.info("MatchMakingClient.get_state()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.state = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_state -> done") return obj async def set_state(self, gid, state): logger.info("MatchMakingClient.set_state()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.u32(state) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SET_STATE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.set_state -> done") return result async def report_stats(self, gid, stats): logger.info("MatchMakingClient.report_stats()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(stats, stream.add) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REPORT_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.report_stats -> done") return result async def get_stats(self, gid, pids, columns): logger.info("MatchMakingClient.get_stats()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(pids, stream.pid) stream.list(columns, stream.u8) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.stats = stream.list(GatheringStats) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_stats -> done") return obj async def delete_gathering(self, gid): logger.info("MatchMakingClient.delete_gathering()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_GATHERING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.delete_gathering -> done") return result async def get_pending_deletions(self, reason, range): logger.info("MatchMakingClient.get_pending_deletions()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(reason) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PENDING_DELETIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.deletions = stream.list(DeletionEntry) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_pending_deletions -> done") return obj async def delete_from_deletions(self, deletions): logger.info("MatchMakingClient.delete_from_deletions()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(deletions, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_FROM_DELETIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.delete_from_deletions -> done") return result async def migrate_gathering_ownership_v1(self, gid, potential_owners): logger.info("MatchMakingClient.migrate_gathering_ownership_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(potential_owners, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_MIGRATE_GATHERING_OWNERSHIP_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.migrate_gathering_ownership_v1 -> done") return result async def find_by_description_like(self, description, range): logger.info("MatchMakingClient.find_by_description_like()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(description) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_DESCRIPTION_LIKE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_description_like -> done") return gatherings async def register_local_url(self, gid, url): logger.info("MatchMakingClient.register_local_url()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.stationurl(url) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REGISTER_LOCAL_URL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.register_local_url -> done") async def register_local_urls(self, gid, urls): logger.info("MatchMakingClient.register_local_urls()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(urls, stream.stationurl) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REGISTER_LOCAL_URLS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.register_local_urls -> done") async def update_session_host_v1(self, gid): logger.info("MatchMakingClient.update_session_host_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_SESSION_HOST_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.update_session_host_v1 -> done") async def get_session_urls(self, gid): logger.info("MatchMakingClient.get_session_urls()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SESSION_URLS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) urls = stream.list(stream.stationurl) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_session_urls -> done") return urls async def update_session_host(self, gid, is_migrate_owner): logger.info("MatchMakingClient.update_session_host()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.bool(is_migrate_owner) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_SESSION_HOST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.update_session_host -> done") async def update_gathering_ownership(self, gid, participants_only): logger.info("MatchMakingClient.update_gathering_ownership()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.bool(participants_only) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_GATHERING_OWNERSHIP, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.update_gathering_ownership -> done") return result async def migrate_gathering_ownership(self, gid, potential_owners, participants_only): logger.info("MatchMakingClient.migrate_gathering_ownership()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(potential_owners, stream.pid) stream.bool(participants_only) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_MIGRATE_GATHERING_OWNERSHIP, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.migrate_gathering_ownership -> done") class MatchMakingClientExt(MatchMakingProtocolExt): def __init__(self, client): self.settings = client.settings self.client = client async def end_participation(self, gid, message): logger.info("MatchMakingClientExt.end_participation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_END_PARTICIPATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.end_participation -> done") return result async def get_participants(self, gid, only_active): logger.info("MatchMakingClientExt.get_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.bool(only_active) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) participants = stream.list(stream.pid) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.get_participants -> done") return participants async def get_detailed_participants(self, gid, only_active): logger.info("MatchMakingClientExt.get_detailed_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.bool(only_active) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_DETAILED_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) details = stream.list(ParticipantDetails) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.get_detailed_participants -> done") return details async def get_participants_urls(self, gids): logger.info("MatchMakingClientExt.get_participants_urls()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PARTICIPANTS_URLS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) urls = stream.list(GatheringURLs) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.get_participants_urls -> done") return urls async def get_gathering_relations(self, id, descr): logger.info("MatchMakingClientExt.get_gathering_relations()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(id) stream.string(descr) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_GATHERING_RELATIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.string() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.get_gathering_relations -> done") return result async def delete_from_deletions(self, deletions, pid): logger.info("MatchMakingClientExt.delete_from_deletions()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(deletions, stream.u32) stream.pid(pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_FROM_DELETIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.delete_from_deletions -> done") class MatchmakeRefereeClient(MatchmakeRefereeProtocol): def __init__(self, client): self.settings = client.settings self.client = client async def start_round(self, param): logger.info("MatchmakeRefereeClient.start_round()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_START_ROUND, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) round_id = stream.u64() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.start_round -> done") return round_id async def get_start_round_param(self, round_id): logger.info("MatchmakeRefereeClient.get_start_round_param()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(round_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_START_ROUND_PARAM, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) param = stream.extract(MatchmakeRefereeStartRoundParam) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_start_round_param -> done") return param async def end_round(self, param): logger.info("MatchmakeRefereeClient.end_round()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_END_ROUND, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.end_round -> done") async def end_round_without_report(self, round_id): logger.info("MatchmakeRefereeClient.end_round_without_report()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(round_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_END_ROUND_WITHOUT_REPORT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.end_round_without_report -> done") async def get_round_participants(self, round_id): logger.info("MatchmakeRefereeClient.get_round_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(round_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_ROUND_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) pids = stream.list(stream.pid) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_round_participants -> done") return pids async def get_not_summarized_round(self): logger.info("MatchmakeRefereeClient.get_not_summarized_round()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_NOT_SUMMARIZED_ROUND, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) rounds = stream.list(MatchmakeRefereeRound) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_not_summarized_round -> done") return rounds async def get_round(self, round): logger.info("MatchmakeRefereeClient.get_round()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(round) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_ROUND, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) round = stream.extract(MatchmakeRefereeRound) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_round -> done") return round async def get_stats_primary(self, target): logger.info("MatchmakeRefereeClient.get_stats_primary()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATS_PRIMARY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) stats = stream.extract(MatchmakeRefereeStats) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_stats_primary -> done") return stats async def get_stats_primaries(self, targets): logger.info("MatchmakeRefereeClient.get_stats_primaries()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(targets, stream.add) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATS_PRIMARIES, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.stats = stream.list(MatchmakeRefereeStats) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_stats_primaries -> done") return obj async def get_stats_all(self, target): logger.info("MatchmakeRefereeClient.get_stats_all()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATS_ALL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) stats = stream.list(MatchmakeRefereeStats) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_stats_all -> done") return stats async def create_stats(self, param): logger.info("MatchmakeRefereeClient.create_stats()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CREATE_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) stats = stream.extract(MatchmakeRefereeStats) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.create_stats -> done") return stats async def get_or_create_stats(self, param): logger.info("MatchmakeRefereeClient.get_or_create_stats()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_OR_CREATE_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) stats = stream.extract(MatchmakeRefereeStats) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_or_create_stats -> done") return stats async def reset_stats(self): logger.info("MatchmakeRefereeClient.reset_stats()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RESET_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.reset_stats -> done") class MatchmakeExtensionClientMHXX(MatchmakeExtensionProtocolMHXX): def __init__(self, client): self.settings = client.settings self.client = client async def close_participation(self, gid): logger.info("MatchmakeExtensionClientMHXX.close_participation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CLOSE_PARTICIPATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.close_participation -> done") async def open_participation(self, gid): logger.info("MatchmakeExtensionClientMHXX.open_participation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_OPEN_PARTICIPATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.open_participation -> done") async def auto_matchmake_postpone(self, gathering, message): logger.info("MatchmakeExtensionClientMHXX.auto_matchmake_postpone()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(gathering) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_AUTO_MATCHMAKE_POSTPONE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gathering = stream.anydata() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.auto_matchmake_postpone -> done") return gathering async def browse_matchmake_session(self, search_criteria, range): logger.info("MatchmakeExtensionClientMHXX.browse_matchmake_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.browse_matchmake_session -> done") return gatherings async def browse_matchmake_session_with_host_urls(self, search_criteria, range): logger.info("MatchmakeExtensionClientMHXX.browse_matchmake_session_with_host_urls()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.gatherings = stream.list(stream.anydata) obj.urls = stream.list(GatheringURLs) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.browse_matchmake_session_with_host_urls -> done") return obj async def create_matchmake_session(self, gathering, description, num_participants): logger.info("MatchmakeExtensionClientMHXX.create_matchmake_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(gathering) stream.string(description) stream.u16(num_participants) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CREATE_MATCHMAKE_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.gid = stream.u32() obj.session_key = stream.buffer() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.create_matchmake_session -> done") return obj async def join_matchmake_session(self, gid, message): logger.info("MatchmakeExtensionClientMHXX.join_matchmake_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_JOIN_MATCHMAKE_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session_key = stream.buffer() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.join_matchmake_session -> done") return session_key async def modify_current_game_attribute(self, gid, attrib, value): logger.info("MatchmakeExtensionClientMHXX.modify_current_game_attribute()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.u32(attrib) stream.u32(value) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_MODIFY_CURRENT_GAME_ATTRIBUTE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.modify_current_game_attribute -> done") async def update_notification_data(self, type, param1, param2, param3): logger.info("MatchmakeExtensionClientMHXX.update_notification_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(type) stream.pid(param1) stream.pid(param2) stream.string(param3) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_NOTIFICATION_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.update_notification_data -> done") async def get_friend_notification_data(self, type): logger.info("MatchmakeExtensionClientMHXX.get_friend_notification_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.s32(type) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_FRIEND_NOTIFICATION_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) notifications = stream.list(notification.NotificationEvent) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.get_friend_notification_data -> done") return notifications async def update_application_buffer(self, gid, buffer): logger.info("MatchmakeExtensionClientMHXX.update_application_buffer()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.buffer(buffer) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_APPLICATION_BUFFER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.update_application_buffer -> done") async def update_matchmake_session_attribute(self, gid, attribs): logger.info("MatchmakeExtensionClientMHXX.update_matchmake_session_attribute()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(attribs, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_MATCHMAKE_SESSION_ATTRIBUTE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.update_matchmake_session_attribute -> done") async def get_friend_notification_data_list(self, types): logger.info("MatchmakeExtensionClientMHXX.get_friend_notification_data_list()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(types, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_FRIEND_NOTIFICATION_DATA_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) notifications = stream.list(notification.NotificationEvent) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.get_friend_notification_data_list -> done") return notifications async def update_matchmake_session(self, gathering): logger.info("MatchmakeExtensionClientMHXX.update_matchmake_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(gathering) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_MATCHMAKE_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.update_matchmake_session -> done") async def auto_matchmake_with_search_criteria_postpone(self, search_criteria, gathering, message): logger.info("MatchmakeExtensionClientMHXX.auto_matchmake_with_search_criteria_postpone()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(search_criteria, stream.add) stream.anydata(gathering) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_AUTO_MATCHMAKE_WITH_SEARCH_CRITERIA_POSTPONE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gathering = stream.anydata() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.auto_matchmake_with_search_criteria_postpone -> done") return gathering async def get_playing_session(self, pids): logger.info("MatchmakeExtensionClientMHXX.get_playing_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PLAYING_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) sessions = stream.list(PlayingSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.get_playing_session -> done") return sessions async def create_community(self, community, message): logger.info("MatchmakeExtensionClientMHXX.create_community()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(community) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CREATE_COMMUNITY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gid = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.create_community -> done") return gid async def update_community(self, community): logger.info("MatchmakeExtensionClientMHXX.update_community()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(community) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_COMMUNITY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.update_community -> done") async def join_community(self, gid, message, password): logger.info("MatchmakeExtensionClientMHXX.join_community()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) stream.string(password) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_JOIN_COMMUNITY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.join_community -> done") async def find_community_by_gathering_id(self, gids): logger.info("MatchmakeExtensionClientMHXX.find_community_by_gathering_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_COMMUNITY_BY_GATHERING_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) communities = stream.list(PersistentGathering) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.find_community_by_gathering_id -> done") return communities async def find_official_community(self, available_only, range): logger.info("MatchmakeExtensionClientMHXX.find_official_community()") #--- request --- stream = streams.StreamOut(self.settings) stream.bool(available_only) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_OFFICIAL_COMMUNITY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) communities = stream.list(PersistentGathering) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.find_official_community -> done") return communities async def find_community_by_participant(self, pid, range): logger.info("MatchmakeExtensionClientMHXX.find_community_by_participant()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_COMMUNITY_BY_PARTICIPANT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) communities = stream.list(PersistentGathering) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.find_community_by_participant -> done") return communities async def update_privacy_setting(self, online_status, community_participation): logger.info("MatchmakeExtensionClientMHXX.update_privacy_setting()") #--- request --- stream = streams.StreamOut(self.settings) stream.bool(online_status) stream.bool(community_participation) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_PRIVACY_SETTING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.update_privacy_setting -> done") async def get_my_block_list(self): logger.info("MatchmakeExtensionClientMHXX.get_my_block_list()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_MY_BLOCK_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) pids = stream.list(stream.pid) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.get_my_block_list -> done") return pids async def add_to_block_list(self, pids): logger.info("MatchmakeExtensionClientMHXX.add_to_block_list()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_ADD_TO_BLOCK_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.add_to_block_list -> done") async def remove_from_block_list(self, pids): logger.info("MatchmakeExtensionClientMHXX.remove_from_block_list()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REMOVE_FROM_BLOCK_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.remove_from_block_list -> done") async def clear_my_block_list(self): logger.info("MatchmakeExtensionClientMHXX.clear_my_block_list()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CLEAR_MY_BLOCK_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.clear_my_block_list -> done") async def report_violation(self, pid, username, violation_code): logger.info("MatchmakeExtensionClientMHXX.report_violation()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) stream.string(username) stream.u32(violation_code) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REPORT_VIOLATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.report_violation -> done") async def is_violation_user(self): logger.info("MatchmakeExtensionClientMHXX.is_violation_user()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_IS_VIOLATION_USER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.flag = stream.bool() obj.score = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.is_violation_user -> done") return obj async def join_matchmake_session_ex(self, gid, gmessage, ignore_block_list, num_participants): logger.info("MatchmakeExtensionClientMHXX.join_matchmake_session_ex()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(gmessage) stream.bool(ignore_block_list) stream.u16(num_participants) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_JOIN_MATCHMAKE_SESSION_EX, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session_key = stream.buffer() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.join_matchmake_session_ex -> done") return session_key async def get_simple_playing_session(self, pids, include_login_user): logger.info("MatchmakeExtensionClientMHXX.get_simple_playing_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) stream.bool(include_login_user) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SIMPLE_PLAYING_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session = stream.list(SimplePlayingSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.get_simple_playing_session -> done") return session async def get_simple_community(self, gids): logger.info("MatchmakeExtensionClientMHXX.get_simple_community()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SIMPLE_COMMUNITY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) communities = stream.list(SimpleCommunity) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.get_simple_community -> done") return communities async def auto_matchmake_with_gathering_id_postpone(self, gids, gathering, message): logger.info("MatchmakeExtensionClientMHXX.auto_matchmake_with_gathering_id_postpone()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) stream.anydata(gathering) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_AUTO_MATCHMAKE_WITH_GATHERING_ID_POSTPONE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) joined_gathering = stream.anydata() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.auto_matchmake_with_gathering_id_postpone -> done") return joined_gathering async def update_progress_score(self, gid, score): logger.info("MatchmakeExtensionClientMHXX.update_progress_score()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.u8(score) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_PROGRESS_SCORE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.update_progress_score -> done") async def debug_notify_event(self, pid, main_type, sub_type, param1, param2, param3): logger.info("MatchmakeExtensionClientMHXX.debug_notify_event()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) stream.u32(main_type) stream.u32(sub_type) stream.u64(param1) stream.u64(param2) stream.string(param3) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DEBUG_NOTIFY_EVENT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.debug_notify_event -> done") async def generate_matchmake_session_system_password(self, gid): logger.info("MatchmakeExtensionClientMHXX.generate_matchmake_session_system_password()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GENERATE_MATCHMAKE_SESSION_SYSTEM_PASSWORD, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) password = stream.string() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.generate_matchmake_session_system_password -> done") return password async def clear_matchmake_session_system_password(self, gid): logger.info("MatchmakeExtensionClientMHXX.clear_matchmake_session_system_password()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CLEAR_MATCHMAKE_SESSION_SYSTEM_PASSWORD, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.clear_matchmake_session_system_password -> done") async def create_matchmake_session_with_param(self, param): logger.info("MatchmakeExtensionClientMHXX.create_matchmake_session_with_param()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CREATE_MATCHMAKE_SESSION_WITH_PARAM, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session = stream.extract(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.create_matchmake_session_with_param -> done") return session async def join_matchmake_session_with_param(self, param): logger.info("MatchmakeExtensionClientMHXX.join_matchmake_session_with_param()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_JOIN_MATCHMAKE_SESSION_WITH_PARAM, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session = stream.extract(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.join_matchmake_session_with_param -> done") return session async def auto_matchmake_with_param_postpone(self, param): logger.info("MatchmakeExtensionClientMHXX.auto_matchmake_with_param_postpone()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_AUTO_MATCHMAKE_WITH_PARAM_POSTPONE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session = stream.extract(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.auto_matchmake_with_param_postpone -> done") return session async def find_matchmake_session_by_gathering_id_detail(self, gid): logger.info("MatchmakeExtensionClientMHXX.find_matchmake_session_by_gathering_id_detail()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_MATCHMAKE_SESSION_BY_GATHERING_ID_DETAIL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session = stream.extract(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.find_matchmake_session_by_gathering_id_detail -> done") return session async def browse_matchmake_session_no_holder(self, search_criteria, range): logger.info("MatchmakeExtensionClientMHXX.browse_matchmake_session_no_holder()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) sessions = stream.list(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.browse_matchmake_session_no_holder -> done") return sessions async def browse_matchmake_session_with_host_urls_no_holder(self, search_criteria, range): logger.info("MatchmakeExtensionClientMHXX.browse_matchmake_session_with_host_urls_no_holder()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.sessions = stream.list(MatchmakeSession) obj.urls = stream.list(GatheringURLs) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.browse_matchmake_session_with_host_urls_no_holder -> done") return obj async def update_matchmake_session_part(self, param): logger.info("MatchmakeExtensionClientMHXX.update_matchmake_session_part()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_MATCHMAKE_SESSION_PART, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.update_matchmake_session_part -> done") async def request_matchmaking(self, param): logger.info("MatchmakeExtensionClientMHXX.request_matchmaking()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REQUEST_MATCHMAKING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) request_id = stream.u64() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.request_matchmaking -> done") return request_id async def withdraw_matchmaking(self, request_id): logger.info("MatchmakeExtensionClientMHXX.withdraw_matchmaking()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(request_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_WITHDRAW_MATCHMAKING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.withdraw_matchmaking -> done") async def withdraw_matchmaking_all(self): logger.info("MatchmakeExtensionClientMHXX.withdraw_matchmaking_all()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_WITHDRAW_MATCHMAKING_ALL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.withdraw_matchmaking_all -> done") async def find_matchmake_session_by_gathering_id(self, gids): logger.info("MatchmakeExtensionClientMHXX.find_matchmake_session_by_gathering_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_MATCHMAKE_SESSION_BY_GATHERING_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) sessions = stream.list(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.find_matchmake_session_by_gathering_id -> done") return sessions async def find_matchmake_session_by_single_gathering_id(self, gid): logger.info("MatchmakeExtensionClientMHXX.find_matchmake_session_by_single_gathering_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_MATCHMAKE_SESSION_BY_SINGLE_GATHERING_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session = stream.extract(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.find_matchmake_session_by_single_gathering_id -> done") return session async def find_matchmake_session_by_owner(self, pid, range): logger.info("MatchmakeExtensionClientMHXX.find_matchmake_session_by_owner()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_MATCHMAKE_SESSION_BY_OWNER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) sessions = stream.list(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.find_matchmake_session_by_owner -> done") return sessions async def find_matchmake_session_by_participant(self, param): logger.info("MatchmakeExtensionClientMHXX.find_matchmake_session_by_participant()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_MATCHMAKE_SESSION_BY_PARTICIPANT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.list(FindMatchmakeSessionByParticipantResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.find_matchmake_session_by_participant -> done") return result async def browse_matchmake_session_no_holder_no_result_range(self, search_criteria): logger.info("MatchmakeExtensionClientMHXX.browse_matchmake_session_no_holder_no_result_range()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER_NO_RESULT_RANGE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) sessions = stream.list(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.browse_matchmake_session_no_holder_no_result_range -> done") return sessions async def browse_matchmake_session_with_host_urls_no_holder_no_result_range(self, search_criteria): logger.info("MatchmakeExtensionClientMHXX.browse_matchmake_session_with_host_urls_no_holder_no_result_range()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER_NO_RESULT_RANGE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.sessions = stream.list(MatchmakeSession) obj.urls = stream.list(GatheringURLs) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.browse_matchmake_session_with_host_urls_no_holder_no_result_range -> done") return obj async def update_friend_user_profile(self, param): logger.info("MatchmakeExtensionClientMHXX.update_friend_user_profile()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_FRIEND_USER_PROFILE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.update_friend_user_profile -> done") async def get_friend_user_profiles(self, pids): logger.info("MatchmakeExtensionClientMHXX.get_friend_user_profiles()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.u64) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_FRIEND_USER_PROFILES, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) infos = stream.list(FriendUserInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.get_friend_user_profiles -> done") return infos async def get_friends(self): logger.info("MatchmakeExtensionClientMHXX.get_friends()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_FRIENDS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) infos = stream.list(FriendUserInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.get_friends -> done") return infos async def add_friends(self, pids): logger.info("MatchmakeExtensionClientMHXX.add_friends()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.u64) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_ADD_FRIENDS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.add_friends -> done") async def remove_friend(self, pid): logger.info("MatchmakeExtensionClientMHXX.remove_friend()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REMOVE_FRIEND, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.remove_friend -> done") async def find_community_by_owner(self, id, range): logger.info("MatchmakeExtensionClientMHXX.find_community_by_owner()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(id) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_COMMUNITY_BY_OWNER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) lst_community = stream.list(PersistentGathering) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMHXX.find_community_by_owner -> done") return lst_community class MatchMakingServer(MatchMakingProtocol): def __init__(self): self.methods = { self.METHOD_REGISTER_GATHERING: self.handle_register_gathering, self.METHOD_UNREGISTER_GATHERING: self.handle_unregister_gathering, self.METHOD_UNREGISTER_GATHERINGS: self.handle_unregister_gatherings, self.METHOD_UPDATE_GATHERING: self.handle_update_gathering, self.METHOD_INVITE: self.handle_invite, self.METHOD_ACCEPT_INVITATION: self.handle_accept_invitation, self.METHOD_DECLINE_INVITATION: self.handle_decline_invitation, self.METHOD_CANCEL_INVITATION: self.handle_cancel_invitation, self.METHOD_GET_INVITATIONS_SENT: self.handle_get_invitations_sent, self.METHOD_GET_INVITATIONS_RECEIVED: self.handle_get_invitations_received, self.METHOD_PARTICIPATE: self.handle_participate, self.METHOD_CANCEL_PARTICIPATION: self.handle_cancel_participation, self.METHOD_GET_PARTICIPANTS: self.handle_get_participants, self.METHOD_ADD_PARTICIPANTS: self.handle_add_participants, self.METHOD_GET_DETAILED_PARTICIPANTS: self.handle_get_detailed_participants, self.METHOD_GET_PARTICIPANTS_URLS: self.handle_get_participants_urls, self.METHOD_FIND_BY_TYPE: self.handle_find_by_type, self.METHOD_FIND_BY_DESCRIPTION: self.handle_find_by_description, self.METHOD_FIND_BY_DESCRIPTION_REGEX: self.handle_find_by_description_regex, self.METHOD_FIND_BY_ID: self.handle_find_by_id, self.METHOD_FIND_BY_SINGLE_ID: self.handle_find_by_single_id, self.METHOD_FIND_BY_OWNER: self.handle_find_by_owner, self.METHOD_FIND_BY_PARTICIPANTS: self.handle_find_by_participants, self.METHOD_FIND_INVITATIONS: self.handle_find_invitations, self.METHOD_FIND_BY_SQL_QUERY: self.handle_find_by_sql_query, self.METHOD_LAUNCH_SESSION: self.handle_launch_session, self.METHOD_UPDATE_SESSION_URL: self.handle_update_session_url, self.METHOD_GET_SESSION_URL: self.handle_get_session_url, self.METHOD_GET_STATE: self.handle_get_state, self.METHOD_SET_STATE: self.handle_set_state, self.METHOD_REPORT_STATS: self.handle_report_stats, self.METHOD_GET_STATS: self.handle_get_stats, self.METHOD_DELETE_GATHERING: self.handle_delete_gathering, self.METHOD_GET_PENDING_DELETIONS: self.handle_get_pending_deletions, self.METHOD_DELETE_FROM_DELETIONS: self.handle_delete_from_deletions, self.METHOD_MIGRATE_GATHERING_OWNERSHIP_V1: self.handle_migrate_gathering_ownership_v1, self.METHOD_FIND_BY_DESCRIPTION_LIKE: self.handle_find_by_description_like, self.METHOD_REGISTER_LOCAL_URL: self.handle_register_local_url, self.METHOD_REGISTER_LOCAL_URLS: self.handle_register_local_urls, self.METHOD_UPDATE_SESSION_HOST_V1: self.handle_update_session_host_v1, self.METHOD_GET_SESSION_URLS: self.handle_get_session_urls, self.METHOD_UPDATE_SESSION_HOST: self.handle_update_session_host, self.METHOD_UPDATE_GATHERING_OWNERSHIP: self.handle_update_gathering_ownership, self.METHOD_MIGRATE_GATHERING_OWNERSHIP: self.handle_migrate_gathering_ownership, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on MatchMakingServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_register_gathering(self, client, input, output): logger.info("MatchMakingServer.register_gathering()") #--- request --- gathering = input.anydata() response = await self.register_gathering(client, gathering) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u32(response) async def handle_unregister_gathering(self, client, input, output): logger.info("MatchMakingServer.unregister_gathering()") #--- request --- gid = input.u32() response = await self.unregister_gathering(client, gid) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_unregister_gatherings(self, client, input, output): logger.info("MatchMakingServer.unregister_gatherings()") #--- request --- gids = input.list(input.u32) response = await self.unregister_gatherings(client, gids) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_update_gathering(self, client, input, output): logger.info("MatchMakingServer.update_gathering()") #--- request --- gathering = input.anydata() response = await self.update_gathering(client, gathering) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_invite(self, client, input, output): logger.info("MatchMakingServer.invite()") #--- request --- gid = input.u32() pids = input.list(input.pid) message = input.string() response = await self.invite(client, gid, pids, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_accept_invitation(self, client, input, output): logger.info("MatchMakingServer.accept_invitation()") #--- request --- gid = input.u32() message = input.string() response = await self.accept_invitation(client, gid, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_decline_invitation(self, client, input, output): logger.info("MatchMakingServer.decline_invitation()") #--- request --- gid = input.u32() message = input.string() response = await self.decline_invitation(client, gid, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_cancel_invitation(self, client, input, output): logger.info("MatchMakingServer.cancel_invitation()") #--- request --- gid = input.u32() pids = input.list(input.pid) message = input.string() response = await self.cancel_invitation(client, gid, pids, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_invitations_sent(self, client, input, output): logger.info("MatchMakingServer.get_invitations_sent()") #--- request --- gid = input.u32() response = await self.get_invitations_sent(client, gid) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_invitations_received(self, client, input, output): logger.info("MatchMakingServer.get_invitations_received()") #--- request --- response = await self.get_invitations_received(client) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_participate(self, client, input, output): logger.info("MatchMakingServer.participate()") #--- request --- gid = input.u32() message = input.string() response = await self.participate(client, gid, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_cancel_participation(self, client, input, output): logger.info("MatchMakingServer.cancel_participation()") #--- request --- gid = input.u32() message = input.string() response = await self.cancel_participation(client, gid, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_participants(self, client, input, output): logger.info("MatchMakingServer.get_participants()") #--- request --- gid = input.u32() response = await self.get_participants(client, gid) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.pid) async def handle_add_participants(self, client, input, output): logger.info("MatchMakingServer.add_participants()") #--- request --- gid = input.u32() pids = input.list(input.pid) message = input.string() response = await self.add_participants(client, gid, pids, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_detailed_participants(self, client, input, output): logger.info("MatchMakingServer.get_detailed_participants()") #--- request --- gid = input.u32() response = await self.get_detailed_participants(client, gid) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_participants_urls(self, client, input, output): logger.info("MatchMakingServer.get_participants_urls()") #--- request --- gid = input.u32() response = await self.get_participants_urls(client, gid) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.stationurl) async def handle_find_by_type(self, client, input, output): logger.info("MatchMakingServer.find_by_type()") #--- request --- type = input.string() range = input.extract(common.ResultRange) response = await self.find_by_type(client, type, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_description(self, client, input, output): logger.info("MatchMakingServer.find_by_description()") #--- request --- description = input.string() range = input.extract(common.ResultRange) response = await self.find_by_description(client, description, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_description_regex(self, client, input, output): logger.info("MatchMakingServer.find_by_description_regex()") #--- request --- regex = input.string() range = input.extract(common.ResultRange) response = await self.find_by_description_regex(client, regex, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_id(self, client, input, output): logger.info("MatchMakingServer.find_by_id()") #--- request --- ids = input.list(input.u32) response = await self.find_by_id(client, ids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_single_id(self, client, input, output): logger.info("MatchMakingServer.find_by_single_id()") #--- request --- gid = input.u32() response = await self.find_by_single_id(client, gid) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'gathering']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.anydata(response.gathering) async def handle_find_by_owner(self, client, input, output): logger.info("MatchMakingServer.find_by_owner()") #--- request --- owner = input.pid() range = input.extract(common.ResultRange) response = await self.find_by_owner(client, owner, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_participants(self, client, input, output): logger.info("MatchMakingServer.find_by_participants()") #--- request --- pids = input.list(input.pid) response = await self.find_by_participants(client, pids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_invitations(self, client, input, output): logger.info("MatchMakingServer.find_invitations()") #--- request --- range = input.extract(common.ResultRange) response = await self.find_invitations(client, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_sql_query(self, client, input, output): logger.info("MatchMakingServer.find_by_sql_query()") #--- request --- query = input.string() range = input.extract(common.ResultRange) response = await self.find_by_sql_query(client, query, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_launch_session(self, client, input, output): logger.info("MatchMakingServer.launch_session()") #--- request --- gid = input.u32() url = input.string() response = await self.launch_session(client, gid, url) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_update_session_url(self, client, input, output): logger.info("MatchMakingServer.update_session_url()") #--- request --- gid = input.u32() url = input.string() response = await self.update_session_url(client, gid, url) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_session_url(self, client, input, output): logger.info("MatchMakingServer.get_session_url()") #--- request --- gid = input.u32() response = await self.get_session_url(client, gid) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'url']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.string(response.url) async def handle_get_state(self, client, input, output): logger.info("MatchMakingServer.get_state()") #--- request --- gid = input.u32() response = await self.get_state(client, gid) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'state']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.u32(response.state) async def handle_set_state(self, client, input, output): logger.info("MatchMakingServer.set_state()") #--- request --- gid = input.u32() state = input.u32() response = await self.set_state(client, gid, state) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_report_stats(self, client, input, output): logger.info("MatchMakingServer.report_stats()") #--- request --- gid = input.u32() stats = input.list(GatheringStats) response = await self.report_stats(client, gid, stats) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_stats(self, client, input, output): logger.info("MatchMakingServer.get_stats()") #--- request --- gid = input.u32() pids = input.list(input.pid) columns = input.list(input.u8) response = await self.get_stats(client, gid, pids, columns) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'stats']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.list(response.stats, output.add) async def handle_delete_gathering(self, client, input, output): logger.info("MatchMakingServer.delete_gathering()") #--- request --- gid = input.u32() response = await self.delete_gathering(client, gid) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_pending_deletions(self, client, input, output): logger.info("MatchMakingServer.get_pending_deletions()") #--- request --- reason = input.u32() range = input.extract(common.ResultRange) response = await self.get_pending_deletions(client, reason, range) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'deletions']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.list(response.deletions, output.add) async def handle_delete_from_deletions(self, client, input, output): logger.info("MatchMakingServer.delete_from_deletions()") #--- request --- deletions = input.list(input.u32) response = await self.delete_from_deletions(client, deletions) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_migrate_gathering_ownership_v1(self, client, input, output): logger.info("MatchMakingServer.migrate_gathering_ownership_v1()") #--- request --- gid = input.u32() potential_owners = input.list(input.pid) response = await self.migrate_gathering_ownership_v1(client, gid, potential_owners) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_find_by_description_like(self, client, input, output): logger.info("MatchMakingServer.find_by_description_like()") #--- request --- description = input.string() range = input.extract(common.ResultRange) response = await self.find_by_description_like(client, description, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_register_local_url(self, client, input, output): logger.info("MatchMakingServer.register_local_url()") #--- request --- gid = input.u32() url = input.stationurl() await self.register_local_url(client, gid, url) async def handle_register_local_urls(self, client, input, output): logger.info("MatchMakingServer.register_local_urls()") #--- request --- gid = input.u32() urls = input.list(input.stationurl) await self.register_local_urls(client, gid, urls) async def handle_update_session_host_v1(self, client, input, output): logger.info("MatchMakingServer.update_session_host_v1()") #--- request --- gid = input.u32() await self.update_session_host_v1(client, gid) async def handle_get_session_urls(self, client, input, output): logger.info("MatchMakingServer.get_session_urls()") #--- request --- gid = input.u32() response = await self.get_session_urls(client, gid) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.stationurl) async def handle_update_session_host(self, client, input, output): logger.info("MatchMakingServer.update_session_host()") #--- request --- gid = input.u32() is_migrate_owner = input.bool() await self.update_session_host(client, gid, is_migrate_owner) async def handle_update_gathering_ownership(self, client, input, output): logger.info("MatchMakingServer.update_gathering_ownership()") #--- request --- gid = input.u32() participants_only = input.bool() response = await self.update_gathering_ownership(client, gid, participants_only) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_migrate_gathering_ownership(self, client, input, output): logger.info("MatchMakingServer.migrate_gathering_ownership()") #--- request --- gid = input.u32() potential_owners = input.list(input.pid) participants_only = input.bool() await self.migrate_gathering_ownership(client, gid, potential_owners, participants_only) async def register_gathering(self, *args): logger.warning("MatchMakingServer.register_gathering not implemented") raise common.RMCError("Core::NotImplemented") async def unregister_gathering(self, *args): logger.warning("MatchMakingServer.unregister_gathering not implemented") raise common.RMCError("Core::NotImplemented") async def unregister_gatherings(self, *args): logger.warning("MatchMakingServer.unregister_gatherings not implemented") raise common.RMCError("Core::NotImplemented") async def update_gathering(self, *args): logger.warning("MatchMakingServer.update_gathering not implemented") raise common.RMCError("Core::NotImplemented") async def invite(self, *args): logger.warning("MatchMakingServer.invite not implemented") raise common.RMCError("Core::NotImplemented") async def accept_invitation(self, *args): logger.warning("MatchMakingServer.accept_invitation not implemented") raise common.RMCError("Core::NotImplemented") async def decline_invitation(self, *args): logger.warning("MatchMakingServer.decline_invitation not implemented") raise common.RMCError("Core::NotImplemented") async def cancel_invitation(self, *args): logger.warning("MatchMakingServer.cancel_invitation not implemented") raise common.RMCError("Core::NotImplemented") async def get_invitations_sent(self, *args): logger.warning("MatchMakingServer.get_invitations_sent not implemented") raise common.RMCError("Core::NotImplemented") async def get_invitations_received(self, *args): logger.warning("MatchMakingServer.get_invitations_received not implemented") raise common.RMCError("Core::NotImplemented") async def participate(self, *args): logger.warning("MatchMakingServer.participate not implemented") raise common.RMCError("Core::NotImplemented") async def cancel_participation(self, *args): logger.warning("MatchMakingServer.cancel_participation not implemented") raise common.RMCError("Core::NotImplemented") async def get_participants(self, *args): logger.warning("MatchMakingServer.get_participants not implemented") raise common.RMCError("Core::NotImplemented") async def add_participants(self, *args): logger.warning("MatchMakingServer.add_participants not implemented") raise common.RMCError("Core::NotImplemented") async def get_detailed_participants(self, *args): logger.warning("MatchMakingServer.get_detailed_participants not implemented") raise common.RMCError("Core::NotImplemented") async def get_participants_urls(self, *args): logger.warning("MatchMakingServer.get_participants_urls not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_type(self, *args): logger.warning("MatchMakingServer.find_by_type not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_description(self, *args): logger.warning("MatchMakingServer.find_by_description not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_description_regex(self, *args): logger.warning("MatchMakingServer.find_by_description_regex not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_id(self, *args): logger.warning("MatchMakingServer.find_by_id not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_single_id(self, *args): logger.warning("MatchMakingServer.find_by_single_id not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_owner(self, *args): logger.warning("MatchMakingServer.find_by_owner not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_participants(self, *args): logger.warning("MatchMakingServer.find_by_participants not implemented") raise common.RMCError("Core::NotImplemented") async def find_invitations(self, *args): logger.warning("MatchMakingServer.find_invitations not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_sql_query(self, *args): logger.warning("MatchMakingServer.find_by_sql_query not implemented") raise common.RMCError("Core::NotImplemented") async def launch_session(self, *args): logger.warning("MatchMakingServer.launch_session not implemented") raise common.RMCError("Core::NotImplemented") async def update_session_url(self, *args): logger.warning("MatchMakingServer.update_session_url not implemented") raise common.RMCError("Core::NotImplemented") async def get_session_url(self, *args): logger.warning("MatchMakingServer.get_session_url not implemented") raise common.RMCError("Core::NotImplemented") async def get_state(self, *args): logger.warning("MatchMakingServer.get_state not implemented") raise common.RMCError("Core::NotImplemented") async def set_state(self, *args): logger.warning("MatchMakingServer.set_state not implemented") raise common.RMCError("Core::NotImplemented") async def report_stats(self, *args): logger.warning("MatchMakingServer.report_stats not implemented") raise common.RMCError("Core::NotImplemented") async def get_stats(self, *args): logger.warning("MatchMakingServer.get_stats not implemented") raise common.RMCError("Core::NotImplemented") async def delete_gathering(self, *args): logger.warning("MatchMakingServer.delete_gathering not implemented") raise common.RMCError("Core::NotImplemented") async def get_pending_deletions(self, *args): logger.warning("MatchMakingServer.get_pending_deletions not implemented") raise common.RMCError("Core::NotImplemented") async def delete_from_deletions(self, *args): logger.warning("MatchMakingServer.delete_from_deletions not implemented") raise common.RMCError("Core::NotImplemented") async def migrate_gathering_ownership_v1(self, *args): logger.warning("MatchMakingServer.migrate_gathering_ownership_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_description_like(self, *args): logger.warning("MatchMakingServer.find_by_description_like not implemented") raise common.RMCError("Core::NotImplemented") async def register_local_url(self, *args): logger.warning("MatchMakingServer.register_local_url not implemented") raise common.RMCError("Core::NotImplemented") async def register_local_urls(self, *args): logger.warning("MatchMakingServer.register_local_urls not implemented") raise common.RMCError("Core::NotImplemented") async def update_session_host_v1(self, *args): logger.warning("MatchMakingServer.update_session_host_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def get_session_urls(self, *args): logger.warning("MatchMakingServer.get_session_urls not implemented") raise common.RMCError("Core::NotImplemented") async def update_session_host(self, *args): logger.warning("MatchMakingServer.update_session_host not implemented") raise common.RMCError("Core::NotImplemented") async def update_gathering_ownership(self, *args): logger.warning("MatchMakingServer.update_gathering_ownership not implemented") raise common.RMCError("Core::NotImplemented") async def migrate_gathering_ownership(self, *args): logger.warning("MatchMakingServer.migrate_gathering_ownership not implemented") raise common.RMCError("Core::NotImplemented") class MatchMakingServerExt(MatchMakingProtocolExt): def __init__(self): self.methods = { self.METHOD_END_PARTICIPATION: self.handle_end_participation, self.METHOD_GET_PARTICIPANTS: self.handle_get_participants, self.METHOD_GET_DETAILED_PARTICIPANTS: self.handle_get_detailed_participants, self.METHOD_GET_PARTICIPANTS_URLS: self.handle_get_participants_urls, self.METHOD_GET_GATHERING_RELATIONS: self.handle_get_gathering_relations, self.METHOD_DELETE_FROM_DELETIONS: self.handle_delete_from_deletions, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on MatchMakingServerExt: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_end_participation(self, client, input, output): logger.info("MatchMakingServerExt.end_participation()") #--- request --- gid = input.u32() message = input.string() response = await self.end_participation(client, gid, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_participants(self, client, input, output): logger.info("MatchMakingServerExt.get_participants()") #--- request --- gid = input.u32() only_active = input.bool() response = await self.get_participants(client, gid, only_active) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.pid) async def handle_get_detailed_participants(self, client, input, output): logger.info("MatchMakingServerExt.get_detailed_participants()") #--- request --- gid = input.u32() only_active = input.bool() response = await self.get_detailed_participants(client, gid, only_active) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_participants_urls(self, client, input, output): logger.info("MatchMakingServerExt.get_participants_urls()") #--- request --- gids = input.list(input.u32) response = await self.get_participants_urls(client, gids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_gathering_relations(self, client, input, output): logger.info("MatchMakingServerExt.get_gathering_relations()") #--- request --- id = input.u32() descr = input.string() response = await self.get_gathering_relations(client, id, descr) #--- response --- if not isinstance(response, str): raise RuntimeError("Expected str, got %s" %response.__class__.__name__) output.string(response) async def handle_delete_from_deletions(self, client, input, output): logger.info("MatchMakingServerExt.delete_from_deletions()") #--- request --- deletions = input.list(input.u32) pid = input.pid() await self.delete_from_deletions(client, deletions, pid) async def end_participation(self, *args): logger.warning("MatchMakingServerExt.end_participation not implemented") raise common.RMCError("Core::NotImplemented") async def get_participants(self, *args): logger.warning("MatchMakingServerExt.get_participants not implemented") raise common.RMCError("Core::NotImplemented") async def get_detailed_participants(self, *args): logger.warning("MatchMakingServerExt.get_detailed_participants not implemented") raise common.RMCError("Core::NotImplemented") async def get_participants_urls(self, *args): logger.warning("MatchMakingServerExt.get_participants_urls not implemented") raise common.RMCError("Core::NotImplemented") async def get_gathering_relations(self, *args): logger.warning("MatchMakingServerExt.get_gathering_relations not implemented") raise common.RMCError("Core::NotImplemented") async def delete_from_deletions(self, *args): logger.warning("MatchMakingServerExt.delete_from_deletions not implemented") raise common.RMCError("Core::NotImplemented") class MatchmakeRefereeServer(MatchmakeRefereeProtocol): def __init__(self): self.methods = { self.METHOD_START_ROUND: self.handle_start_round, self.METHOD_GET_START_ROUND_PARAM: self.handle_get_start_round_param, self.METHOD_END_ROUND: self.handle_end_round, self.METHOD_END_ROUND_WITHOUT_REPORT: self.handle_end_round_without_report, self.METHOD_GET_ROUND_PARTICIPANTS: self.handle_get_round_participants, self.METHOD_GET_NOT_SUMMARIZED_ROUND: self.handle_get_not_summarized_round, self.METHOD_GET_ROUND: self.handle_get_round, self.METHOD_GET_STATS_PRIMARY: self.handle_get_stats_primary, self.METHOD_GET_STATS_PRIMARIES: self.handle_get_stats_primaries, self.METHOD_GET_STATS_ALL: self.handle_get_stats_all, self.METHOD_CREATE_STATS: self.handle_create_stats, self.METHOD_GET_OR_CREATE_STATS: self.handle_get_or_create_stats, self.METHOD_RESET_STATS: self.handle_reset_stats, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on MatchmakeRefereeServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_start_round(self, client, input, output): logger.info("MatchmakeRefereeServer.start_round()") #--- request --- param = input.extract(MatchmakeRefereeStartRoundParam) response = await self.start_round(client, param) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u64(response) async def handle_get_start_round_param(self, client, input, output): logger.info("MatchmakeRefereeServer.get_start_round_param()") #--- request --- round_id = input.u64() response = await self.get_start_round_param(client, round_id) #--- response --- if not isinstance(response, MatchmakeRefereeStartRoundParam): raise RuntimeError("Expected MatchmakeRefereeStartRoundParam, got %s" %response.__class__.__name__) output.add(response) async def handle_end_round(self, client, input, output): logger.info("MatchmakeRefereeServer.end_round()") #--- request --- param = input.extract(MatchmakeRefereeEndRoundParam) await self.end_round(client, param) async def handle_end_round_without_report(self, client, input, output): logger.info("MatchmakeRefereeServer.end_round_without_report()") #--- request --- round_id = input.u64() await self.end_round_without_report(client, round_id) async def handle_get_round_participants(self, client, input, output): logger.info("MatchmakeRefereeServer.get_round_participants()") #--- request --- round_id = input.u64() response = await self.get_round_participants(client, round_id) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.pid) async def handle_get_not_summarized_round(self, client, input, output): logger.info("MatchmakeRefereeServer.get_not_summarized_round()") #--- request --- response = await self.get_not_summarized_round(client) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_round(self, client, input, output): logger.info("MatchmakeRefereeServer.get_round()") #--- request --- round = input.u64() response = await self.get_round(client, round) #--- response --- if not isinstance(response, MatchmakeRefereeRound): raise RuntimeError("Expected MatchmakeRefereeRound, got %s" %response.__class__.__name__) output.add(response) async def handle_get_stats_primary(self, client, input, output): logger.info("MatchmakeRefereeServer.get_stats_primary()") #--- request --- target = input.extract(MatchmakeRefereeStatsTarget) response = await self.get_stats_primary(client, target) #--- response --- if not isinstance(response, MatchmakeRefereeStats): raise RuntimeError("Expected MatchmakeRefereeStats, got %s" %response.__class__.__name__) output.add(response) async def handle_get_stats_primaries(self, client, input, output): logger.info("MatchmakeRefereeServer.get_stats_primaries()") #--- request --- targets = input.list(MatchmakeRefereeStatsTarget) response = await self.get_stats_primaries(client, targets) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['stats', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.stats, output.add) output.list(response.results, output.result) async def handle_get_stats_all(self, client, input, output): logger.info("MatchmakeRefereeServer.get_stats_all()") #--- request --- target = input.extract(MatchmakeRefereeStatsTarget) response = await self.get_stats_all(client, target) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_create_stats(self, client, input, output): logger.info("MatchmakeRefereeServer.create_stats()") #--- request --- param = input.extract(MatchmakeRefereeStatsInitParam) response = await self.create_stats(client, param) #--- response --- if not isinstance(response, MatchmakeRefereeStats): raise RuntimeError("Expected MatchmakeRefereeStats, got %s" %response.__class__.__name__) output.add(response) async def handle_get_or_create_stats(self, client, input, output): logger.info("MatchmakeRefereeServer.get_or_create_stats()") #--- request --- param = input.extract(MatchmakeRefereeStatsInitParam) response = await self.get_or_create_stats(client, param) #--- response --- if not isinstance(response, MatchmakeRefereeStats): raise RuntimeError("Expected MatchmakeRefereeStats, got %s" %response.__class__.__name__) output.add(response) async def handle_reset_stats(self, client, input, output): logger.info("MatchmakeRefereeServer.reset_stats()") #--- request --- await self.reset_stats(client) async def start_round(self, *args): logger.warning("MatchmakeRefereeServer.start_round not implemented") raise common.RMCError("Core::NotImplemented") async def get_start_round_param(self, *args): logger.warning("MatchmakeRefereeServer.get_start_round_param not implemented") raise common.RMCError("Core::NotImplemented") async def end_round(self, *args): logger.warning("MatchmakeRefereeServer.end_round not implemented") raise common.RMCError("Core::NotImplemented") async def end_round_without_report(self, *args): logger.warning("MatchmakeRefereeServer.end_round_without_report not implemented") raise common.RMCError("Core::NotImplemented") async def get_round_participants(self, *args): logger.warning("MatchmakeRefereeServer.get_round_participants not implemented") raise common.RMCError("Core::NotImplemented") async def get_not_summarized_round(self, *args): logger.warning("MatchmakeRefereeServer.get_not_summarized_round not implemented") raise common.RMCError("Core::NotImplemented") async def get_round(self, *args): logger.warning("MatchmakeRefereeServer.get_round not implemented") raise common.RMCError("Core::NotImplemented") async def get_stats_primary(self, *args): logger.warning("MatchmakeRefereeServer.get_stats_primary not implemented") raise common.RMCError("Core::NotImplemented") async def get_stats_primaries(self, *args): logger.warning("MatchmakeRefereeServer.get_stats_primaries not implemented") raise common.RMCError("Core::NotImplemented") async def get_stats_all(self, *args): logger.warning("MatchmakeRefereeServer.get_stats_all not implemented") raise common.RMCError("Core::NotImplemented") async def create_stats(self, *args): logger.warning("MatchmakeRefereeServer.create_stats not implemented") raise common.RMCError("Core::NotImplemented") async def get_or_create_stats(self, *args): logger.warning("MatchmakeRefereeServer.get_or_create_stats not implemented") raise common.RMCError("Core::NotImplemented") async def reset_stats(self, *args): logger.warning("MatchmakeRefereeServer.reset_stats not implemented") raise common.RMCError("Core::NotImplemented") class MatchmakeExtensionServerMHXX(MatchmakeExtensionProtocolMHXX): def __init__(self): self.methods = { self.METHOD_CLOSE_PARTICIPATION: self.handle_close_participation, self.METHOD_OPEN_PARTICIPATION: self.handle_open_participation, self.METHOD_AUTO_MATCHMAKE_POSTPONE: self.handle_auto_matchmake_postpone, self.METHOD_BROWSE_MATCHMAKE_SESSION: self.handle_browse_matchmake_session, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS: self.handle_browse_matchmake_session_with_host_urls, self.METHOD_CREATE_MATCHMAKE_SESSION: self.handle_create_matchmake_session, self.METHOD_JOIN_MATCHMAKE_SESSION: self.handle_join_matchmake_session, self.METHOD_MODIFY_CURRENT_GAME_ATTRIBUTE: self.handle_modify_current_game_attribute, self.METHOD_UPDATE_NOTIFICATION_DATA: self.handle_update_notification_data, self.METHOD_GET_FRIEND_NOTIFICATION_DATA: self.handle_get_friend_notification_data, self.METHOD_UPDATE_APPLICATION_BUFFER: self.handle_update_application_buffer, self.METHOD_UPDATE_MATCHMAKE_SESSION_ATTRIBUTE: self.handle_update_matchmake_session_attribute, self.METHOD_GET_FRIEND_NOTIFICATION_DATA_LIST: self.handle_get_friend_notification_data_list, self.METHOD_UPDATE_MATCHMAKE_SESSION: self.handle_update_matchmake_session, self.METHOD_AUTO_MATCHMAKE_WITH_SEARCH_CRITERIA_POSTPONE: self.handle_auto_matchmake_with_search_criteria_postpone, self.METHOD_GET_PLAYING_SESSION: self.handle_get_playing_session, self.METHOD_CREATE_COMMUNITY: self.handle_create_community, self.METHOD_UPDATE_COMMUNITY: self.handle_update_community, self.METHOD_JOIN_COMMUNITY: self.handle_join_community, self.METHOD_FIND_COMMUNITY_BY_GATHERING_ID: self.handle_find_community_by_gathering_id, self.METHOD_FIND_OFFICIAL_COMMUNITY: self.handle_find_official_community, self.METHOD_FIND_COMMUNITY_BY_PARTICIPANT: self.handle_find_community_by_participant, self.METHOD_UPDATE_PRIVACY_SETTING: self.handle_update_privacy_setting, self.METHOD_GET_MY_BLOCK_LIST: self.handle_get_my_block_list, self.METHOD_ADD_TO_BLOCK_LIST: self.handle_add_to_block_list, self.METHOD_REMOVE_FROM_BLOCK_LIST: self.handle_remove_from_block_list, self.METHOD_CLEAR_MY_BLOCK_LIST: self.handle_clear_my_block_list, self.METHOD_REPORT_VIOLATION: self.handle_report_violation, self.METHOD_IS_VIOLATION_USER: self.handle_is_violation_user, self.METHOD_JOIN_MATCHMAKE_SESSION_EX: self.handle_join_matchmake_session_ex, self.METHOD_GET_SIMPLE_PLAYING_SESSION: self.handle_get_simple_playing_session, self.METHOD_GET_SIMPLE_COMMUNITY: self.handle_get_simple_community, self.METHOD_AUTO_MATCHMAKE_WITH_GATHERING_ID_POSTPONE: self.handle_auto_matchmake_with_gathering_id_postpone, self.METHOD_UPDATE_PROGRESS_SCORE: self.handle_update_progress_score, self.METHOD_DEBUG_NOTIFY_EVENT: self.handle_debug_notify_event, self.METHOD_GENERATE_MATCHMAKE_SESSION_SYSTEM_PASSWORD: self.handle_generate_matchmake_session_system_password, self.METHOD_CLEAR_MATCHMAKE_SESSION_SYSTEM_PASSWORD: self.handle_clear_matchmake_session_system_password, self.METHOD_CREATE_MATCHMAKE_SESSION_WITH_PARAM: self.handle_create_matchmake_session_with_param, self.METHOD_JOIN_MATCHMAKE_SESSION_WITH_PARAM: self.handle_join_matchmake_session_with_param, self.METHOD_AUTO_MATCHMAKE_WITH_PARAM_POSTPONE: self.handle_auto_matchmake_with_param_postpone, self.METHOD_FIND_MATCHMAKE_SESSION_BY_GATHERING_ID_DETAIL: self.handle_find_matchmake_session_by_gathering_id_detail, self.METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER: self.handle_browse_matchmake_session_no_holder, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER: self.handle_browse_matchmake_session_with_host_urls_no_holder, self.METHOD_UPDATE_MATCHMAKE_SESSION_PART: self.handle_update_matchmake_session_part, self.METHOD_REQUEST_MATCHMAKING: self.handle_request_matchmaking, self.METHOD_WITHDRAW_MATCHMAKING: self.handle_withdraw_matchmaking, self.METHOD_WITHDRAW_MATCHMAKING_ALL: self.handle_withdraw_matchmaking_all, self.METHOD_FIND_MATCHMAKE_SESSION_BY_GATHERING_ID: self.handle_find_matchmake_session_by_gathering_id, self.METHOD_FIND_MATCHMAKE_SESSION_BY_SINGLE_GATHERING_ID: self.handle_find_matchmake_session_by_single_gathering_id, self.METHOD_FIND_MATCHMAKE_SESSION_BY_OWNER: self.handle_find_matchmake_session_by_owner, self.METHOD_FIND_MATCHMAKE_SESSION_BY_PARTICIPANT: self.handle_find_matchmake_session_by_participant, self.METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER_NO_RESULT_RANGE: self.handle_browse_matchmake_session_no_holder_no_result_range, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER_NO_RESULT_RANGE: self.handle_browse_matchmake_session_with_host_urls_no_holder_no_result_range, self.METHOD_UPDATE_FRIEND_USER_PROFILE: self.handle_update_friend_user_profile, self.METHOD_GET_FRIEND_USER_PROFILES: self.handle_get_friend_user_profiles, self.METHOD_GET_FRIENDS: self.handle_get_friends, self.METHOD_ADD_FRIENDS: self.handle_add_friends, self.METHOD_REMOVE_FRIEND: self.handle_remove_friend, self.METHOD_FIND_COMMUNITY_BY_OWNER: self.handle_find_community_by_owner, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on MatchmakeExtensionServerMHXX: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_close_participation(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.close_participation()") #--- request --- gid = input.u32() await self.close_participation(client, gid) async def handle_open_participation(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.open_participation()") #--- request --- gid = input.u32() await self.open_participation(client, gid) async def handle_auto_matchmake_postpone(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.auto_matchmake_postpone()") #--- request --- gathering = input.anydata() message = input.string() response = await self.auto_matchmake_postpone(client, gathering, message) #--- response --- if not isinstance(response, Gathering): raise RuntimeError("Expected Gathering, got %s" %response.__class__.__name__) output.anydata(response) async def handle_browse_matchmake_session(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.browse_matchmake_session()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) range = input.extract(common.ResultRange) response = await self.browse_matchmake_session(client, search_criteria, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_browse_matchmake_session_with_host_urls(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.browse_matchmake_session_with_host_urls()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) range = input.extract(common.ResultRange) response = await self.browse_matchmake_session_with_host_urls(client, search_criteria, range) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['gatherings', 'urls']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.gatherings, output.anydata) output.list(response.urls, output.add) async def handle_create_matchmake_session(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.create_matchmake_session()") #--- request --- gathering = input.anydata() description = input.string() num_participants = input.u16() response = await self.create_matchmake_session(client, gathering, description, num_participants) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['gid', 'session_key']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.u32(response.gid) output.buffer(response.session_key) async def handle_join_matchmake_session(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.join_matchmake_session()") #--- request --- gid = input.u32() message = input.string() response = await self.join_matchmake_session(client, gid, message) #--- response --- if not isinstance(response, bytes): raise RuntimeError("Expected bytes, got %s" %response.__class__.__name__) output.buffer(response) async def handle_modify_current_game_attribute(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.modify_current_game_attribute()") #--- request --- gid = input.u32() attrib = input.u32() value = input.u32() await self.modify_current_game_attribute(client, gid, attrib, value) async def handle_update_notification_data(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.update_notification_data()") #--- request --- type = input.u32() param1 = input.pid() param2 = input.pid() param3 = input.string() await self.update_notification_data(client, type, param1, param2, param3) async def handle_get_friend_notification_data(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.get_friend_notification_data()") #--- request --- type = input.s32() response = await self.get_friend_notification_data(client, type) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_update_application_buffer(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.update_application_buffer()") #--- request --- gid = input.u32() buffer = input.buffer() await self.update_application_buffer(client, gid, buffer) async def handle_update_matchmake_session_attribute(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.update_matchmake_session_attribute()") #--- request --- gid = input.u32() attribs = input.list(input.u32) await self.update_matchmake_session_attribute(client, gid, attribs) async def handle_get_friend_notification_data_list(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.get_friend_notification_data_list()") #--- request --- types = input.list(input.u32) response = await self.get_friend_notification_data_list(client, types) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_update_matchmake_session(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.update_matchmake_session()") #--- request --- gathering = input.anydata() await self.update_matchmake_session(client, gathering) async def handle_auto_matchmake_with_search_criteria_postpone(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.auto_matchmake_with_search_criteria_postpone()") #--- request --- search_criteria = input.list(MatchmakeSessionSearchCriteria) gathering = input.anydata() message = input.string() response = await self.auto_matchmake_with_search_criteria_postpone(client, search_criteria, gathering, message) #--- response --- if not isinstance(response, Gathering): raise RuntimeError("Expected Gathering, got %s" %response.__class__.__name__) output.anydata(response) async def handle_get_playing_session(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.get_playing_session()") #--- request --- pids = input.list(input.pid) response = await self.get_playing_session(client, pids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_create_community(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.create_community()") #--- request --- community = input.extract(PersistentGathering) message = input.string() response = await self.create_community(client, community, message) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u32(response) async def handle_update_community(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.update_community()") #--- request --- community = input.extract(PersistentGathering) await self.update_community(client, community) async def handle_join_community(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.join_community()") #--- request --- gid = input.u32() message = input.string() password = input.string() await self.join_community(client, gid, message, password) async def handle_find_community_by_gathering_id(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.find_community_by_gathering_id()") #--- request --- gids = input.list(input.u32) response = await self.find_community_by_gathering_id(client, gids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_find_official_community(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.find_official_community()") #--- request --- available_only = input.bool() range = input.extract(common.ResultRange) response = await self.find_official_community(client, available_only, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_find_community_by_participant(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.find_community_by_participant()") #--- request --- pid = input.pid() range = input.extract(common.ResultRange) response = await self.find_community_by_participant(client, pid, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_update_privacy_setting(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.update_privacy_setting()") #--- request --- online_status = input.bool() community_participation = input.bool() await self.update_privacy_setting(client, online_status, community_participation) async def handle_get_my_block_list(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.get_my_block_list()") #--- request --- response = await self.get_my_block_list(client) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.pid) async def handle_add_to_block_list(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.add_to_block_list()") #--- request --- pids = input.list(input.pid) await self.add_to_block_list(client, pids) async def handle_remove_from_block_list(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.remove_from_block_list()") #--- request --- pids = input.list(input.pid) await self.remove_from_block_list(client, pids) async def handle_clear_my_block_list(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.clear_my_block_list()") #--- request --- await self.clear_my_block_list(client) async def handle_report_violation(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.report_violation()") #--- request --- pid = input.pid() username = input.string() violation_code = input.u32() await self.report_violation(client, pid, username, violation_code) async def handle_is_violation_user(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.is_violation_user()") #--- request --- response = await self.is_violation_user(client) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['flag', 'score']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.flag) output.u32(response.score) async def handle_join_matchmake_session_ex(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.join_matchmake_session_ex()") #--- request --- gid = input.u32() gmessage = input.string() ignore_block_list = input.bool() num_participants = input.u16() response = await self.join_matchmake_session_ex(client, gid, gmessage, ignore_block_list, num_participants) #--- response --- if not isinstance(response, bytes): raise RuntimeError("Expected bytes, got %s" %response.__class__.__name__) output.buffer(response) async def handle_get_simple_playing_session(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.get_simple_playing_session()") #--- request --- pids = input.list(input.pid) include_login_user = input.bool() response = await self.get_simple_playing_session(client, pids, include_login_user) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_simple_community(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.get_simple_community()") #--- request --- gids = input.list(input.u32) response = await self.get_simple_community(client, gids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_auto_matchmake_with_gathering_id_postpone(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.auto_matchmake_with_gathering_id_postpone()") #--- request --- gids = input.list(input.u32) gathering = input.anydata() message = input.string() response = await self.auto_matchmake_with_gathering_id_postpone(client, gids, gathering, message) #--- response --- if not isinstance(response, Gathering): raise RuntimeError("Expected Gathering, got %s" %response.__class__.__name__) output.anydata(response) async def handle_update_progress_score(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.update_progress_score()") #--- request --- gid = input.u32() score = input.u8() await self.update_progress_score(client, gid, score) async def handle_debug_notify_event(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.debug_notify_event()") #--- request --- pid = input.pid() main_type = input.u32() sub_type = input.u32() param1 = input.u64() param2 = input.u64() param3 = input.string() await self.debug_notify_event(client, pid, main_type, sub_type, param1, param2, param3) async def handle_generate_matchmake_session_system_password(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.generate_matchmake_session_system_password()") #--- request --- gid = input.u32() response = await self.generate_matchmake_session_system_password(client, gid) #--- response --- if not isinstance(response, str): raise RuntimeError("Expected str, got %s" %response.__class__.__name__) output.string(response) async def handle_clear_matchmake_session_system_password(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.clear_matchmake_session_system_password()") #--- request --- gid = input.u32() await self.clear_matchmake_session_system_password(client, gid) async def handle_create_matchmake_session_with_param(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.create_matchmake_session_with_param()") #--- request --- param = input.extract(CreateMatchmakeSessionParam) response = await self.create_matchmake_session_with_param(client, param) #--- response --- if not isinstance(response, MatchmakeSession): raise RuntimeError("Expected MatchmakeSession, got %s" %response.__class__.__name__) output.add(response) async def handle_join_matchmake_session_with_param(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.join_matchmake_session_with_param()") #--- request --- param = input.extract(JoinMatchmakeSessionParam) response = await self.join_matchmake_session_with_param(client, param) #--- response --- if not isinstance(response, MatchmakeSession): raise RuntimeError("Expected MatchmakeSession, got %s" %response.__class__.__name__) output.add(response) async def handle_auto_matchmake_with_param_postpone(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.auto_matchmake_with_param_postpone()") #--- request --- param = input.extract(AutoMatchmakeParam) response = await self.auto_matchmake_with_param_postpone(client, param) #--- response --- if not isinstance(response, MatchmakeSession): raise RuntimeError("Expected MatchmakeSession, got %s" %response.__class__.__name__) output.add(response) async def handle_find_matchmake_session_by_gathering_id_detail(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.find_matchmake_session_by_gathering_id_detail()") #--- request --- gid = input.u32() response = await self.find_matchmake_session_by_gathering_id_detail(client, gid) #--- response --- if not isinstance(response, MatchmakeSession): raise RuntimeError("Expected MatchmakeSession, got %s" %response.__class__.__name__) output.add(response) async def handle_browse_matchmake_session_no_holder(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.browse_matchmake_session_no_holder()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) range = input.extract(common.ResultRange) response = await self.browse_matchmake_session_no_holder(client, search_criteria, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_browse_matchmake_session_with_host_urls_no_holder(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.browse_matchmake_session_with_host_urls_no_holder()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) range = input.extract(common.ResultRange) response = await self.browse_matchmake_session_with_host_urls_no_holder(client, search_criteria, range) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['sessions', 'urls']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.sessions, output.add) output.list(response.urls, output.add) async def handle_update_matchmake_session_part(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.update_matchmake_session_part()") #--- request --- param = input.extract(UpdateMatchmakeSessionParam) await self.update_matchmake_session_part(client, param) async def handle_request_matchmaking(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.request_matchmaking()") #--- request --- param = input.extract(AutoMatchmakeParam) response = await self.request_matchmaking(client, param) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u64(response) async def handle_withdraw_matchmaking(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.withdraw_matchmaking()") #--- request --- request_id = input.u64() await self.withdraw_matchmaking(client, request_id) async def handle_withdraw_matchmaking_all(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.withdraw_matchmaking_all()") #--- request --- await self.withdraw_matchmaking_all(client) async def handle_find_matchmake_session_by_gathering_id(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.find_matchmake_session_by_gathering_id()") #--- request --- gids = input.list(input.u32) response = await self.find_matchmake_session_by_gathering_id(client, gids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_find_matchmake_session_by_single_gathering_id(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.find_matchmake_session_by_single_gathering_id()") #--- request --- gid = input.u32() response = await self.find_matchmake_session_by_single_gathering_id(client, gid) #--- response --- if not isinstance(response, MatchmakeSession): raise RuntimeError("Expected MatchmakeSession, got %s" %response.__class__.__name__) output.add(response) async def handle_find_matchmake_session_by_owner(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.find_matchmake_session_by_owner()") #--- request --- pid = input.pid() range = input.extract(common.ResultRange) response = await self.find_matchmake_session_by_owner(client, pid, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_find_matchmake_session_by_participant(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.find_matchmake_session_by_participant()") #--- request --- param = input.extract(FindMatchmakeSessionByParticipantParam) response = await self.find_matchmake_session_by_participant(client, param) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_browse_matchmake_session_no_holder_no_result_range(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.browse_matchmake_session_no_holder_no_result_range()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) response = await self.browse_matchmake_session_no_holder_no_result_range(client, search_criteria) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_browse_matchmake_session_with_host_urls_no_holder_no_result_range(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.browse_matchmake_session_with_host_urls_no_holder_no_result_range()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) response = await self.browse_matchmake_session_with_host_urls_no_holder_no_result_range(client, search_criteria) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['sessions', 'urls']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.sessions, output.add) output.list(response.urls, output.add) async def handle_update_friend_user_profile(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.update_friend_user_profile()") #--- request --- param = input.extract(FriendUserParam) await self.update_friend_user_profile(client, param) async def handle_get_friend_user_profiles(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.get_friend_user_profiles()") #--- request --- pids = input.list(input.u64) response = await self.get_friend_user_profiles(client, pids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_friends(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.get_friends()") #--- request --- response = await self.get_friends(client) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_add_friends(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.add_friends()") #--- request --- pids = input.list(input.u64) await self.add_friends(client, pids) async def handle_remove_friend(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.remove_friend()") #--- request --- pid = input.u64() await self.remove_friend(client, pid) async def handle_find_community_by_owner(self, client, input, output): logger.info("MatchmakeExtensionServerMHXX.find_community_by_owner()") #--- request --- id = input.u64() range = input.extract(common.ResultRange) response = await self.find_community_by_owner(client, id, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def close_participation(self, *args): logger.warning("MatchmakeExtensionServerMHXX.close_participation not implemented") raise common.RMCError("Core::NotImplemented") async def open_participation(self, *args): logger.warning("MatchmakeExtensionServerMHXX.open_participation not implemented") raise common.RMCError("Core::NotImplemented") async def auto_matchmake_postpone(self, *args): logger.warning("MatchmakeExtensionServerMHXX.auto_matchmake_postpone not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session(self, *args): logger.warning("MatchmakeExtensionServerMHXX.browse_matchmake_session not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session_with_host_urls(self, *args): logger.warning("MatchmakeExtensionServerMHXX.browse_matchmake_session_with_host_urls not implemented") raise common.RMCError("Core::NotImplemented") async def create_matchmake_session(self, *args): logger.warning("MatchmakeExtensionServerMHXX.create_matchmake_session not implemented") raise common.RMCError("Core::NotImplemented") async def join_matchmake_session(self, *args): logger.warning("MatchmakeExtensionServerMHXX.join_matchmake_session not implemented") raise common.RMCError("Core::NotImplemented") async def modify_current_game_attribute(self, *args): logger.warning("MatchmakeExtensionServerMHXX.modify_current_game_attribute not implemented") raise common.RMCError("Core::NotImplemented") async def update_notification_data(self, *args): logger.warning("MatchmakeExtensionServerMHXX.update_notification_data not implemented") raise common.RMCError("Core::NotImplemented") async def get_friend_notification_data(self, *args): logger.warning("MatchmakeExtensionServerMHXX.get_friend_notification_data not implemented") raise common.RMCError("Core::NotImplemented") async def update_application_buffer(self, *args): logger.warning("MatchmakeExtensionServerMHXX.update_application_buffer not implemented") raise common.RMCError("Core::NotImplemented") async def update_matchmake_session_attribute(self, *args): logger.warning("MatchmakeExtensionServerMHXX.update_matchmake_session_attribute not implemented") raise common.RMCError("Core::NotImplemented") async def get_friend_notification_data_list(self, *args): logger.warning("MatchmakeExtensionServerMHXX.get_friend_notification_data_list not implemented") raise common.RMCError("Core::NotImplemented") async def update_matchmake_session(self, *args): logger.warning("MatchmakeExtensionServerMHXX.update_matchmake_session not implemented") raise common.RMCError("Core::NotImplemented") async def auto_matchmake_with_search_criteria_postpone(self, *args): logger.warning("MatchmakeExtensionServerMHXX.auto_matchmake_with_search_criteria_postpone not implemented") raise common.RMCError("Core::NotImplemented") async def get_playing_session(self, *args): logger.warning("MatchmakeExtensionServerMHXX.get_playing_session not implemented") raise common.RMCError("Core::NotImplemented") async def create_community(self, *args): logger.warning("MatchmakeExtensionServerMHXX.create_community not implemented") raise common.RMCError("Core::NotImplemented") async def update_community(self, *args): logger.warning("MatchmakeExtensionServerMHXX.update_community not implemented") raise common.RMCError("Core::NotImplemented") async def join_community(self, *args): logger.warning("MatchmakeExtensionServerMHXX.join_community not implemented") raise common.RMCError("Core::NotImplemented") async def find_community_by_gathering_id(self, *args): logger.warning("MatchmakeExtensionServerMHXX.find_community_by_gathering_id not implemented") raise common.RMCError("Core::NotImplemented") async def find_official_community(self, *args): logger.warning("MatchmakeExtensionServerMHXX.find_official_community not implemented") raise common.RMCError("Core::NotImplemented") async def find_community_by_participant(self, *args): logger.warning("MatchmakeExtensionServerMHXX.find_community_by_participant not implemented") raise common.RMCError("Core::NotImplemented") async def update_privacy_setting(self, *args): logger.warning("MatchmakeExtensionServerMHXX.update_privacy_setting not implemented") raise common.RMCError("Core::NotImplemented") async def get_my_block_list(self, *args): logger.warning("MatchmakeExtensionServerMHXX.get_my_block_list not implemented") raise common.RMCError("Core::NotImplemented") async def add_to_block_list(self, *args): logger.warning("MatchmakeExtensionServerMHXX.add_to_block_list not implemented") raise common.RMCError("Core::NotImplemented") async def remove_from_block_list(self, *args): logger.warning("MatchmakeExtensionServerMHXX.remove_from_block_list not implemented") raise common.RMCError("Core::NotImplemented") async def clear_my_block_list(self, *args): logger.warning("MatchmakeExtensionServerMHXX.clear_my_block_list not implemented") raise common.RMCError("Core::NotImplemented") async def report_violation(self, *args): logger.warning("MatchmakeExtensionServerMHXX.report_violation not implemented") raise common.RMCError("Core::NotImplemented") async def is_violation_user(self, *args): logger.warning("MatchmakeExtensionServerMHXX.is_violation_user not implemented") raise common.RMCError("Core::NotImplemented") async def join_matchmake_session_ex(self, *args): logger.warning("MatchmakeExtensionServerMHXX.join_matchmake_session_ex not implemented") raise common.RMCError("Core::NotImplemented") async def get_simple_playing_session(self, *args): logger.warning("MatchmakeExtensionServerMHXX.get_simple_playing_session not implemented") raise common.RMCError("Core::NotImplemented") async def get_simple_community(self, *args): logger.warning("MatchmakeExtensionServerMHXX.get_simple_community not implemented") raise common.RMCError("Core::NotImplemented") async def auto_matchmake_with_gathering_id_postpone(self, *args): logger.warning("MatchmakeExtensionServerMHXX.auto_matchmake_with_gathering_id_postpone not implemented") raise common.RMCError("Core::NotImplemented") async def update_progress_score(self, *args): logger.warning("MatchmakeExtensionServerMHXX.update_progress_score not implemented") raise common.RMCError("Core::NotImplemented") async def debug_notify_event(self, *args): logger.warning("MatchmakeExtensionServerMHXX.debug_notify_event not implemented") raise common.RMCError("Core::NotImplemented") async def generate_matchmake_session_system_password(self, *args): logger.warning("MatchmakeExtensionServerMHXX.generate_matchmake_session_system_password not implemented") raise common.RMCError("Core::NotImplemented") async def clear_matchmake_session_system_password(self, *args): logger.warning("MatchmakeExtensionServerMHXX.clear_matchmake_session_system_password not implemented") raise common.RMCError("Core::NotImplemented") async def create_matchmake_session_with_param(self, *args): logger.warning("MatchmakeExtensionServerMHXX.create_matchmake_session_with_param not implemented") raise common.RMCError("Core::NotImplemented") async def join_matchmake_session_with_param(self, *args): logger.warning("MatchmakeExtensionServerMHXX.join_matchmake_session_with_param not implemented") raise common.RMCError("Core::NotImplemented") async def auto_matchmake_with_param_postpone(self, *args): logger.warning("MatchmakeExtensionServerMHXX.auto_matchmake_with_param_postpone not implemented") raise common.RMCError("Core::NotImplemented") async def find_matchmake_session_by_gathering_id_detail(self, *args): logger.warning("MatchmakeExtensionServerMHXX.find_matchmake_session_by_gathering_id_detail not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session_no_holder(self, *args): logger.warning("MatchmakeExtensionServerMHXX.browse_matchmake_session_no_holder not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session_with_host_urls_no_holder(self, *args): logger.warning("MatchmakeExtensionServerMHXX.browse_matchmake_session_with_host_urls_no_holder not implemented") raise common.RMCError("Core::NotImplemented") async def update_matchmake_session_part(self, *args): logger.warning("MatchmakeExtensionServerMHXX.update_matchmake_session_part not implemented") raise common.RMCError("Core::NotImplemented") async def request_matchmaking(self, *args): logger.warning("MatchmakeExtensionServerMHXX.request_matchmaking not implemented") raise common.RMCError("Core::NotImplemented") async def withdraw_matchmaking(self, *args): logger.warning("MatchmakeExtensionServerMHXX.withdraw_matchmaking not implemented") raise common.RMCError("Core::NotImplemented") async def withdraw_matchmaking_all(self, *args): logger.warning("MatchmakeExtensionServerMHXX.withdraw_matchmaking_all not implemented") raise common.RMCError("Core::NotImplemented") async def find_matchmake_session_by_gathering_id(self, *args): logger.warning("MatchmakeExtensionServerMHXX.find_matchmake_session_by_gathering_id not implemented") raise common.RMCError("Core::NotImplemented") async def find_matchmake_session_by_single_gathering_id(self, *args): logger.warning("MatchmakeExtensionServerMHXX.find_matchmake_session_by_single_gathering_id not implemented") raise common.RMCError("Core::NotImplemented") async def find_matchmake_session_by_owner(self, *args): logger.warning("MatchmakeExtensionServerMHXX.find_matchmake_session_by_owner not implemented") raise common.RMCError("Core::NotImplemented") async def find_matchmake_session_by_participant(self, *args): logger.warning("MatchmakeExtensionServerMHXX.find_matchmake_session_by_participant not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session_no_holder_no_result_range(self, *args): logger.warning("MatchmakeExtensionServerMHXX.browse_matchmake_session_no_holder_no_result_range not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session_with_host_urls_no_holder_no_result_range(self, *args): logger.warning("MatchmakeExtensionServerMHXX.browse_matchmake_session_with_host_urls_no_holder_no_result_range not implemented") raise common.RMCError("Core::NotImplemented") async def update_friend_user_profile(self, *args): logger.warning("MatchmakeExtensionServerMHXX.update_friend_user_profile not implemented") raise common.RMCError("Core::NotImplemented") async def get_friend_user_profiles(self, *args): logger.warning("MatchmakeExtensionServerMHXX.get_friend_user_profiles not implemented") raise common.RMCError("Core::NotImplemented") async def get_friends(self, *args): logger.warning("MatchmakeExtensionServerMHXX.get_friends not implemented") raise common.RMCError("Core::NotImplemented") async def add_friends(self, *args): logger.warning("MatchmakeExtensionServerMHXX.add_friends not implemented") raise common.RMCError("Core::NotImplemented") async def remove_friend(self, *args): logger.warning("MatchmakeExtensionServerMHXX.remove_friend not implemented") raise common.RMCError("Core::NotImplemented") async def find_community_by_owner(self, *args): logger.warning("MatchmakeExtensionServerMHXX.find_community_by_owner not implemented") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/matchmaking_mk8.py ================================================ # This file was generated automatically by generate_protocols.py from nintendo.nex import notification, rmc, common, streams import logging logger = logging.getLogger(__name__) class MatchmakeSystem: GLOBAL = 1 FRIENDS = 2 class Gathering(common.Structure): def __init__(self): super().__init__() self.id = 0 self.owner = 0 self.host = 0 self.min_participants = 0 self.max_participants = 0 self.participation_policy = 1 self.policy_argument = 0 self.flags = 512 self.state = 0 self.description = "" def check_required(self, settings, version): pass def load(self, stream, version): self.id = stream.u32() self.owner = stream.pid() self.host = stream.pid() self.min_participants = stream.u16() self.max_participants = stream.u16() self.participation_policy = stream.u32() self.policy_argument = stream.u32() self.flags = stream.u32() self.state = stream.u32() self.description = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.id) stream.pid(self.owner) stream.pid(self.host) stream.u16(self.min_participants) stream.u16(self.max_participants) stream.u32(self.participation_policy) stream.u32(self.policy_argument) stream.u32(self.flags) stream.u32(self.state) stream.string(self.description) class GatheringURLs(common.Structure): def __init__(self): super().__init__() self.gid = None self.urls = None def check_required(self, settings, version): for field in ['gid', 'urls']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.gid = stream.u32() self.urls = stream.list(stream.stationurl) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.gid) stream.list(self.urls, stream.stationurl) class GatheringStats(common.Structure): def __init__(self): super().__init__() self.pid = None self.flags = None self.values = None def check_required(self, settings, version): for field in ['pid', 'flags', 'values']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.flags = stream.u32() self.values = stream.list(stream.float) def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.u32(self.flags) stream.list(self.values, stream.float) class Invitation(common.Structure): def __init__(self): super().__init__() self.gid = None self.guest = None self.message = None def check_required(self, settings, version): for field in ['gid', 'guest', 'message']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.gid = stream.u32() self.guest = stream.u32() self.message = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.gid) stream.u32(self.guest) stream.string(self.message) class ParticipantDetails(common.Structure): def __init__(self): super().__init__() self.pid = None self.name = None self.message = None self.participants = None def check_required(self, settings, version): for field in ['pid', 'name', 'message', 'participants']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.name = stream.string() self.message = stream.string() self.participants = stream.u16() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.string(self.name) stream.string(self.message) stream.u16(self.participants) class DeletionEntry(common.Structure): def __init__(self): super().__init__() self.gid = None self.pid = None self.reason = None def check_required(self, settings, version): for field in ['gid', 'pid', 'reason']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.gid = stream.u32() self.pid = stream.pid() self.reason = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.gid) stream.pid(self.pid) stream.u32(self.reason) class MatchmakeParam(common.Structure): def __init__(self): super().__init__() self.param = {} def check_required(self, settings, version): pass def load(self, stream, version): self.param = stream.map(stream.string, stream.variant) def save(self, stream, version): self.check_required(stream.settings, version) stream.map(self.param, stream.string, stream.variant) class MatchmakeSessionSearchCriteria(common.Structure): def __init__(self): super().__init__() self.attribs = ["", "", "", "", "", ""] self.game_mode = "" self.min_participants = "" self.max_participants = "" self.matchmake_system = "" self.vacant_only = True self.exclude_locked = True self.exclude_non_host_pid = False self.selection_method = 0 self.vacant_participants = 1 self.param = MatchmakeParam() self.exclude_user_password = False self.exclude_system_password = False self.refer_gid = 0 self.codeword = "" self.range = common.ResultRange() def check_required(self, settings, version): if settings["nex.version"] >= 30500: pass if settings["nex.version"] >= 40000: pass def load(self, stream, version): self.attribs = stream.list(stream.string) self.game_mode = stream.string() self.min_participants = stream.string() self.max_participants = stream.string() self.matchmake_system = stream.string() self.vacant_only = stream.bool() self.exclude_locked = stream.bool() self.exclude_non_host_pid = stream.bool() self.selection_method = stream.u32() if stream.settings["nex.version"] >= 30500: self.vacant_participants = stream.u16() if stream.settings["nex.version"] >= 40000: self.param = stream.extract(MatchmakeParam) self.exclude_user_password = stream.bool() self.exclude_system_password = stream.bool() self.refer_gid = stream.u32() self.codeword = stream.string() self.range = stream.extract(common.ResultRange) def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.attribs, stream.string) stream.string(self.game_mode) stream.string(self.min_participants) stream.string(self.max_participants) stream.string(self.matchmake_system) stream.bool(self.vacant_only) stream.bool(self.exclude_locked) stream.bool(self.exclude_non_host_pid) stream.u32(self.selection_method) if stream.settings["nex.version"] >= 30500: stream.u16(self.vacant_participants) if stream.settings["nex.version"] >= 40000: stream.add(self.param) stream.bool(self.exclude_user_password) stream.bool(self.exclude_system_password) stream.u32(self.refer_gid) stream.string(self.codeword) stream.add(self.range) class MatchmakeSession(Gathering): def __init__(self): super().__init__() self.game_mode = 0 self.attribs = [0, 0, 0, 0, 0, 0] self.open_participation = True self.matchmake_system = 0 self.application_data = b"" self.num_participants = 0 self.progress_score = 100 self.session_key = b"" self.option = 0 self.param = MatchmakeParam() self.started_time = common.DateTime(0) self.user_password = "" self.refer_gid = 0 self.user_password_enabled = False self.system_password_enabled = False self.codeword = "" def max_version(self, settings): version = 0 if 30000 <= settings["nex.version"] < 40000: if settings["nex.version"] >= 30600: version = 1 if settings["nex.version"] >= 30700: version = 2 if settings["nex.version"] >= 30800: version = 3 return version def check_required(self, settings, version): if 30000 <= settings["nex.version"] < 40000: if settings["nex.version"] >= 30500: pass if settings["nex.version"] >= 30000: pass if settings["nex.version"] >= 30500: pass if settings["nex.version"] >= 30600: if version >= 1: pass if settings["nex.version"] >= 30700: if version >= 2: pass if settings["nex.version"] >= 30800: if version >= 3: pass if settings["nex.version"] >= 40000: pass def load(self, stream, version): self.game_mode = stream.u32() self.attribs = stream.list(stream.u32) self.open_participation = stream.bool() self.matchmake_system = stream.u32() self.application_data = stream.buffer() self.num_participants = stream.u32() if 30000 <= stream.settings["nex.version"] < 40000: if stream.settings["nex.version"] >= 30500: self.progress_score = stream.u8() if stream.settings["nex.version"] >= 30000: self.session_key = stream.buffer() if stream.settings["nex.version"] >= 30500: self.option = stream.u32() if stream.settings["nex.version"] >= 30600: if version >= 1: self.param = stream.extract(MatchmakeParam) self.started_time = stream.datetime() if stream.settings["nex.version"] >= 30700: if version >= 2: self.user_password = stream.string() if stream.settings["nex.version"] >= 30800: if version >= 3: self.refer_gid = stream.u32() self.user_password_enabled = stream.bool() self.system_password_enabled = stream.bool() if stream.settings["nex.version"] >= 40000: self.progress_score = stream.u8() self.session_key = stream.buffer() self.option = stream.u32() self.param = stream.extract(MatchmakeParam) self.started_time = stream.datetime() self.user_password = stream.string() self.refer_gid = stream.u32() self.user_password_enabled = stream.bool() self.system_password_enabled = stream.bool() self.codeword = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.game_mode) stream.list(self.attribs, stream.u32) stream.bool(self.open_participation) stream.u32(self.matchmake_system) stream.buffer(self.application_data) stream.u32(self.num_participants) if 30000 <= stream.settings["nex.version"] < 40000: if stream.settings["nex.version"] >= 30500: stream.u8(self.progress_score) if stream.settings["nex.version"] >= 30000: stream.buffer(self.session_key) if stream.settings["nex.version"] >= 30500: stream.u32(self.option) if stream.settings["nex.version"] >= 30600: if version >= 1: stream.add(self.param) stream.datetime(self.started_time) if stream.settings["nex.version"] >= 30700: if version >= 2: stream.string(self.user_password) if stream.settings["nex.version"] >= 30800: if version >= 3: stream.u32(self.refer_gid) stream.bool(self.user_password_enabled) stream.bool(self.system_password_enabled) if stream.settings["nex.version"] >= 40000: stream.u8(self.progress_score) stream.buffer(self.session_key) stream.u32(self.option) stream.add(self.param) stream.datetime(self.started_time) stream.string(self.user_password) stream.u32(self.refer_gid) stream.bool(self.user_password_enabled) stream.bool(self.system_password_enabled) stream.string(self.codeword) common.DataHolder.register(MatchmakeSession, "MatchmakeSession") class MatchmakeBlockListParam(common.Structure): def __init__(self): super().__init__() self.options = 0 def check_required(self, settings, version): pass def load(self, stream, version): self.options = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.options) class CreateMatchmakeSessionParam(common.Structure): def __init__(self): super().__init__() self.session = MatchmakeSession() self.additional_participants = None self.gid_for_participation_check = None self.options = None self.join_message = None self.num_participants = None def check_required(self, settings, version): for field in ['additional_participants', 'gid_for_participation_check', 'options', 'join_message', 'num_participants']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.session = stream.extract(MatchmakeSession) self.additional_participants = stream.list(stream.pid) self.gid_for_participation_check = stream.u32() self.options = stream.u32() self.join_message = stream.string() self.num_participants = stream.u16() def save(self, stream, version): self.check_required(stream.settings, version) stream.add(self.session) stream.list(self.additional_participants, stream.pid) stream.u32(self.gid_for_participation_check) stream.u32(self.options) stream.string(self.join_message) stream.u16(self.num_participants) class JoinMatchmakeSessionParam(common.Structure): def __init__(self): super().__init__() self.gid = None self.participants = None self.gid_for_participation_check = None self.options = None self.behavior = None self.user_password = None self.system_password = None self.join_message = None self.num_participants = None self.extra_participants = None self.block_list = MatchmakeBlockListParam() def check_required(self, settings, version): for field in ['gid', 'participants', 'gid_for_participation_check', 'options', 'behavior', 'user_password', 'system_password', 'join_message', 'num_participants', 'extra_participants']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.gid = stream.u32() self.participants = stream.list(stream.pid) self.gid_for_participation_check = stream.u32() self.options = stream.u32() self.behavior = stream.u8() self.user_password = stream.string() self.system_password = stream.string() self.join_message = stream.string() self.num_participants = stream.u16() self.extra_participants = stream.u16() self.block_list = stream.extract(MatchmakeBlockListParam) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.gid) stream.list(self.participants, stream.pid) stream.u32(self.gid_for_participation_check) stream.u32(self.options) stream.u8(self.behavior) stream.string(self.user_password) stream.string(self.system_password) stream.string(self.join_message) stream.u16(self.num_participants) stream.u16(self.extra_participants) stream.add(self.block_list) class UpdateMatchmakeSessionParam(common.Structure): def __init__(self): super().__init__() self.gid = None self.modification_flags = None self.attributes = None self.open_participation = None self.application_buffer = None self.progress_score = None self.param = MatchmakeParam() self.started_time = None self.user_password = None self.game_mode = None self.description = None self.min_participants = None self.max_participants = None self.matchmake_system = None self.participation_policy = None self.policy_argument = None self.codeword = None def check_required(self, settings, version): for field in ['gid', 'modification_flags', 'attributes', 'open_participation', 'application_buffer', 'progress_score', 'started_time', 'user_password', 'game_mode', 'description', 'min_participants', 'max_participants', 'matchmake_system', 'participation_policy', 'policy_argument', 'codeword']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.gid = stream.u32() self.modification_flags = stream.u32() self.attributes = stream.list(stream.u32) self.open_participation = stream.bool() self.application_buffer = stream.buffer() self.progress_score = stream.u8() self.param = stream.extract(MatchmakeParam) self.started_time = stream.datetime() self.user_password = stream.string() self.game_mode = stream.u32() self.description = stream.string() self.min_participants = stream.u16() self.max_participants = stream.u16() self.matchmake_system = stream.u32() self.participation_policy = stream.u32() self.policy_argument = stream.u32() self.codeword = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.gid) stream.u32(self.modification_flags) stream.list(self.attributes, stream.u32) stream.bool(self.open_participation) stream.buffer(self.application_buffer) stream.u8(self.progress_score) stream.add(self.param) stream.datetime(self.started_time) stream.string(self.user_password) stream.u32(self.game_mode) stream.string(self.description) stream.u16(self.min_participants) stream.u16(self.max_participants) stream.u32(self.matchmake_system) stream.u32(self.participation_policy) stream.u32(self.policy_argument) stream.string(self.codeword) class AutoMatchmakeParam(common.Structure): def __init__(self): super().__init__() self.session = MatchmakeSession() self.participants = None self.gid_for_participation_check = None self.options = None self.join_message = None self.num_participants = None self.search_criteria = None self.target_gids = None self.block_list = MatchmakeBlockListParam() def check_required(self, settings, version): for field in ['participants', 'gid_for_participation_check', 'options', 'join_message', 'num_participants', 'search_criteria', 'target_gids']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.session = stream.extract(MatchmakeSession) self.participants = stream.list(stream.pid) self.gid_for_participation_check = stream.u32() self.options = stream.u32() self.join_message = stream.string() self.num_participants = stream.u16() self.search_criteria = stream.list(MatchmakeSessionSearchCriteria) self.target_gids = stream.list(stream.u32) self.block_list = stream.extract(MatchmakeBlockListParam) def save(self, stream, version): self.check_required(stream.settings, version) stream.add(self.session) stream.list(self.participants, stream.pid) stream.u32(self.gid_for_participation_check) stream.u32(self.options) stream.string(self.join_message) stream.u16(self.num_participants) stream.list(self.search_criteria, stream.add) stream.list(self.target_gids, stream.u32) stream.add(self.block_list) class FindMatchmakeSessionByParticipantParam(common.Structure): def __init__(self): super().__init__() self.pids = None self.options = None self.block_list = MatchmakeBlockListParam() def check_required(self, settings, version): for field in ['pids', 'options']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pids = stream.list(stream.pid) self.options = stream.u32() self.block_list = stream.extract(MatchmakeBlockListParam) def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.pids, stream.pid) stream.u32(self.options) stream.add(self.block_list) class FindMatchmakeSessionByParticipantResult(common.Structure): def __init__(self): super().__init__() self.pid = None self.session = MatchmakeSession() def check_required(self, settings, version): for field in ['pid']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.session = stream.extract(MatchmakeSession) def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.add(self.session) class PersistentGathering(Gathering): def __init__(self): super().__init__() self.type = None self.password = None self.attribs = None self.application_buffer = None self.participation_start = None self.participation_end = None self.matchmake_session_count = None self.num_participants = None def check_required(self, settings, version): for field in ['type', 'password', 'attribs', 'application_buffer', 'participation_start', 'participation_end', 'matchmake_session_count', 'num_participants']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.type = stream.u32() self.password = stream.string() self.attribs = stream.list(stream.u32) self.application_buffer = stream.buffer() self.participation_start = stream.datetime() self.participation_end = stream.datetime() self.matchmake_session_count = stream.u32() self.num_participants = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.type) stream.string(self.password) stream.list(self.attribs, stream.u32) stream.buffer(self.application_buffer) stream.datetime(self.participation_start) stream.datetime(self.participation_end) stream.u32(self.matchmake_session_count) stream.u32(self.num_participants) common.DataHolder.register(PersistentGathering, "PersistentGathering") class SimpleCommunity(common.Structure): def __init__(self): super().__init__() self.gid = None self.matchmake_session_count = None def check_required(self, settings, version): for field in ['gid', 'matchmake_session_count']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.gid = stream.u32() self.matchmake_session_count = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.gid) stream.u32(self.matchmake_session_count) class PlayingSession(common.Structure): def __init__(self): super().__init__() self.pid = None self.gathering = None def check_required(self, settings, version): for field in ['pid', 'gathering']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.gathering = stream.anydata() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.anydata(self.gathering) class SimplePlayingSession(common.Structure): def __init__(self): super().__init__() self.pid = None self.gid = None self.game_mode = None self.attribute = None def check_required(self, settings, version): for field in ['pid', 'gid', 'game_mode', 'attribute']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.gid = stream.u32() self.game_mode = stream.u32() self.attribute = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.u32(self.gid) stream.u32(self.game_mode) stream.u32(self.attribute) class MatchmakeRefereeRound(common.Structure): def __init__(self): super().__init__() self.id = None self.gid = None self.state = None self.personal_data_category = None self.results = None def check_required(self, settings, version): for field in ['id', 'gid', 'state', 'personal_data_category', 'results']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.id = stream.u64() self.gid = stream.u32() self.state = stream.u32() self.personal_data_category = stream.u32() self.results = stream.list(MatchmakeRefereePersonalRoundResult) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.id) stream.u32(self.gid) stream.u32(self.state) stream.u32(self.personal_data_category) stream.list(self.results, stream.add) class MatchmakeRefereeStartRoundParam(common.Structure): def __init__(self): super().__init__() self.personal_data_category = None self.gid = None self.pids = None def check_required(self, settings, version): for field in ['personal_data_category', 'gid', 'pids']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.personal_data_category = stream.u32() self.gid = stream.u32() self.pids = stream.list(stream.pid) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.personal_data_category) stream.u32(self.gid) stream.list(self.pids, stream.pid) class MatchmakeRefereeEndRoundParam(common.Structure): def __init__(self): super().__init__() self.round_id = None self.results = None def check_required(self, settings, version): for field in ['round_id', 'results']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.round_id = stream.u64() self.results = stream.list(MatchmakeRefereePersonalRoundResult) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.round_id) stream.list(self.results, stream.add) class MatchmakeRefereePersonalRoundResult(common.Structure): def __init__(self): super().__init__() self.pid = None self.personal_round_result_flag = None self.round_win_loss = None self.rating_change = None self.buffer = None def check_required(self, settings, version): for field in ['pid', 'personal_round_result_flag', 'round_win_loss', 'rating_change', 'buffer']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.personal_round_result_flag = stream.u32() self.round_win_loss = stream.u32() self.rating_change = stream.s32() self.buffer = stream.qbuffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.u32(self.personal_round_result_flag) stream.u32(self.round_win_loss) stream.s32(self.rating_change) stream.qbuffer(self.buffer) class MatchmakeRefereeStats(common.Structure): def __init__(self): super().__init__() self.unique_id = None self.category = None self.pid = None self.recent_disconnection = None self.recent_violation = None self.recent_mismatch = None self.recent_win = None self.recent_loss = None self.recent_draw = None self.total_disconnect = None self.total_violation = None self.total_mismatch = None self.total_win = None self.total_loss = None self.total_draw = None self.rating_value = None def check_required(self, settings, version): for field in ['unique_id', 'category', 'pid', 'recent_disconnection', 'recent_violation', 'recent_mismatch', 'recent_win', 'recent_loss', 'recent_draw', 'total_disconnect', 'total_violation', 'total_mismatch', 'total_win', 'total_loss', 'total_draw', 'rating_value']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.unique_id = stream.u64() self.category = stream.u32() self.pid = stream.pid() self.recent_disconnection = stream.u32() self.recent_violation = stream.u32() self.recent_mismatch = stream.u32() self.recent_win = stream.u32() self.recent_loss = stream.u32() self.recent_draw = stream.u32() self.total_disconnect = stream.u32() self.total_violation = stream.u32() self.total_mismatch = stream.u32() self.total_win = stream.u32() self.total_loss = stream.u32() self.total_draw = stream.u32() self.rating_value = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.unique_id) stream.u32(self.category) stream.pid(self.pid) stream.u32(self.recent_disconnection) stream.u32(self.recent_violation) stream.u32(self.recent_mismatch) stream.u32(self.recent_win) stream.u32(self.recent_loss) stream.u32(self.recent_draw) stream.u32(self.total_disconnect) stream.u32(self.total_violation) stream.u32(self.total_mismatch) stream.u32(self.total_win) stream.u32(self.total_loss) stream.u32(self.total_draw) stream.u32(self.rating_value) class MatchmakeRefereeStatsTarget(common.Structure): def __init__(self): super().__init__() self.pid = None self.category = None def check_required(self, settings, version): for field in ['pid', 'category']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.category = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.u32(self.category) class MatchmakeRefereeStatsInitParam(common.Structure): def __init__(self): super().__init__() self.category = None self.initial_rating = None def check_required(self, settings, version): for field in ['category', 'initial_rating']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.category = stream.u32() self.initial_rating = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.category) stream.u32(self.initial_rating) class SimpleSearchObject(common.Structure): def __init__(self): super().__init__() self.id = None self.owner = None self.attributes = None self.metadata = None self.community_id = None self.community_code = None self.datetime = SimpleSearchDateTimeAttribute() def check_required(self, settings, version): for field in ['id', 'owner', 'attributes', 'metadata', 'community_id', 'community_code']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.id = stream.u32() self.owner = stream.pid() self.attributes = stream.list(stream.u32) self.metadata = stream.qbuffer() self.community_id = stream.u32() self.community_code = stream.string() self.datetime = stream.extract(SimpleSearchDateTimeAttribute) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.id) stream.pid(self.owner) stream.list(self.attributes, stream.u32) stream.qbuffer(self.metadata) stream.u32(self.community_id) stream.string(self.community_code) stream.add(self.datetime) class SimpleSearchDateTimeAttribute(common.Structure): def __init__(self): super().__init__() self.unk1 = None self.unk2 = None self.unk3 = None self.unk4 = None self.start_time = None self.end_time = None def check_required(self, settings, version): for field in ['unk1', 'unk2', 'unk3', 'unk4', 'start_time', 'end_time']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.unk1 = stream.u32() self.unk2 = stream.u32() self.unk3 = stream.u32() self.unk4 = stream.u32() self.start_time = stream.datetime() self.end_time = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.unk1) stream.u32(self.unk2) stream.u32(self.unk3) stream.u32(self.unk4) stream.datetime(self.start_time) stream.datetime(self.end_time) class SimpleSearchParam(common.Structure): def __init__(self): super().__init__() self.unk1 = None self.unk2 = None self.conditions = None self.unk3 = None self.range = common.ResultRange() self.unk4 = None def check_required(self, settings, version): for field in ['unk1', 'unk2', 'conditions', 'unk3', 'unk4']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.unk1 = stream.u32() self.unk2 = stream.pid() self.conditions = stream.list(SimpleSearchCondition) self.unk3 = stream.string() self.range = stream.extract(common.ResultRange) self.unk4 = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.unk1) stream.pid(self.unk2) stream.list(self.conditions, stream.add) stream.string(self.unk3) stream.add(self.range) stream.datetime(self.unk4) class SimpleSearchCondition(common.Structure): def __init__(self): super().__init__() self.value = None self.operator = None def check_required(self, settings, version): for field in ['value', 'operator']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.value = stream.u32() self.operator = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.value) stream.u32(self.operator) class MatchMakingProtocol: METHOD_REGISTER_GATHERING = 1 METHOD_UNREGISTER_GATHERING = 2 METHOD_UNREGISTER_GATHERINGS = 3 METHOD_UPDATE_GATHERING = 4 METHOD_INVITE = 5 METHOD_ACCEPT_INVITATION = 6 METHOD_DECLINE_INVITATION = 7 METHOD_CANCEL_INVITATION = 8 METHOD_GET_INVITATIONS_SENT = 9 METHOD_GET_INVITATIONS_RECEIVED = 10 METHOD_PARTICIPATE = 11 METHOD_CANCEL_PARTICIPATION = 12 METHOD_GET_PARTICIPANTS = 13 METHOD_ADD_PARTICIPANTS = 14 METHOD_GET_DETAILED_PARTICIPANTS = 15 METHOD_GET_PARTICIPANTS_URLS = 16 METHOD_FIND_BY_TYPE = 17 METHOD_FIND_BY_DESCRIPTION = 18 METHOD_FIND_BY_DESCRIPTION_REGEX = 19 METHOD_FIND_BY_ID = 20 METHOD_FIND_BY_SINGLE_ID = 21 METHOD_FIND_BY_OWNER = 22 METHOD_FIND_BY_PARTICIPANTS = 23 METHOD_FIND_INVITATIONS = 24 METHOD_FIND_BY_SQL_QUERY = 25 METHOD_LAUNCH_SESSION = 26 METHOD_UPDATE_SESSION_URL = 27 METHOD_GET_SESSION_URL = 28 METHOD_GET_STATE = 29 METHOD_SET_STATE = 30 METHOD_REPORT_STATS = 31 METHOD_GET_STATS = 32 METHOD_DELETE_GATHERING = 33 METHOD_GET_PENDING_DELETIONS = 34 METHOD_DELETE_FROM_DELETIONS = 35 METHOD_MIGRATE_GATHERING_OWNERSHIP_V1 = 36 METHOD_FIND_BY_DESCRIPTION_LIKE = 37 METHOD_REGISTER_LOCAL_URL = 38 METHOD_REGISTER_LOCAL_URLS = 39 METHOD_UPDATE_SESSION_HOST_V1 = 40 METHOD_GET_SESSION_URLS = 41 METHOD_UPDATE_SESSION_HOST = 42 METHOD_UPDATE_GATHERING_OWNERSHIP = 43 METHOD_MIGRATE_GATHERING_OWNERSHIP = 44 PROTOCOL_ID = 0x15 class MatchMakingProtocolExt: METHOD_END_PARTICIPATION = 1 METHOD_GET_PARTICIPANTS = 2 METHOD_GET_DETAILED_PARTICIPANTS = 3 METHOD_GET_PARTICIPANTS_URLS = 4 METHOD_GET_GATHERING_RELATIONS = 5 METHOD_DELETE_FROM_DELETIONS = 6 PROTOCOL_ID = 0x32 class MatchmakeRefereeProtocol: METHOD_START_ROUND = 1 METHOD_GET_START_ROUND_PARAM = 2 METHOD_END_ROUND = 3 METHOD_END_ROUND_WITHOUT_REPORT = 4 METHOD_GET_ROUND_PARTICIPANTS = 5 METHOD_GET_NOT_SUMMARIZED_ROUND = 6 METHOD_GET_ROUND = 7 METHOD_GET_STATS_PRIMARY = 8 METHOD_GET_STATS_PRIMARIES = 9 METHOD_GET_STATS_ALL = 10 METHOD_CREATE_STATS = 11 METHOD_GET_OR_CREATE_STATS = 12 METHOD_RESET_STATS = 13 PROTOCOL_ID = 0x78 class MatchmakeExtensionProtocolMK8: METHOD_CLOSE_PARTICIPATION = 1 METHOD_OPEN_PARTICIPATION = 2 METHOD_AUTO_MATCHMAKE_POSTPONE = 3 METHOD_BROWSE_MATCHMAKE_SESSION = 4 METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS = 5 METHOD_CREATE_MATCHMAKE_SESSION = 6 METHOD_JOIN_MATCHMAKE_SESSION = 7 METHOD_MODIFY_CURRENT_GAME_ATTRIBUTE = 8 METHOD_UPDATE_NOTIFICATION_DATA = 9 METHOD_GET_FRIEND_NOTIFICATION_DATA = 10 METHOD_UPDATE_APPLICATION_BUFFER = 11 METHOD_UPDATE_MATCHMAKE_SESSION_ATTRIBUTE = 12 METHOD_GET_FRIEND_NOTIFICATION_DATA_LIST = 13 METHOD_UPDATE_MATCHMAKE_SESSION = 14 METHOD_AUTO_MATCHMAKE_WITH_SEARCH_CRITERIA_POSTPONE = 15 METHOD_GET_PLAYING_SESSION = 16 METHOD_CREATE_COMMUNITY = 17 METHOD_UPDATE_COMMUNITY = 18 METHOD_JOIN_COMMUNITY = 19 METHOD_FIND_COMMUNITY_BY_GATHERING_ID = 20 METHOD_FIND_OFFICIAL_COMMUNITY = 21 METHOD_FIND_COMMUNITY_BY_PARTICIPANT = 22 METHOD_UPDATE_PRIVACY_SETTING = 23 METHOD_GET_MY_BLOCK_LIST = 24 METHOD_ADD_TO_BLOCK_LIST = 25 METHOD_REMOVE_FROM_BLOCK_LIST = 26 METHOD_CLEAR_MY_BLOCK_LIST = 27 METHOD_REPORT_VIOLATION = 28 METHOD_IS_VIOLATION_USER = 29 METHOD_JOIN_MATCHMAKE_SESSION_EX = 30 METHOD_GET_SIMPLE_PLAYING_SESSION = 31 METHOD_GET_SIMPLE_COMMUNITY = 32 METHOD_AUTO_MATCHMAKE_WITH_GATHERING_ID_POSTPONE = 33 METHOD_UPDATE_PROGRESS_SCORE = 34 METHOD_DEBUG_NOTIFY_EVENT = 35 METHOD_CREATE_SIMPLE_SEARCH_OBJECT = 36 METHOD_UPDATE_SIMPLE_SEARCH_OBJECT = 37 METHOD_DELETE_SIMPLE_SEARCH_OBJECT = 38 METHOD_SEARCH_SIMPLE_SEARCH_OBJECT = 39 METHOD_JOIN_MATCHMAKE_SESSION_WITH_EXTRA_PARTICIPANTS = 40 METHOD_SEARCH_SIMPLE_SEARCH_OBJECT_BY_OBJECT_IDS = 41 METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER = 42 METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER = 43 METHOD_UPDATE_MATCHMAKE_SESSION_PART = 44 METHOD_REQUEST_MATCHMAKING = 45 METHOD_WITHDRAW_MATCHMAKING = 46 METHOD_WITHDRAW_MATCHMAKING_ALL = 47 METHOD_FIND_MATCHMAKE_SESSION_BY_GATHERING_ID = 48 METHOD_FIND_MATCHMAKE_SESSION_BY_SINGLE_GATHERING_ID = 49 METHOD_FIND_MATCHMAKE_SESSION_BY_OWNER = 50 METHOD_FIND_MATCHMAKE_SESSION_BY_PARTICIPANT = 51 METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER_NO_RESULT_RANGE = 52 METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER_NO_RESULT_RANGE = 53 PROTOCOL_ID = 0x6D class MatchMakingClient(MatchMakingProtocol): def __init__(self, client): self.settings = client.settings self.client = client async def register_gathering(self, gathering): logger.info("MatchMakingClient.register_gathering()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(gathering) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REGISTER_GATHERING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gid = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.register_gathering -> done") return gid async def unregister_gathering(self, gid): logger.info("MatchMakingClient.unregister_gathering()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UNREGISTER_GATHERING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.unregister_gathering -> done") return result async def unregister_gatherings(self, gids): logger.info("MatchMakingClient.unregister_gatherings()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UNREGISTER_GATHERINGS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.unregister_gatherings -> done") return result async def update_gathering(self, gathering): logger.info("MatchMakingClient.update_gathering()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(gathering) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_GATHERING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.update_gathering -> done") return result async def invite(self, gid, pids, message): logger.info("MatchMakingClient.invite()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(pids, stream.pid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_INVITE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.invite -> done") return result async def accept_invitation(self, gid, message): logger.info("MatchMakingClient.accept_invitation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_ACCEPT_INVITATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.accept_invitation -> done") return result async def decline_invitation(self, gid, message): logger.info("MatchMakingClient.decline_invitation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DECLINE_INVITATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.decline_invitation -> done") return result async def cancel_invitation(self, gid, pids, message): logger.info("MatchMakingClient.cancel_invitation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(pids, stream.pid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CANCEL_INVITATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.cancel_invitation -> done") return result async def get_invitations_sent(self, gid): logger.info("MatchMakingClient.get_invitations_sent()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_INVITATIONS_SENT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) invitations = stream.list(Invitation) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_invitations_sent -> done") return invitations async def get_invitations_received(self): logger.info("MatchMakingClient.get_invitations_received()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_INVITATIONS_RECEIVED, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) invitations = stream.list(Invitation) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_invitations_received -> done") return invitations async def participate(self, gid, message): logger.info("MatchMakingClient.participate()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PARTICIPATE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.participate -> done") return result async def cancel_participation(self, gid, message): logger.info("MatchMakingClient.cancel_participation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CANCEL_PARTICIPATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.cancel_participation -> done") return result async def get_participants(self, gid): logger.info("MatchMakingClient.get_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) participants = stream.list(stream.pid) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_participants -> done") return participants async def add_participants(self, gid, pids, message): logger.info("MatchMakingClient.add_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(pids, stream.pid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_ADD_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.add_participants -> done") return result async def get_detailed_participants(self, gid): logger.info("MatchMakingClient.get_detailed_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_DETAILED_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) details = stream.list(ParticipantDetails) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_detailed_participants -> done") return details async def get_participants_urls(self, gid): logger.info("MatchMakingClient.get_participants_urls()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PARTICIPANTS_URLS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) urls = stream.list(stream.stationurl) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_participants_urls -> done") return urls async def find_by_type(self, type, range): logger.info("MatchMakingClient.find_by_type()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(type) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_TYPE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_type -> done") return gatherings async def find_by_description(self, description, range): logger.info("MatchMakingClient.find_by_description()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(description) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_DESCRIPTION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_description -> done") return gatherings async def find_by_description_regex(self, regex, range): logger.info("MatchMakingClient.find_by_description_regex()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(regex) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_DESCRIPTION_REGEX, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_description_regex -> done") return gatherings async def find_by_id(self, ids): logger.info("MatchMakingClient.find_by_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(ids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_id -> done") return gatherings async def find_by_single_id(self, gid): logger.info("MatchMakingClient.find_by_single_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_SINGLE_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.gathering = stream.anydata() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_single_id -> done") return obj async def find_by_owner(self, owner, range): logger.info("MatchMakingClient.find_by_owner()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(owner) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_OWNER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_owner -> done") return gatherings async def find_by_participants(self, pids): logger.info("MatchMakingClient.find_by_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_participants -> done") return gatherings async def find_invitations(self, range): logger.info("MatchMakingClient.find_invitations()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_INVITATIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_invitations -> done") return gatherings async def find_by_sql_query(self, query, range): logger.info("MatchMakingClient.find_by_sql_query()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(query) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_SQL_QUERY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_sql_query -> done") return gatherings async def launch_session(self, gid, url): logger.info("MatchMakingClient.launch_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(url) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_LAUNCH_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.launch_session -> done") return result async def update_session_url(self, gid, url): logger.info("MatchMakingClient.update_session_url()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(url) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_SESSION_URL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.update_session_url -> done") return result async def get_session_url(self, gid): logger.info("MatchMakingClient.get_session_url()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SESSION_URL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.url = stream.string() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_session_url -> done") return obj async def get_state(self, gid): logger.info("MatchMakingClient.get_state()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.state = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_state -> done") return obj async def set_state(self, gid, state): logger.info("MatchMakingClient.set_state()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.u32(state) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SET_STATE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.set_state -> done") return result async def report_stats(self, gid, stats): logger.info("MatchMakingClient.report_stats()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(stats, stream.add) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REPORT_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.report_stats -> done") return result async def get_stats(self, gid, pids, columns): logger.info("MatchMakingClient.get_stats()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(pids, stream.pid) stream.list(columns, stream.u8) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.stats = stream.list(GatheringStats) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_stats -> done") return obj async def delete_gathering(self, gid): logger.info("MatchMakingClient.delete_gathering()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_GATHERING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.delete_gathering -> done") return result async def get_pending_deletions(self, reason, range): logger.info("MatchMakingClient.get_pending_deletions()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(reason) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PENDING_DELETIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.deletions = stream.list(DeletionEntry) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_pending_deletions -> done") return obj async def delete_from_deletions(self, deletions): logger.info("MatchMakingClient.delete_from_deletions()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(deletions, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_FROM_DELETIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.delete_from_deletions -> done") return result async def migrate_gathering_ownership_v1(self, gid, potential_owners): logger.info("MatchMakingClient.migrate_gathering_ownership_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(potential_owners, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_MIGRATE_GATHERING_OWNERSHIP_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.migrate_gathering_ownership_v1 -> done") return result async def find_by_description_like(self, description, range): logger.info("MatchMakingClient.find_by_description_like()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(description) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_DESCRIPTION_LIKE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_description_like -> done") return gatherings async def register_local_url(self, gid, url): logger.info("MatchMakingClient.register_local_url()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.stationurl(url) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REGISTER_LOCAL_URL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.register_local_url -> done") async def register_local_urls(self, gid, urls): logger.info("MatchMakingClient.register_local_urls()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(urls, stream.stationurl) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REGISTER_LOCAL_URLS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.register_local_urls -> done") async def update_session_host_v1(self, gid): logger.info("MatchMakingClient.update_session_host_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_SESSION_HOST_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.update_session_host_v1 -> done") async def get_session_urls(self, gid): logger.info("MatchMakingClient.get_session_urls()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SESSION_URLS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) urls = stream.list(stream.stationurl) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_session_urls -> done") return urls async def update_session_host(self, gid, is_migrate_owner): logger.info("MatchMakingClient.update_session_host()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.bool(is_migrate_owner) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_SESSION_HOST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.update_session_host -> done") async def update_gathering_ownership(self, gid, participants_only): logger.info("MatchMakingClient.update_gathering_ownership()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.bool(participants_only) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_GATHERING_OWNERSHIP, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.update_gathering_ownership -> done") return result async def migrate_gathering_ownership(self, gid, potential_owners, participants_only): logger.info("MatchMakingClient.migrate_gathering_ownership()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(potential_owners, stream.pid) stream.bool(participants_only) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_MIGRATE_GATHERING_OWNERSHIP, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.migrate_gathering_ownership -> done") class MatchMakingClientExt(MatchMakingProtocolExt): def __init__(self, client): self.settings = client.settings self.client = client async def end_participation(self, gid, message): logger.info("MatchMakingClientExt.end_participation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_END_PARTICIPATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.end_participation -> done") return result async def get_participants(self, gid, only_active): logger.info("MatchMakingClientExt.get_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.bool(only_active) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) participants = stream.list(stream.pid) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.get_participants -> done") return participants async def get_detailed_participants(self, gid, only_active): logger.info("MatchMakingClientExt.get_detailed_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.bool(only_active) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_DETAILED_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) details = stream.list(ParticipantDetails) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.get_detailed_participants -> done") return details async def get_participants_urls(self, gids): logger.info("MatchMakingClientExt.get_participants_urls()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PARTICIPANTS_URLS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) urls = stream.list(GatheringURLs) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.get_participants_urls -> done") return urls async def get_gathering_relations(self, id, descr): logger.info("MatchMakingClientExt.get_gathering_relations()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(id) stream.string(descr) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_GATHERING_RELATIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.string() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.get_gathering_relations -> done") return result async def delete_from_deletions(self, deletions, pid): logger.info("MatchMakingClientExt.delete_from_deletions()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(deletions, stream.u32) stream.pid(pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_FROM_DELETIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.delete_from_deletions -> done") class MatchmakeRefereeClient(MatchmakeRefereeProtocol): def __init__(self, client): self.settings = client.settings self.client = client async def start_round(self, param): logger.info("MatchmakeRefereeClient.start_round()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_START_ROUND, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) round_id = stream.u64() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.start_round -> done") return round_id async def get_start_round_param(self, round_id): logger.info("MatchmakeRefereeClient.get_start_round_param()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(round_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_START_ROUND_PARAM, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) param = stream.extract(MatchmakeRefereeStartRoundParam) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_start_round_param -> done") return param async def end_round(self, param): logger.info("MatchmakeRefereeClient.end_round()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_END_ROUND, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.end_round -> done") async def end_round_without_report(self, round_id): logger.info("MatchmakeRefereeClient.end_round_without_report()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(round_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_END_ROUND_WITHOUT_REPORT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.end_round_without_report -> done") async def get_round_participants(self, round_id): logger.info("MatchmakeRefereeClient.get_round_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(round_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_ROUND_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) pids = stream.list(stream.pid) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_round_participants -> done") return pids async def get_not_summarized_round(self): logger.info("MatchmakeRefereeClient.get_not_summarized_round()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_NOT_SUMMARIZED_ROUND, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) rounds = stream.list(MatchmakeRefereeRound) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_not_summarized_round -> done") return rounds async def get_round(self, round): logger.info("MatchmakeRefereeClient.get_round()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(round) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_ROUND, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) round = stream.extract(MatchmakeRefereeRound) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_round -> done") return round async def get_stats_primary(self, target): logger.info("MatchmakeRefereeClient.get_stats_primary()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATS_PRIMARY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) stats = stream.extract(MatchmakeRefereeStats) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_stats_primary -> done") return stats async def get_stats_primaries(self, targets): logger.info("MatchmakeRefereeClient.get_stats_primaries()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(targets, stream.add) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATS_PRIMARIES, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.stats = stream.list(MatchmakeRefereeStats) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_stats_primaries -> done") return obj async def get_stats_all(self, target): logger.info("MatchmakeRefereeClient.get_stats_all()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATS_ALL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) stats = stream.list(MatchmakeRefereeStats) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_stats_all -> done") return stats async def create_stats(self, param): logger.info("MatchmakeRefereeClient.create_stats()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CREATE_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) stats = stream.extract(MatchmakeRefereeStats) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.create_stats -> done") return stats async def get_or_create_stats(self, param): logger.info("MatchmakeRefereeClient.get_or_create_stats()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_OR_CREATE_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) stats = stream.extract(MatchmakeRefereeStats) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_or_create_stats -> done") return stats async def reset_stats(self): logger.info("MatchmakeRefereeClient.reset_stats()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RESET_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.reset_stats -> done") class MatchmakeExtensionClientMK8(MatchmakeExtensionProtocolMK8): def __init__(self, client): self.settings = client.settings self.client = client async def close_participation(self, gid): logger.info("MatchmakeExtensionClientMK8.close_participation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CLOSE_PARTICIPATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.close_participation -> done") async def open_participation(self, gid): logger.info("MatchmakeExtensionClientMK8.open_participation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_OPEN_PARTICIPATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.open_participation -> done") async def auto_matchmake_postpone(self, gathering, message): logger.info("MatchmakeExtensionClientMK8.auto_matchmake_postpone()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(gathering) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_AUTO_MATCHMAKE_POSTPONE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gathering = stream.anydata() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.auto_matchmake_postpone -> done") return gathering async def browse_matchmake_session(self, search_criteria, range): logger.info("MatchmakeExtensionClientMK8.browse_matchmake_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.browse_matchmake_session -> done") return gatherings async def browse_matchmake_session_with_host_urls(self, search_criteria, range): logger.info("MatchmakeExtensionClientMK8.browse_matchmake_session_with_host_urls()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.gatherings = stream.list(stream.anydata) obj.urls = stream.list(GatheringURLs) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.browse_matchmake_session_with_host_urls -> done") return obj async def create_matchmake_session(self, gathering, description, num_participants): logger.info("MatchmakeExtensionClientMK8.create_matchmake_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(gathering) stream.string(description) stream.u16(num_participants) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CREATE_MATCHMAKE_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.gid = stream.u32() obj.session_key = stream.buffer() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.create_matchmake_session -> done") return obj async def join_matchmake_session(self, gid, message): logger.info("MatchmakeExtensionClientMK8.join_matchmake_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_JOIN_MATCHMAKE_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session_key = stream.buffer() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.join_matchmake_session -> done") return session_key async def modify_current_game_attribute(self, gid, attrib, value): logger.info("MatchmakeExtensionClientMK8.modify_current_game_attribute()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.u32(attrib) stream.u32(value) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_MODIFY_CURRENT_GAME_ATTRIBUTE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.modify_current_game_attribute -> done") async def update_notification_data(self, type, param1, param2, param3): logger.info("MatchmakeExtensionClientMK8.update_notification_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(type) stream.pid(param1) stream.pid(param2) stream.string(param3) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_NOTIFICATION_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.update_notification_data -> done") async def get_friend_notification_data(self, type): logger.info("MatchmakeExtensionClientMK8.get_friend_notification_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.s32(type) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_FRIEND_NOTIFICATION_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) notifications = stream.list(notification.NotificationEvent) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.get_friend_notification_data -> done") return notifications async def update_application_buffer(self, gid, buffer): logger.info("MatchmakeExtensionClientMK8.update_application_buffer()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.buffer(buffer) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_APPLICATION_BUFFER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.update_application_buffer -> done") async def update_matchmake_session_attribute(self, gid, attribs): logger.info("MatchmakeExtensionClientMK8.update_matchmake_session_attribute()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(attribs, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_MATCHMAKE_SESSION_ATTRIBUTE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.update_matchmake_session_attribute -> done") async def get_friend_notification_data_list(self, types): logger.info("MatchmakeExtensionClientMK8.get_friend_notification_data_list()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(types, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_FRIEND_NOTIFICATION_DATA_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) notifications = stream.list(notification.NotificationEvent) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.get_friend_notification_data_list -> done") return notifications async def update_matchmake_session(self, gathering): logger.info("MatchmakeExtensionClientMK8.update_matchmake_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(gathering) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_MATCHMAKE_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.update_matchmake_session -> done") async def auto_matchmake_with_search_criteria_postpone(self, search_criteria, gathering, message): logger.info("MatchmakeExtensionClientMK8.auto_matchmake_with_search_criteria_postpone()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(search_criteria, stream.add) stream.anydata(gathering) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_AUTO_MATCHMAKE_WITH_SEARCH_CRITERIA_POSTPONE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gathering = stream.anydata() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.auto_matchmake_with_search_criteria_postpone -> done") return gathering async def get_playing_session(self, pids): logger.info("MatchmakeExtensionClientMK8.get_playing_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PLAYING_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) sessions = stream.list(PlayingSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.get_playing_session -> done") return sessions async def create_community(self, community, message): logger.info("MatchmakeExtensionClientMK8.create_community()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(community) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CREATE_COMMUNITY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gid = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.create_community -> done") return gid async def update_community(self, community): logger.info("MatchmakeExtensionClientMK8.update_community()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(community) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_COMMUNITY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.update_community -> done") async def join_community(self, gid, message, password): logger.info("MatchmakeExtensionClientMK8.join_community()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) stream.string(password) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_JOIN_COMMUNITY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.join_community -> done") async def find_community_by_gathering_id(self, gids): logger.info("MatchmakeExtensionClientMK8.find_community_by_gathering_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_COMMUNITY_BY_GATHERING_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) communities = stream.list(PersistentGathering) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.find_community_by_gathering_id -> done") return communities async def find_official_community(self, available_only, range): logger.info("MatchmakeExtensionClientMK8.find_official_community()") #--- request --- stream = streams.StreamOut(self.settings) stream.bool(available_only) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_OFFICIAL_COMMUNITY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) communities = stream.list(PersistentGathering) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.find_official_community -> done") return communities async def find_community_by_participant(self, pid, range): logger.info("MatchmakeExtensionClientMK8.find_community_by_participant()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_COMMUNITY_BY_PARTICIPANT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) communities = stream.list(PersistentGathering) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.find_community_by_participant -> done") return communities async def update_privacy_setting(self, online_status, community_participation): logger.info("MatchmakeExtensionClientMK8.update_privacy_setting()") #--- request --- stream = streams.StreamOut(self.settings) stream.bool(online_status) stream.bool(community_participation) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_PRIVACY_SETTING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.update_privacy_setting -> done") async def get_my_block_list(self): logger.info("MatchmakeExtensionClientMK8.get_my_block_list()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_MY_BLOCK_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) pids = stream.list(stream.pid) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.get_my_block_list -> done") return pids async def add_to_block_list(self, pids): logger.info("MatchmakeExtensionClientMK8.add_to_block_list()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_ADD_TO_BLOCK_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.add_to_block_list -> done") async def remove_from_block_list(self, pids): logger.info("MatchmakeExtensionClientMK8.remove_from_block_list()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REMOVE_FROM_BLOCK_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.remove_from_block_list -> done") async def clear_my_block_list(self): logger.info("MatchmakeExtensionClientMK8.clear_my_block_list()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CLEAR_MY_BLOCK_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.clear_my_block_list -> done") async def report_violation(self, pid, username, violation_code): logger.info("MatchmakeExtensionClientMK8.report_violation()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) stream.string(username) stream.u32(violation_code) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REPORT_VIOLATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.report_violation -> done") async def is_violation_user(self): logger.info("MatchmakeExtensionClientMK8.is_violation_user()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_IS_VIOLATION_USER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.flag = stream.bool() obj.score = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.is_violation_user -> done") return obj async def join_matchmake_session_ex(self, gid, gmessage, ignore_block_list, num_participants): logger.info("MatchmakeExtensionClientMK8.join_matchmake_session_ex()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(gmessage) stream.bool(ignore_block_list) stream.u16(num_participants) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_JOIN_MATCHMAKE_SESSION_EX, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session_key = stream.buffer() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.join_matchmake_session_ex -> done") return session_key async def get_simple_playing_session(self, pids, include_login_user): logger.info("MatchmakeExtensionClientMK8.get_simple_playing_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) stream.bool(include_login_user) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SIMPLE_PLAYING_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session = stream.list(SimplePlayingSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.get_simple_playing_session -> done") return session async def get_simple_community(self, gids): logger.info("MatchmakeExtensionClientMK8.get_simple_community()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SIMPLE_COMMUNITY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) communities = stream.list(SimpleCommunity) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.get_simple_community -> done") return communities async def auto_matchmake_with_gathering_id_postpone(self, gids, gathering, message): logger.info("MatchmakeExtensionClientMK8.auto_matchmake_with_gathering_id_postpone()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) stream.anydata(gathering) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_AUTO_MATCHMAKE_WITH_GATHERING_ID_POSTPONE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) joined_gathering = stream.anydata() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.auto_matchmake_with_gathering_id_postpone -> done") return joined_gathering async def update_progress_score(self, gid, score): logger.info("MatchmakeExtensionClientMK8.update_progress_score()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.u8(score) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_PROGRESS_SCORE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.update_progress_score -> done") async def debug_notify_event(self, pid, main_type, sub_type, param1, param2, param3): logger.info("MatchmakeExtensionClientMK8.debug_notify_event()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) stream.u32(main_type) stream.u32(sub_type) stream.u64(param1) stream.u64(param2) stream.string(param3) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DEBUG_NOTIFY_EVENT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.debug_notify_event -> done") async def create_simple_search_object(self, object): logger.info("MatchmakeExtensionClientMK8.create_simple_search_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(object) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CREATE_SIMPLE_SEARCH_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) id = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.create_simple_search_object -> done") return id async def update_simple_search_object(self, id, object): logger.info("MatchmakeExtensionClientMK8.update_simple_search_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(id) stream.add(object) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_SIMPLE_SEARCH_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.update_simple_search_object -> done") async def delete_simple_search_object(self, id): logger.info("MatchmakeExtensionClientMK8.delete_simple_search_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_SIMPLE_SEARCH_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.delete_simple_search_object -> done") async def search_simple_search_object(self, param): logger.info("MatchmakeExtensionClientMK8.search_simple_search_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_SIMPLE_SEARCH_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) objects = stream.list(SimpleSearchObject) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.search_simple_search_object -> done") return objects async def join_matchmake_session_with_extra_participants(self, gid, join_message, ignore_blacklist, participation_count, extra_participants): logger.info("MatchmakeExtensionClientMK8.join_matchmake_session_with_extra_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(join_message) stream.bool(ignore_blacklist) stream.u16(participation_count) stream.u32(extra_participants) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_JOIN_MATCHMAKE_SESSION_WITH_EXTRA_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session_key = stream.buffer() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.join_matchmake_session_with_extra_participants -> done") return session_key async def search_simple_search_object_by_object_ids(self, ids): logger.info("MatchmakeExtensionClientMK8.search_simple_search_object_by_object_ids()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(ids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_SIMPLE_SEARCH_OBJECT_BY_OBJECT_IDS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) objects = stream.list(SimpleSearchObject) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.search_simple_search_object_by_object_ids -> done") return objects async def browse_matchmake_session_no_holder(self, search_criteria, range): logger.info("MatchmakeExtensionClientMK8.browse_matchmake_session_no_holder()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) sessions = stream.list(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.browse_matchmake_session_no_holder -> done") return sessions async def browse_matchmake_session_with_host_urls_no_holder(self, search_criteria, range): logger.info("MatchmakeExtensionClientMK8.browse_matchmake_session_with_host_urls_no_holder()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.sessions = stream.list(MatchmakeSession) obj.urls = stream.list(GatheringURLs) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.browse_matchmake_session_with_host_urls_no_holder -> done") return obj async def update_matchmake_session_part(self, param): logger.info("MatchmakeExtensionClientMK8.update_matchmake_session_part()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_MATCHMAKE_SESSION_PART, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.update_matchmake_session_part -> done") async def request_matchmaking(self, param): logger.info("MatchmakeExtensionClientMK8.request_matchmaking()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REQUEST_MATCHMAKING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) request_id = stream.u64() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.request_matchmaking -> done") return request_id async def withdraw_matchmaking(self, request_id): logger.info("MatchmakeExtensionClientMK8.withdraw_matchmaking()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(request_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_WITHDRAW_MATCHMAKING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.withdraw_matchmaking -> done") async def withdraw_matchmaking_all(self): logger.info("MatchmakeExtensionClientMK8.withdraw_matchmaking_all()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_WITHDRAW_MATCHMAKING_ALL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.withdraw_matchmaking_all -> done") async def find_matchmake_session_by_gathering_id(self, gids): logger.info("MatchmakeExtensionClientMK8.find_matchmake_session_by_gathering_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_MATCHMAKE_SESSION_BY_GATHERING_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) sessions = stream.list(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.find_matchmake_session_by_gathering_id -> done") return sessions async def find_matchmake_session_by_single_gathering_id(self, gid): logger.info("MatchmakeExtensionClientMK8.find_matchmake_session_by_single_gathering_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_MATCHMAKE_SESSION_BY_SINGLE_GATHERING_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session = stream.extract(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.find_matchmake_session_by_single_gathering_id -> done") return session async def find_matchmake_session_by_owner(self, pid, range): logger.info("MatchmakeExtensionClientMK8.find_matchmake_session_by_owner()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_MATCHMAKE_SESSION_BY_OWNER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) sessions = stream.list(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.find_matchmake_session_by_owner -> done") return sessions async def find_matchmake_session_by_participant(self, param): logger.info("MatchmakeExtensionClientMK8.find_matchmake_session_by_participant()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_MATCHMAKE_SESSION_BY_PARTICIPANT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.list(FindMatchmakeSessionByParticipantResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.find_matchmake_session_by_participant -> done") return result async def browse_matchmake_session_no_holder_no_result_range(self, search_criteria): logger.info("MatchmakeExtensionClientMK8.browse_matchmake_session_no_holder_no_result_range()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER_NO_RESULT_RANGE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) sessions = stream.list(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.browse_matchmake_session_no_holder_no_result_range -> done") return sessions async def browse_matchmake_session_with_host_urls_no_holder_no_result_range(self, search_criteria): logger.info("MatchmakeExtensionClientMK8.browse_matchmake_session_with_host_urls_no_holder_no_result_range()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER_NO_RESULT_RANGE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.sessions = stream.list(MatchmakeSession) obj.urls = stream.list(GatheringURLs) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8.browse_matchmake_session_with_host_urls_no_holder_no_result_range -> done") return obj class MatchMakingServer(MatchMakingProtocol): def __init__(self): self.methods = { self.METHOD_REGISTER_GATHERING: self.handle_register_gathering, self.METHOD_UNREGISTER_GATHERING: self.handle_unregister_gathering, self.METHOD_UNREGISTER_GATHERINGS: self.handle_unregister_gatherings, self.METHOD_UPDATE_GATHERING: self.handle_update_gathering, self.METHOD_INVITE: self.handle_invite, self.METHOD_ACCEPT_INVITATION: self.handle_accept_invitation, self.METHOD_DECLINE_INVITATION: self.handle_decline_invitation, self.METHOD_CANCEL_INVITATION: self.handle_cancel_invitation, self.METHOD_GET_INVITATIONS_SENT: self.handle_get_invitations_sent, self.METHOD_GET_INVITATIONS_RECEIVED: self.handle_get_invitations_received, self.METHOD_PARTICIPATE: self.handle_participate, self.METHOD_CANCEL_PARTICIPATION: self.handle_cancel_participation, self.METHOD_GET_PARTICIPANTS: self.handle_get_participants, self.METHOD_ADD_PARTICIPANTS: self.handle_add_participants, self.METHOD_GET_DETAILED_PARTICIPANTS: self.handle_get_detailed_participants, self.METHOD_GET_PARTICIPANTS_URLS: self.handle_get_participants_urls, self.METHOD_FIND_BY_TYPE: self.handle_find_by_type, self.METHOD_FIND_BY_DESCRIPTION: self.handle_find_by_description, self.METHOD_FIND_BY_DESCRIPTION_REGEX: self.handle_find_by_description_regex, self.METHOD_FIND_BY_ID: self.handle_find_by_id, self.METHOD_FIND_BY_SINGLE_ID: self.handle_find_by_single_id, self.METHOD_FIND_BY_OWNER: self.handle_find_by_owner, self.METHOD_FIND_BY_PARTICIPANTS: self.handle_find_by_participants, self.METHOD_FIND_INVITATIONS: self.handle_find_invitations, self.METHOD_FIND_BY_SQL_QUERY: self.handle_find_by_sql_query, self.METHOD_LAUNCH_SESSION: self.handle_launch_session, self.METHOD_UPDATE_SESSION_URL: self.handle_update_session_url, self.METHOD_GET_SESSION_URL: self.handle_get_session_url, self.METHOD_GET_STATE: self.handle_get_state, self.METHOD_SET_STATE: self.handle_set_state, self.METHOD_REPORT_STATS: self.handle_report_stats, self.METHOD_GET_STATS: self.handle_get_stats, self.METHOD_DELETE_GATHERING: self.handle_delete_gathering, self.METHOD_GET_PENDING_DELETIONS: self.handle_get_pending_deletions, self.METHOD_DELETE_FROM_DELETIONS: self.handle_delete_from_deletions, self.METHOD_MIGRATE_GATHERING_OWNERSHIP_V1: self.handle_migrate_gathering_ownership_v1, self.METHOD_FIND_BY_DESCRIPTION_LIKE: self.handle_find_by_description_like, self.METHOD_REGISTER_LOCAL_URL: self.handle_register_local_url, self.METHOD_REGISTER_LOCAL_URLS: self.handle_register_local_urls, self.METHOD_UPDATE_SESSION_HOST_V1: self.handle_update_session_host_v1, self.METHOD_GET_SESSION_URLS: self.handle_get_session_urls, self.METHOD_UPDATE_SESSION_HOST: self.handle_update_session_host, self.METHOD_UPDATE_GATHERING_OWNERSHIP: self.handle_update_gathering_ownership, self.METHOD_MIGRATE_GATHERING_OWNERSHIP: self.handle_migrate_gathering_ownership, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on MatchMakingServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_register_gathering(self, client, input, output): logger.info("MatchMakingServer.register_gathering()") #--- request --- gathering = input.anydata() response = await self.register_gathering(client, gathering) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u32(response) async def handle_unregister_gathering(self, client, input, output): logger.info("MatchMakingServer.unregister_gathering()") #--- request --- gid = input.u32() response = await self.unregister_gathering(client, gid) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_unregister_gatherings(self, client, input, output): logger.info("MatchMakingServer.unregister_gatherings()") #--- request --- gids = input.list(input.u32) response = await self.unregister_gatherings(client, gids) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_update_gathering(self, client, input, output): logger.info("MatchMakingServer.update_gathering()") #--- request --- gathering = input.anydata() response = await self.update_gathering(client, gathering) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_invite(self, client, input, output): logger.info("MatchMakingServer.invite()") #--- request --- gid = input.u32() pids = input.list(input.pid) message = input.string() response = await self.invite(client, gid, pids, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_accept_invitation(self, client, input, output): logger.info("MatchMakingServer.accept_invitation()") #--- request --- gid = input.u32() message = input.string() response = await self.accept_invitation(client, gid, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_decline_invitation(self, client, input, output): logger.info("MatchMakingServer.decline_invitation()") #--- request --- gid = input.u32() message = input.string() response = await self.decline_invitation(client, gid, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_cancel_invitation(self, client, input, output): logger.info("MatchMakingServer.cancel_invitation()") #--- request --- gid = input.u32() pids = input.list(input.pid) message = input.string() response = await self.cancel_invitation(client, gid, pids, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_invitations_sent(self, client, input, output): logger.info("MatchMakingServer.get_invitations_sent()") #--- request --- gid = input.u32() response = await self.get_invitations_sent(client, gid) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_invitations_received(self, client, input, output): logger.info("MatchMakingServer.get_invitations_received()") #--- request --- response = await self.get_invitations_received(client) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_participate(self, client, input, output): logger.info("MatchMakingServer.participate()") #--- request --- gid = input.u32() message = input.string() response = await self.participate(client, gid, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_cancel_participation(self, client, input, output): logger.info("MatchMakingServer.cancel_participation()") #--- request --- gid = input.u32() message = input.string() response = await self.cancel_participation(client, gid, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_participants(self, client, input, output): logger.info("MatchMakingServer.get_participants()") #--- request --- gid = input.u32() response = await self.get_participants(client, gid) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.pid) async def handle_add_participants(self, client, input, output): logger.info("MatchMakingServer.add_participants()") #--- request --- gid = input.u32() pids = input.list(input.pid) message = input.string() response = await self.add_participants(client, gid, pids, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_detailed_participants(self, client, input, output): logger.info("MatchMakingServer.get_detailed_participants()") #--- request --- gid = input.u32() response = await self.get_detailed_participants(client, gid) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_participants_urls(self, client, input, output): logger.info("MatchMakingServer.get_participants_urls()") #--- request --- gid = input.u32() response = await self.get_participants_urls(client, gid) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.stationurl) async def handle_find_by_type(self, client, input, output): logger.info("MatchMakingServer.find_by_type()") #--- request --- type = input.string() range = input.extract(common.ResultRange) response = await self.find_by_type(client, type, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_description(self, client, input, output): logger.info("MatchMakingServer.find_by_description()") #--- request --- description = input.string() range = input.extract(common.ResultRange) response = await self.find_by_description(client, description, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_description_regex(self, client, input, output): logger.info("MatchMakingServer.find_by_description_regex()") #--- request --- regex = input.string() range = input.extract(common.ResultRange) response = await self.find_by_description_regex(client, regex, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_id(self, client, input, output): logger.info("MatchMakingServer.find_by_id()") #--- request --- ids = input.list(input.u32) response = await self.find_by_id(client, ids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_single_id(self, client, input, output): logger.info("MatchMakingServer.find_by_single_id()") #--- request --- gid = input.u32() response = await self.find_by_single_id(client, gid) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'gathering']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.anydata(response.gathering) async def handle_find_by_owner(self, client, input, output): logger.info("MatchMakingServer.find_by_owner()") #--- request --- owner = input.pid() range = input.extract(common.ResultRange) response = await self.find_by_owner(client, owner, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_participants(self, client, input, output): logger.info("MatchMakingServer.find_by_participants()") #--- request --- pids = input.list(input.pid) response = await self.find_by_participants(client, pids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_invitations(self, client, input, output): logger.info("MatchMakingServer.find_invitations()") #--- request --- range = input.extract(common.ResultRange) response = await self.find_invitations(client, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_sql_query(self, client, input, output): logger.info("MatchMakingServer.find_by_sql_query()") #--- request --- query = input.string() range = input.extract(common.ResultRange) response = await self.find_by_sql_query(client, query, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_launch_session(self, client, input, output): logger.info("MatchMakingServer.launch_session()") #--- request --- gid = input.u32() url = input.string() response = await self.launch_session(client, gid, url) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_update_session_url(self, client, input, output): logger.info("MatchMakingServer.update_session_url()") #--- request --- gid = input.u32() url = input.string() response = await self.update_session_url(client, gid, url) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_session_url(self, client, input, output): logger.info("MatchMakingServer.get_session_url()") #--- request --- gid = input.u32() response = await self.get_session_url(client, gid) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'url']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.string(response.url) async def handle_get_state(self, client, input, output): logger.info("MatchMakingServer.get_state()") #--- request --- gid = input.u32() response = await self.get_state(client, gid) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'state']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.u32(response.state) async def handle_set_state(self, client, input, output): logger.info("MatchMakingServer.set_state()") #--- request --- gid = input.u32() state = input.u32() response = await self.set_state(client, gid, state) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_report_stats(self, client, input, output): logger.info("MatchMakingServer.report_stats()") #--- request --- gid = input.u32() stats = input.list(GatheringStats) response = await self.report_stats(client, gid, stats) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_stats(self, client, input, output): logger.info("MatchMakingServer.get_stats()") #--- request --- gid = input.u32() pids = input.list(input.pid) columns = input.list(input.u8) response = await self.get_stats(client, gid, pids, columns) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'stats']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.list(response.stats, output.add) async def handle_delete_gathering(self, client, input, output): logger.info("MatchMakingServer.delete_gathering()") #--- request --- gid = input.u32() response = await self.delete_gathering(client, gid) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_pending_deletions(self, client, input, output): logger.info("MatchMakingServer.get_pending_deletions()") #--- request --- reason = input.u32() range = input.extract(common.ResultRange) response = await self.get_pending_deletions(client, reason, range) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'deletions']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.list(response.deletions, output.add) async def handle_delete_from_deletions(self, client, input, output): logger.info("MatchMakingServer.delete_from_deletions()") #--- request --- deletions = input.list(input.u32) response = await self.delete_from_deletions(client, deletions) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_migrate_gathering_ownership_v1(self, client, input, output): logger.info("MatchMakingServer.migrate_gathering_ownership_v1()") #--- request --- gid = input.u32() potential_owners = input.list(input.pid) response = await self.migrate_gathering_ownership_v1(client, gid, potential_owners) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_find_by_description_like(self, client, input, output): logger.info("MatchMakingServer.find_by_description_like()") #--- request --- description = input.string() range = input.extract(common.ResultRange) response = await self.find_by_description_like(client, description, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_register_local_url(self, client, input, output): logger.info("MatchMakingServer.register_local_url()") #--- request --- gid = input.u32() url = input.stationurl() await self.register_local_url(client, gid, url) async def handle_register_local_urls(self, client, input, output): logger.info("MatchMakingServer.register_local_urls()") #--- request --- gid = input.u32() urls = input.list(input.stationurl) await self.register_local_urls(client, gid, urls) async def handle_update_session_host_v1(self, client, input, output): logger.info("MatchMakingServer.update_session_host_v1()") #--- request --- gid = input.u32() await self.update_session_host_v1(client, gid) async def handle_get_session_urls(self, client, input, output): logger.info("MatchMakingServer.get_session_urls()") #--- request --- gid = input.u32() response = await self.get_session_urls(client, gid) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.stationurl) async def handle_update_session_host(self, client, input, output): logger.info("MatchMakingServer.update_session_host()") #--- request --- gid = input.u32() is_migrate_owner = input.bool() await self.update_session_host(client, gid, is_migrate_owner) async def handle_update_gathering_ownership(self, client, input, output): logger.info("MatchMakingServer.update_gathering_ownership()") #--- request --- gid = input.u32() participants_only = input.bool() response = await self.update_gathering_ownership(client, gid, participants_only) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_migrate_gathering_ownership(self, client, input, output): logger.info("MatchMakingServer.migrate_gathering_ownership()") #--- request --- gid = input.u32() potential_owners = input.list(input.pid) participants_only = input.bool() await self.migrate_gathering_ownership(client, gid, potential_owners, participants_only) async def register_gathering(self, *args): logger.warning("MatchMakingServer.register_gathering not implemented") raise common.RMCError("Core::NotImplemented") async def unregister_gathering(self, *args): logger.warning("MatchMakingServer.unregister_gathering not implemented") raise common.RMCError("Core::NotImplemented") async def unregister_gatherings(self, *args): logger.warning("MatchMakingServer.unregister_gatherings not implemented") raise common.RMCError("Core::NotImplemented") async def update_gathering(self, *args): logger.warning("MatchMakingServer.update_gathering not implemented") raise common.RMCError("Core::NotImplemented") async def invite(self, *args): logger.warning("MatchMakingServer.invite not implemented") raise common.RMCError("Core::NotImplemented") async def accept_invitation(self, *args): logger.warning("MatchMakingServer.accept_invitation not implemented") raise common.RMCError("Core::NotImplemented") async def decline_invitation(self, *args): logger.warning("MatchMakingServer.decline_invitation not implemented") raise common.RMCError("Core::NotImplemented") async def cancel_invitation(self, *args): logger.warning("MatchMakingServer.cancel_invitation not implemented") raise common.RMCError("Core::NotImplemented") async def get_invitations_sent(self, *args): logger.warning("MatchMakingServer.get_invitations_sent not implemented") raise common.RMCError("Core::NotImplemented") async def get_invitations_received(self, *args): logger.warning("MatchMakingServer.get_invitations_received not implemented") raise common.RMCError("Core::NotImplemented") async def participate(self, *args): logger.warning("MatchMakingServer.participate not implemented") raise common.RMCError("Core::NotImplemented") async def cancel_participation(self, *args): logger.warning("MatchMakingServer.cancel_participation not implemented") raise common.RMCError("Core::NotImplemented") async def get_participants(self, *args): logger.warning("MatchMakingServer.get_participants not implemented") raise common.RMCError("Core::NotImplemented") async def add_participants(self, *args): logger.warning("MatchMakingServer.add_participants not implemented") raise common.RMCError("Core::NotImplemented") async def get_detailed_participants(self, *args): logger.warning("MatchMakingServer.get_detailed_participants not implemented") raise common.RMCError("Core::NotImplemented") async def get_participants_urls(self, *args): logger.warning("MatchMakingServer.get_participants_urls not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_type(self, *args): logger.warning("MatchMakingServer.find_by_type not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_description(self, *args): logger.warning("MatchMakingServer.find_by_description not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_description_regex(self, *args): logger.warning("MatchMakingServer.find_by_description_regex not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_id(self, *args): logger.warning("MatchMakingServer.find_by_id not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_single_id(self, *args): logger.warning("MatchMakingServer.find_by_single_id not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_owner(self, *args): logger.warning("MatchMakingServer.find_by_owner not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_participants(self, *args): logger.warning("MatchMakingServer.find_by_participants not implemented") raise common.RMCError("Core::NotImplemented") async def find_invitations(self, *args): logger.warning("MatchMakingServer.find_invitations not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_sql_query(self, *args): logger.warning("MatchMakingServer.find_by_sql_query not implemented") raise common.RMCError("Core::NotImplemented") async def launch_session(self, *args): logger.warning("MatchMakingServer.launch_session not implemented") raise common.RMCError("Core::NotImplemented") async def update_session_url(self, *args): logger.warning("MatchMakingServer.update_session_url not implemented") raise common.RMCError("Core::NotImplemented") async def get_session_url(self, *args): logger.warning("MatchMakingServer.get_session_url not implemented") raise common.RMCError("Core::NotImplemented") async def get_state(self, *args): logger.warning("MatchMakingServer.get_state not implemented") raise common.RMCError("Core::NotImplemented") async def set_state(self, *args): logger.warning("MatchMakingServer.set_state not implemented") raise common.RMCError("Core::NotImplemented") async def report_stats(self, *args): logger.warning("MatchMakingServer.report_stats not implemented") raise common.RMCError("Core::NotImplemented") async def get_stats(self, *args): logger.warning("MatchMakingServer.get_stats not implemented") raise common.RMCError("Core::NotImplemented") async def delete_gathering(self, *args): logger.warning("MatchMakingServer.delete_gathering not implemented") raise common.RMCError("Core::NotImplemented") async def get_pending_deletions(self, *args): logger.warning("MatchMakingServer.get_pending_deletions not implemented") raise common.RMCError("Core::NotImplemented") async def delete_from_deletions(self, *args): logger.warning("MatchMakingServer.delete_from_deletions not implemented") raise common.RMCError("Core::NotImplemented") async def migrate_gathering_ownership_v1(self, *args): logger.warning("MatchMakingServer.migrate_gathering_ownership_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_description_like(self, *args): logger.warning("MatchMakingServer.find_by_description_like not implemented") raise common.RMCError("Core::NotImplemented") async def register_local_url(self, *args): logger.warning("MatchMakingServer.register_local_url not implemented") raise common.RMCError("Core::NotImplemented") async def register_local_urls(self, *args): logger.warning("MatchMakingServer.register_local_urls not implemented") raise common.RMCError("Core::NotImplemented") async def update_session_host_v1(self, *args): logger.warning("MatchMakingServer.update_session_host_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def get_session_urls(self, *args): logger.warning("MatchMakingServer.get_session_urls not implemented") raise common.RMCError("Core::NotImplemented") async def update_session_host(self, *args): logger.warning("MatchMakingServer.update_session_host not implemented") raise common.RMCError("Core::NotImplemented") async def update_gathering_ownership(self, *args): logger.warning("MatchMakingServer.update_gathering_ownership not implemented") raise common.RMCError("Core::NotImplemented") async def migrate_gathering_ownership(self, *args): logger.warning("MatchMakingServer.migrate_gathering_ownership not implemented") raise common.RMCError("Core::NotImplemented") class MatchMakingServerExt(MatchMakingProtocolExt): def __init__(self): self.methods = { self.METHOD_END_PARTICIPATION: self.handle_end_participation, self.METHOD_GET_PARTICIPANTS: self.handle_get_participants, self.METHOD_GET_DETAILED_PARTICIPANTS: self.handle_get_detailed_participants, self.METHOD_GET_PARTICIPANTS_URLS: self.handle_get_participants_urls, self.METHOD_GET_GATHERING_RELATIONS: self.handle_get_gathering_relations, self.METHOD_DELETE_FROM_DELETIONS: self.handle_delete_from_deletions, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on MatchMakingServerExt: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_end_participation(self, client, input, output): logger.info("MatchMakingServerExt.end_participation()") #--- request --- gid = input.u32() message = input.string() response = await self.end_participation(client, gid, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_participants(self, client, input, output): logger.info("MatchMakingServerExt.get_participants()") #--- request --- gid = input.u32() only_active = input.bool() response = await self.get_participants(client, gid, only_active) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.pid) async def handle_get_detailed_participants(self, client, input, output): logger.info("MatchMakingServerExt.get_detailed_participants()") #--- request --- gid = input.u32() only_active = input.bool() response = await self.get_detailed_participants(client, gid, only_active) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_participants_urls(self, client, input, output): logger.info("MatchMakingServerExt.get_participants_urls()") #--- request --- gids = input.list(input.u32) response = await self.get_participants_urls(client, gids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_gathering_relations(self, client, input, output): logger.info("MatchMakingServerExt.get_gathering_relations()") #--- request --- id = input.u32() descr = input.string() response = await self.get_gathering_relations(client, id, descr) #--- response --- if not isinstance(response, str): raise RuntimeError("Expected str, got %s" %response.__class__.__name__) output.string(response) async def handle_delete_from_deletions(self, client, input, output): logger.info("MatchMakingServerExt.delete_from_deletions()") #--- request --- deletions = input.list(input.u32) pid = input.pid() await self.delete_from_deletions(client, deletions, pid) async def end_participation(self, *args): logger.warning("MatchMakingServerExt.end_participation not implemented") raise common.RMCError("Core::NotImplemented") async def get_participants(self, *args): logger.warning("MatchMakingServerExt.get_participants not implemented") raise common.RMCError("Core::NotImplemented") async def get_detailed_participants(self, *args): logger.warning("MatchMakingServerExt.get_detailed_participants not implemented") raise common.RMCError("Core::NotImplemented") async def get_participants_urls(self, *args): logger.warning("MatchMakingServerExt.get_participants_urls not implemented") raise common.RMCError("Core::NotImplemented") async def get_gathering_relations(self, *args): logger.warning("MatchMakingServerExt.get_gathering_relations not implemented") raise common.RMCError("Core::NotImplemented") async def delete_from_deletions(self, *args): logger.warning("MatchMakingServerExt.delete_from_deletions not implemented") raise common.RMCError("Core::NotImplemented") class MatchmakeRefereeServer(MatchmakeRefereeProtocol): def __init__(self): self.methods = { self.METHOD_START_ROUND: self.handle_start_round, self.METHOD_GET_START_ROUND_PARAM: self.handle_get_start_round_param, self.METHOD_END_ROUND: self.handle_end_round, self.METHOD_END_ROUND_WITHOUT_REPORT: self.handle_end_round_without_report, self.METHOD_GET_ROUND_PARTICIPANTS: self.handle_get_round_participants, self.METHOD_GET_NOT_SUMMARIZED_ROUND: self.handle_get_not_summarized_round, self.METHOD_GET_ROUND: self.handle_get_round, self.METHOD_GET_STATS_PRIMARY: self.handle_get_stats_primary, self.METHOD_GET_STATS_PRIMARIES: self.handle_get_stats_primaries, self.METHOD_GET_STATS_ALL: self.handle_get_stats_all, self.METHOD_CREATE_STATS: self.handle_create_stats, self.METHOD_GET_OR_CREATE_STATS: self.handle_get_or_create_stats, self.METHOD_RESET_STATS: self.handle_reset_stats, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on MatchmakeRefereeServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_start_round(self, client, input, output): logger.info("MatchmakeRefereeServer.start_round()") #--- request --- param = input.extract(MatchmakeRefereeStartRoundParam) response = await self.start_round(client, param) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u64(response) async def handle_get_start_round_param(self, client, input, output): logger.info("MatchmakeRefereeServer.get_start_round_param()") #--- request --- round_id = input.u64() response = await self.get_start_round_param(client, round_id) #--- response --- if not isinstance(response, MatchmakeRefereeStartRoundParam): raise RuntimeError("Expected MatchmakeRefereeStartRoundParam, got %s" %response.__class__.__name__) output.add(response) async def handle_end_round(self, client, input, output): logger.info("MatchmakeRefereeServer.end_round()") #--- request --- param = input.extract(MatchmakeRefereeEndRoundParam) await self.end_round(client, param) async def handle_end_round_without_report(self, client, input, output): logger.info("MatchmakeRefereeServer.end_round_without_report()") #--- request --- round_id = input.u64() await self.end_round_without_report(client, round_id) async def handle_get_round_participants(self, client, input, output): logger.info("MatchmakeRefereeServer.get_round_participants()") #--- request --- round_id = input.u64() response = await self.get_round_participants(client, round_id) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.pid) async def handle_get_not_summarized_round(self, client, input, output): logger.info("MatchmakeRefereeServer.get_not_summarized_round()") #--- request --- response = await self.get_not_summarized_round(client) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_round(self, client, input, output): logger.info("MatchmakeRefereeServer.get_round()") #--- request --- round = input.u64() response = await self.get_round(client, round) #--- response --- if not isinstance(response, MatchmakeRefereeRound): raise RuntimeError("Expected MatchmakeRefereeRound, got %s" %response.__class__.__name__) output.add(response) async def handle_get_stats_primary(self, client, input, output): logger.info("MatchmakeRefereeServer.get_stats_primary()") #--- request --- target = input.extract(MatchmakeRefereeStatsTarget) response = await self.get_stats_primary(client, target) #--- response --- if not isinstance(response, MatchmakeRefereeStats): raise RuntimeError("Expected MatchmakeRefereeStats, got %s" %response.__class__.__name__) output.add(response) async def handle_get_stats_primaries(self, client, input, output): logger.info("MatchmakeRefereeServer.get_stats_primaries()") #--- request --- targets = input.list(MatchmakeRefereeStatsTarget) response = await self.get_stats_primaries(client, targets) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['stats', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.stats, output.add) output.list(response.results, output.result) async def handle_get_stats_all(self, client, input, output): logger.info("MatchmakeRefereeServer.get_stats_all()") #--- request --- target = input.extract(MatchmakeRefereeStatsTarget) response = await self.get_stats_all(client, target) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_create_stats(self, client, input, output): logger.info("MatchmakeRefereeServer.create_stats()") #--- request --- param = input.extract(MatchmakeRefereeStatsInitParam) response = await self.create_stats(client, param) #--- response --- if not isinstance(response, MatchmakeRefereeStats): raise RuntimeError("Expected MatchmakeRefereeStats, got %s" %response.__class__.__name__) output.add(response) async def handle_get_or_create_stats(self, client, input, output): logger.info("MatchmakeRefereeServer.get_or_create_stats()") #--- request --- param = input.extract(MatchmakeRefereeStatsInitParam) response = await self.get_or_create_stats(client, param) #--- response --- if not isinstance(response, MatchmakeRefereeStats): raise RuntimeError("Expected MatchmakeRefereeStats, got %s" %response.__class__.__name__) output.add(response) async def handle_reset_stats(self, client, input, output): logger.info("MatchmakeRefereeServer.reset_stats()") #--- request --- await self.reset_stats(client) async def start_round(self, *args): logger.warning("MatchmakeRefereeServer.start_round not implemented") raise common.RMCError("Core::NotImplemented") async def get_start_round_param(self, *args): logger.warning("MatchmakeRefereeServer.get_start_round_param not implemented") raise common.RMCError("Core::NotImplemented") async def end_round(self, *args): logger.warning("MatchmakeRefereeServer.end_round not implemented") raise common.RMCError("Core::NotImplemented") async def end_round_without_report(self, *args): logger.warning("MatchmakeRefereeServer.end_round_without_report not implemented") raise common.RMCError("Core::NotImplemented") async def get_round_participants(self, *args): logger.warning("MatchmakeRefereeServer.get_round_participants not implemented") raise common.RMCError("Core::NotImplemented") async def get_not_summarized_round(self, *args): logger.warning("MatchmakeRefereeServer.get_not_summarized_round not implemented") raise common.RMCError("Core::NotImplemented") async def get_round(self, *args): logger.warning("MatchmakeRefereeServer.get_round not implemented") raise common.RMCError("Core::NotImplemented") async def get_stats_primary(self, *args): logger.warning("MatchmakeRefereeServer.get_stats_primary not implemented") raise common.RMCError("Core::NotImplemented") async def get_stats_primaries(self, *args): logger.warning("MatchmakeRefereeServer.get_stats_primaries not implemented") raise common.RMCError("Core::NotImplemented") async def get_stats_all(self, *args): logger.warning("MatchmakeRefereeServer.get_stats_all not implemented") raise common.RMCError("Core::NotImplemented") async def create_stats(self, *args): logger.warning("MatchmakeRefereeServer.create_stats not implemented") raise common.RMCError("Core::NotImplemented") async def get_or_create_stats(self, *args): logger.warning("MatchmakeRefereeServer.get_or_create_stats not implemented") raise common.RMCError("Core::NotImplemented") async def reset_stats(self, *args): logger.warning("MatchmakeRefereeServer.reset_stats not implemented") raise common.RMCError("Core::NotImplemented") class MatchmakeExtensionServerMK8(MatchmakeExtensionProtocolMK8): def __init__(self): self.methods = { self.METHOD_CLOSE_PARTICIPATION: self.handle_close_participation, self.METHOD_OPEN_PARTICIPATION: self.handle_open_participation, self.METHOD_AUTO_MATCHMAKE_POSTPONE: self.handle_auto_matchmake_postpone, self.METHOD_BROWSE_MATCHMAKE_SESSION: self.handle_browse_matchmake_session, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS: self.handle_browse_matchmake_session_with_host_urls, self.METHOD_CREATE_MATCHMAKE_SESSION: self.handle_create_matchmake_session, self.METHOD_JOIN_MATCHMAKE_SESSION: self.handle_join_matchmake_session, self.METHOD_MODIFY_CURRENT_GAME_ATTRIBUTE: self.handle_modify_current_game_attribute, self.METHOD_UPDATE_NOTIFICATION_DATA: self.handle_update_notification_data, self.METHOD_GET_FRIEND_NOTIFICATION_DATA: self.handle_get_friend_notification_data, self.METHOD_UPDATE_APPLICATION_BUFFER: self.handle_update_application_buffer, self.METHOD_UPDATE_MATCHMAKE_SESSION_ATTRIBUTE: self.handle_update_matchmake_session_attribute, self.METHOD_GET_FRIEND_NOTIFICATION_DATA_LIST: self.handle_get_friend_notification_data_list, self.METHOD_UPDATE_MATCHMAKE_SESSION: self.handle_update_matchmake_session, self.METHOD_AUTO_MATCHMAKE_WITH_SEARCH_CRITERIA_POSTPONE: self.handle_auto_matchmake_with_search_criteria_postpone, self.METHOD_GET_PLAYING_SESSION: self.handle_get_playing_session, self.METHOD_CREATE_COMMUNITY: self.handle_create_community, self.METHOD_UPDATE_COMMUNITY: self.handle_update_community, self.METHOD_JOIN_COMMUNITY: self.handle_join_community, self.METHOD_FIND_COMMUNITY_BY_GATHERING_ID: self.handle_find_community_by_gathering_id, self.METHOD_FIND_OFFICIAL_COMMUNITY: self.handle_find_official_community, self.METHOD_FIND_COMMUNITY_BY_PARTICIPANT: self.handle_find_community_by_participant, self.METHOD_UPDATE_PRIVACY_SETTING: self.handle_update_privacy_setting, self.METHOD_GET_MY_BLOCK_LIST: self.handle_get_my_block_list, self.METHOD_ADD_TO_BLOCK_LIST: self.handle_add_to_block_list, self.METHOD_REMOVE_FROM_BLOCK_LIST: self.handle_remove_from_block_list, self.METHOD_CLEAR_MY_BLOCK_LIST: self.handle_clear_my_block_list, self.METHOD_REPORT_VIOLATION: self.handle_report_violation, self.METHOD_IS_VIOLATION_USER: self.handle_is_violation_user, self.METHOD_JOIN_MATCHMAKE_SESSION_EX: self.handle_join_matchmake_session_ex, self.METHOD_GET_SIMPLE_PLAYING_SESSION: self.handle_get_simple_playing_session, self.METHOD_GET_SIMPLE_COMMUNITY: self.handle_get_simple_community, self.METHOD_AUTO_MATCHMAKE_WITH_GATHERING_ID_POSTPONE: self.handle_auto_matchmake_with_gathering_id_postpone, self.METHOD_UPDATE_PROGRESS_SCORE: self.handle_update_progress_score, self.METHOD_DEBUG_NOTIFY_EVENT: self.handle_debug_notify_event, self.METHOD_CREATE_SIMPLE_SEARCH_OBJECT: self.handle_create_simple_search_object, self.METHOD_UPDATE_SIMPLE_SEARCH_OBJECT: self.handle_update_simple_search_object, self.METHOD_DELETE_SIMPLE_SEARCH_OBJECT: self.handle_delete_simple_search_object, self.METHOD_SEARCH_SIMPLE_SEARCH_OBJECT: self.handle_search_simple_search_object, self.METHOD_JOIN_MATCHMAKE_SESSION_WITH_EXTRA_PARTICIPANTS: self.handle_join_matchmake_session_with_extra_participants, self.METHOD_SEARCH_SIMPLE_SEARCH_OBJECT_BY_OBJECT_IDS: self.handle_search_simple_search_object_by_object_ids, self.METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER: self.handle_browse_matchmake_session_no_holder, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER: self.handle_browse_matchmake_session_with_host_urls_no_holder, self.METHOD_UPDATE_MATCHMAKE_SESSION_PART: self.handle_update_matchmake_session_part, self.METHOD_REQUEST_MATCHMAKING: self.handle_request_matchmaking, self.METHOD_WITHDRAW_MATCHMAKING: self.handle_withdraw_matchmaking, self.METHOD_WITHDRAW_MATCHMAKING_ALL: self.handle_withdraw_matchmaking_all, self.METHOD_FIND_MATCHMAKE_SESSION_BY_GATHERING_ID: self.handle_find_matchmake_session_by_gathering_id, self.METHOD_FIND_MATCHMAKE_SESSION_BY_SINGLE_GATHERING_ID: self.handle_find_matchmake_session_by_single_gathering_id, self.METHOD_FIND_MATCHMAKE_SESSION_BY_OWNER: self.handle_find_matchmake_session_by_owner, self.METHOD_FIND_MATCHMAKE_SESSION_BY_PARTICIPANT: self.handle_find_matchmake_session_by_participant, self.METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER_NO_RESULT_RANGE: self.handle_browse_matchmake_session_no_holder_no_result_range, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER_NO_RESULT_RANGE: self.handle_browse_matchmake_session_with_host_urls_no_holder_no_result_range, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on MatchmakeExtensionServerMK8: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_close_participation(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.close_participation()") #--- request --- gid = input.u32() await self.close_participation(client, gid) async def handle_open_participation(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.open_participation()") #--- request --- gid = input.u32() await self.open_participation(client, gid) async def handle_auto_matchmake_postpone(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.auto_matchmake_postpone()") #--- request --- gathering = input.anydata() message = input.string() response = await self.auto_matchmake_postpone(client, gathering, message) #--- response --- if not isinstance(response, Gathering): raise RuntimeError("Expected Gathering, got %s" %response.__class__.__name__) output.anydata(response) async def handle_browse_matchmake_session(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.browse_matchmake_session()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) range = input.extract(common.ResultRange) response = await self.browse_matchmake_session(client, search_criteria, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_browse_matchmake_session_with_host_urls(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.browse_matchmake_session_with_host_urls()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) range = input.extract(common.ResultRange) response = await self.browse_matchmake_session_with_host_urls(client, search_criteria, range) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['gatherings', 'urls']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.gatherings, output.anydata) output.list(response.urls, output.add) async def handle_create_matchmake_session(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.create_matchmake_session()") #--- request --- gathering = input.anydata() description = input.string() num_participants = input.u16() response = await self.create_matchmake_session(client, gathering, description, num_participants) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['gid', 'session_key']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.u32(response.gid) output.buffer(response.session_key) async def handle_join_matchmake_session(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.join_matchmake_session()") #--- request --- gid = input.u32() message = input.string() response = await self.join_matchmake_session(client, gid, message) #--- response --- if not isinstance(response, bytes): raise RuntimeError("Expected bytes, got %s" %response.__class__.__name__) output.buffer(response) async def handle_modify_current_game_attribute(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.modify_current_game_attribute()") #--- request --- gid = input.u32() attrib = input.u32() value = input.u32() await self.modify_current_game_attribute(client, gid, attrib, value) async def handle_update_notification_data(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.update_notification_data()") #--- request --- type = input.u32() param1 = input.pid() param2 = input.pid() param3 = input.string() await self.update_notification_data(client, type, param1, param2, param3) async def handle_get_friend_notification_data(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.get_friend_notification_data()") #--- request --- type = input.s32() response = await self.get_friend_notification_data(client, type) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_update_application_buffer(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.update_application_buffer()") #--- request --- gid = input.u32() buffer = input.buffer() await self.update_application_buffer(client, gid, buffer) async def handle_update_matchmake_session_attribute(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.update_matchmake_session_attribute()") #--- request --- gid = input.u32() attribs = input.list(input.u32) await self.update_matchmake_session_attribute(client, gid, attribs) async def handle_get_friend_notification_data_list(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.get_friend_notification_data_list()") #--- request --- types = input.list(input.u32) response = await self.get_friend_notification_data_list(client, types) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_update_matchmake_session(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.update_matchmake_session()") #--- request --- gathering = input.anydata() await self.update_matchmake_session(client, gathering) async def handle_auto_matchmake_with_search_criteria_postpone(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.auto_matchmake_with_search_criteria_postpone()") #--- request --- search_criteria = input.list(MatchmakeSessionSearchCriteria) gathering = input.anydata() message = input.string() response = await self.auto_matchmake_with_search_criteria_postpone(client, search_criteria, gathering, message) #--- response --- if not isinstance(response, Gathering): raise RuntimeError("Expected Gathering, got %s" %response.__class__.__name__) output.anydata(response) async def handle_get_playing_session(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.get_playing_session()") #--- request --- pids = input.list(input.pid) response = await self.get_playing_session(client, pids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_create_community(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.create_community()") #--- request --- community = input.extract(PersistentGathering) message = input.string() response = await self.create_community(client, community, message) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u32(response) async def handle_update_community(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.update_community()") #--- request --- community = input.extract(PersistentGathering) await self.update_community(client, community) async def handle_join_community(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.join_community()") #--- request --- gid = input.u32() message = input.string() password = input.string() await self.join_community(client, gid, message, password) async def handle_find_community_by_gathering_id(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.find_community_by_gathering_id()") #--- request --- gids = input.list(input.u32) response = await self.find_community_by_gathering_id(client, gids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_find_official_community(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.find_official_community()") #--- request --- available_only = input.bool() range = input.extract(common.ResultRange) response = await self.find_official_community(client, available_only, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_find_community_by_participant(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.find_community_by_participant()") #--- request --- pid = input.pid() range = input.extract(common.ResultRange) response = await self.find_community_by_participant(client, pid, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_update_privacy_setting(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.update_privacy_setting()") #--- request --- online_status = input.bool() community_participation = input.bool() await self.update_privacy_setting(client, online_status, community_participation) async def handle_get_my_block_list(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.get_my_block_list()") #--- request --- response = await self.get_my_block_list(client) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.pid) async def handle_add_to_block_list(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.add_to_block_list()") #--- request --- pids = input.list(input.pid) await self.add_to_block_list(client, pids) async def handle_remove_from_block_list(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.remove_from_block_list()") #--- request --- pids = input.list(input.pid) await self.remove_from_block_list(client, pids) async def handle_clear_my_block_list(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.clear_my_block_list()") #--- request --- await self.clear_my_block_list(client) async def handle_report_violation(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.report_violation()") #--- request --- pid = input.pid() username = input.string() violation_code = input.u32() await self.report_violation(client, pid, username, violation_code) async def handle_is_violation_user(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.is_violation_user()") #--- request --- response = await self.is_violation_user(client) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['flag', 'score']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.flag) output.u32(response.score) async def handle_join_matchmake_session_ex(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.join_matchmake_session_ex()") #--- request --- gid = input.u32() gmessage = input.string() ignore_block_list = input.bool() num_participants = input.u16() response = await self.join_matchmake_session_ex(client, gid, gmessage, ignore_block_list, num_participants) #--- response --- if not isinstance(response, bytes): raise RuntimeError("Expected bytes, got %s" %response.__class__.__name__) output.buffer(response) async def handle_get_simple_playing_session(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.get_simple_playing_session()") #--- request --- pids = input.list(input.pid) include_login_user = input.bool() response = await self.get_simple_playing_session(client, pids, include_login_user) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_simple_community(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.get_simple_community()") #--- request --- gids = input.list(input.u32) response = await self.get_simple_community(client, gids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_auto_matchmake_with_gathering_id_postpone(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.auto_matchmake_with_gathering_id_postpone()") #--- request --- gids = input.list(input.u32) gathering = input.anydata() message = input.string() response = await self.auto_matchmake_with_gathering_id_postpone(client, gids, gathering, message) #--- response --- if not isinstance(response, Gathering): raise RuntimeError("Expected Gathering, got %s" %response.__class__.__name__) output.anydata(response) async def handle_update_progress_score(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.update_progress_score()") #--- request --- gid = input.u32() score = input.u8() await self.update_progress_score(client, gid, score) async def handle_debug_notify_event(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.debug_notify_event()") #--- request --- pid = input.pid() main_type = input.u32() sub_type = input.u32() param1 = input.u64() param2 = input.u64() param3 = input.string() await self.debug_notify_event(client, pid, main_type, sub_type, param1, param2, param3) async def handle_create_simple_search_object(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.create_simple_search_object()") #--- request --- object = input.extract(SimpleSearchObject) response = await self.create_simple_search_object(client, object) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u32(response) async def handle_update_simple_search_object(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.update_simple_search_object()") #--- request --- id = input.u32() object = input.extract(SimpleSearchObject) await self.update_simple_search_object(client, id, object) async def handle_delete_simple_search_object(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.delete_simple_search_object()") #--- request --- id = input.u32() await self.delete_simple_search_object(client, id) async def handle_search_simple_search_object(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.search_simple_search_object()") #--- request --- param = input.extract(SimpleSearchParam) response = await self.search_simple_search_object(client, param) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_join_matchmake_session_with_extra_participants(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.join_matchmake_session_with_extra_participants()") #--- request --- gid = input.u32() join_message = input.string() ignore_blacklist = input.bool() participation_count = input.u16() extra_participants = input.u32() response = await self.join_matchmake_session_with_extra_participants(client, gid, join_message, ignore_blacklist, participation_count, extra_participants) #--- response --- if not isinstance(response, bytes): raise RuntimeError("Expected bytes, got %s" %response.__class__.__name__) output.buffer(response) async def handle_search_simple_search_object_by_object_ids(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.search_simple_search_object_by_object_ids()") #--- request --- ids = input.list(input.u32) response = await self.search_simple_search_object_by_object_ids(client, ids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_browse_matchmake_session_no_holder(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.browse_matchmake_session_no_holder()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) range = input.extract(common.ResultRange) response = await self.browse_matchmake_session_no_holder(client, search_criteria, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_browse_matchmake_session_with_host_urls_no_holder(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.browse_matchmake_session_with_host_urls_no_holder()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) range = input.extract(common.ResultRange) response = await self.browse_matchmake_session_with_host_urls_no_holder(client, search_criteria, range) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['sessions', 'urls']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.sessions, output.add) output.list(response.urls, output.add) async def handle_update_matchmake_session_part(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.update_matchmake_session_part()") #--- request --- param = input.extract(UpdateMatchmakeSessionParam) await self.update_matchmake_session_part(client, param) async def handle_request_matchmaking(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.request_matchmaking()") #--- request --- param = input.extract(AutoMatchmakeParam) response = await self.request_matchmaking(client, param) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u64(response) async def handle_withdraw_matchmaking(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.withdraw_matchmaking()") #--- request --- request_id = input.u64() await self.withdraw_matchmaking(client, request_id) async def handle_withdraw_matchmaking_all(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.withdraw_matchmaking_all()") #--- request --- await self.withdraw_matchmaking_all(client) async def handle_find_matchmake_session_by_gathering_id(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.find_matchmake_session_by_gathering_id()") #--- request --- gids = input.list(input.u32) response = await self.find_matchmake_session_by_gathering_id(client, gids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_find_matchmake_session_by_single_gathering_id(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.find_matchmake_session_by_single_gathering_id()") #--- request --- gid = input.u32() response = await self.find_matchmake_session_by_single_gathering_id(client, gid) #--- response --- if not isinstance(response, MatchmakeSession): raise RuntimeError("Expected MatchmakeSession, got %s" %response.__class__.__name__) output.add(response) async def handle_find_matchmake_session_by_owner(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.find_matchmake_session_by_owner()") #--- request --- pid = input.pid() range = input.extract(common.ResultRange) response = await self.find_matchmake_session_by_owner(client, pid, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_find_matchmake_session_by_participant(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.find_matchmake_session_by_participant()") #--- request --- param = input.extract(FindMatchmakeSessionByParticipantParam) response = await self.find_matchmake_session_by_participant(client, param) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_browse_matchmake_session_no_holder_no_result_range(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.browse_matchmake_session_no_holder_no_result_range()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) response = await self.browse_matchmake_session_no_holder_no_result_range(client, search_criteria) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_browse_matchmake_session_with_host_urls_no_holder_no_result_range(self, client, input, output): logger.info("MatchmakeExtensionServerMK8.browse_matchmake_session_with_host_urls_no_holder_no_result_range()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) response = await self.browse_matchmake_session_with_host_urls_no_holder_no_result_range(client, search_criteria) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['sessions', 'urls']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.sessions, output.add) output.list(response.urls, output.add) async def close_participation(self, *args): logger.warning("MatchmakeExtensionServerMK8.close_participation not implemented") raise common.RMCError("Core::NotImplemented") async def open_participation(self, *args): logger.warning("MatchmakeExtensionServerMK8.open_participation not implemented") raise common.RMCError("Core::NotImplemented") async def auto_matchmake_postpone(self, *args): logger.warning("MatchmakeExtensionServerMK8.auto_matchmake_postpone not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session(self, *args): logger.warning("MatchmakeExtensionServerMK8.browse_matchmake_session not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session_with_host_urls(self, *args): logger.warning("MatchmakeExtensionServerMK8.browse_matchmake_session_with_host_urls not implemented") raise common.RMCError("Core::NotImplemented") async def create_matchmake_session(self, *args): logger.warning("MatchmakeExtensionServerMK8.create_matchmake_session not implemented") raise common.RMCError("Core::NotImplemented") async def join_matchmake_session(self, *args): logger.warning("MatchmakeExtensionServerMK8.join_matchmake_session not implemented") raise common.RMCError("Core::NotImplemented") async def modify_current_game_attribute(self, *args): logger.warning("MatchmakeExtensionServerMK8.modify_current_game_attribute not implemented") raise common.RMCError("Core::NotImplemented") async def update_notification_data(self, *args): logger.warning("MatchmakeExtensionServerMK8.update_notification_data not implemented") raise common.RMCError("Core::NotImplemented") async def get_friend_notification_data(self, *args): logger.warning("MatchmakeExtensionServerMK8.get_friend_notification_data not implemented") raise common.RMCError("Core::NotImplemented") async def update_application_buffer(self, *args): logger.warning("MatchmakeExtensionServerMK8.update_application_buffer not implemented") raise common.RMCError("Core::NotImplemented") async def update_matchmake_session_attribute(self, *args): logger.warning("MatchmakeExtensionServerMK8.update_matchmake_session_attribute not implemented") raise common.RMCError("Core::NotImplemented") async def get_friend_notification_data_list(self, *args): logger.warning("MatchmakeExtensionServerMK8.get_friend_notification_data_list not implemented") raise common.RMCError("Core::NotImplemented") async def update_matchmake_session(self, *args): logger.warning("MatchmakeExtensionServerMK8.update_matchmake_session not implemented") raise common.RMCError("Core::NotImplemented") async def auto_matchmake_with_search_criteria_postpone(self, *args): logger.warning("MatchmakeExtensionServerMK8.auto_matchmake_with_search_criteria_postpone not implemented") raise common.RMCError("Core::NotImplemented") async def get_playing_session(self, *args): logger.warning("MatchmakeExtensionServerMK8.get_playing_session not implemented") raise common.RMCError("Core::NotImplemented") async def create_community(self, *args): logger.warning("MatchmakeExtensionServerMK8.create_community not implemented") raise common.RMCError("Core::NotImplemented") async def update_community(self, *args): logger.warning("MatchmakeExtensionServerMK8.update_community not implemented") raise common.RMCError("Core::NotImplemented") async def join_community(self, *args): logger.warning("MatchmakeExtensionServerMK8.join_community not implemented") raise common.RMCError("Core::NotImplemented") async def find_community_by_gathering_id(self, *args): logger.warning("MatchmakeExtensionServerMK8.find_community_by_gathering_id not implemented") raise common.RMCError("Core::NotImplemented") async def find_official_community(self, *args): logger.warning("MatchmakeExtensionServerMK8.find_official_community not implemented") raise common.RMCError("Core::NotImplemented") async def find_community_by_participant(self, *args): logger.warning("MatchmakeExtensionServerMK8.find_community_by_participant not implemented") raise common.RMCError("Core::NotImplemented") async def update_privacy_setting(self, *args): logger.warning("MatchmakeExtensionServerMK8.update_privacy_setting not implemented") raise common.RMCError("Core::NotImplemented") async def get_my_block_list(self, *args): logger.warning("MatchmakeExtensionServerMK8.get_my_block_list not implemented") raise common.RMCError("Core::NotImplemented") async def add_to_block_list(self, *args): logger.warning("MatchmakeExtensionServerMK8.add_to_block_list not implemented") raise common.RMCError("Core::NotImplemented") async def remove_from_block_list(self, *args): logger.warning("MatchmakeExtensionServerMK8.remove_from_block_list not implemented") raise common.RMCError("Core::NotImplemented") async def clear_my_block_list(self, *args): logger.warning("MatchmakeExtensionServerMK8.clear_my_block_list not implemented") raise common.RMCError("Core::NotImplemented") async def report_violation(self, *args): logger.warning("MatchmakeExtensionServerMK8.report_violation not implemented") raise common.RMCError("Core::NotImplemented") async def is_violation_user(self, *args): logger.warning("MatchmakeExtensionServerMK8.is_violation_user not implemented") raise common.RMCError("Core::NotImplemented") async def join_matchmake_session_ex(self, *args): logger.warning("MatchmakeExtensionServerMK8.join_matchmake_session_ex not implemented") raise common.RMCError("Core::NotImplemented") async def get_simple_playing_session(self, *args): logger.warning("MatchmakeExtensionServerMK8.get_simple_playing_session not implemented") raise common.RMCError("Core::NotImplemented") async def get_simple_community(self, *args): logger.warning("MatchmakeExtensionServerMK8.get_simple_community not implemented") raise common.RMCError("Core::NotImplemented") async def auto_matchmake_with_gathering_id_postpone(self, *args): logger.warning("MatchmakeExtensionServerMK8.auto_matchmake_with_gathering_id_postpone not implemented") raise common.RMCError("Core::NotImplemented") async def update_progress_score(self, *args): logger.warning("MatchmakeExtensionServerMK8.update_progress_score not implemented") raise common.RMCError("Core::NotImplemented") async def debug_notify_event(self, *args): logger.warning("MatchmakeExtensionServerMK8.debug_notify_event not implemented") raise common.RMCError("Core::NotImplemented") async def create_simple_search_object(self, *args): logger.warning("MatchmakeExtensionServerMK8.create_simple_search_object not implemented") raise common.RMCError("Core::NotImplemented") async def update_simple_search_object(self, *args): logger.warning("MatchmakeExtensionServerMK8.update_simple_search_object not implemented") raise common.RMCError("Core::NotImplemented") async def delete_simple_search_object(self, *args): logger.warning("MatchmakeExtensionServerMK8.delete_simple_search_object not implemented") raise common.RMCError("Core::NotImplemented") async def search_simple_search_object(self, *args): logger.warning("MatchmakeExtensionServerMK8.search_simple_search_object not implemented") raise common.RMCError("Core::NotImplemented") async def join_matchmake_session_with_extra_participants(self, *args): logger.warning("MatchmakeExtensionServerMK8.join_matchmake_session_with_extra_participants not implemented") raise common.RMCError("Core::NotImplemented") async def search_simple_search_object_by_object_ids(self, *args): logger.warning("MatchmakeExtensionServerMK8.search_simple_search_object_by_object_ids not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session_no_holder(self, *args): logger.warning("MatchmakeExtensionServerMK8.browse_matchmake_session_no_holder not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session_with_host_urls_no_holder(self, *args): logger.warning("MatchmakeExtensionServerMK8.browse_matchmake_session_with_host_urls_no_holder not implemented") raise common.RMCError("Core::NotImplemented") async def update_matchmake_session_part(self, *args): logger.warning("MatchmakeExtensionServerMK8.update_matchmake_session_part not implemented") raise common.RMCError("Core::NotImplemented") async def request_matchmaking(self, *args): logger.warning("MatchmakeExtensionServerMK8.request_matchmaking not implemented") raise common.RMCError("Core::NotImplemented") async def withdraw_matchmaking(self, *args): logger.warning("MatchmakeExtensionServerMK8.withdraw_matchmaking not implemented") raise common.RMCError("Core::NotImplemented") async def withdraw_matchmaking_all(self, *args): logger.warning("MatchmakeExtensionServerMK8.withdraw_matchmaking_all not implemented") raise common.RMCError("Core::NotImplemented") async def find_matchmake_session_by_gathering_id(self, *args): logger.warning("MatchmakeExtensionServerMK8.find_matchmake_session_by_gathering_id not implemented") raise common.RMCError("Core::NotImplemented") async def find_matchmake_session_by_single_gathering_id(self, *args): logger.warning("MatchmakeExtensionServerMK8.find_matchmake_session_by_single_gathering_id not implemented") raise common.RMCError("Core::NotImplemented") async def find_matchmake_session_by_owner(self, *args): logger.warning("MatchmakeExtensionServerMK8.find_matchmake_session_by_owner not implemented") raise common.RMCError("Core::NotImplemented") async def find_matchmake_session_by_participant(self, *args): logger.warning("MatchmakeExtensionServerMK8.find_matchmake_session_by_participant not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session_no_holder_no_result_range(self, *args): logger.warning("MatchmakeExtensionServerMK8.browse_matchmake_session_no_holder_no_result_range not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session_with_host_urls_no_holder_no_result_range(self, *args): logger.warning("MatchmakeExtensionServerMK8.browse_matchmake_session_with_host_urls_no_holder_no_result_range not implemented") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/matchmaking_mk8d.py ================================================ # This file was generated automatically by generate_protocols.py from nintendo.nex import notification, rmc, common, streams import logging logger = logging.getLogger(__name__) class MatchmakeSystem: GLOBAL = 1 FRIENDS = 2 class SimpleSearchConditionOperator: ANY = 0 EQUAL = 1 GREATER_THAN = 2 LESS_THAN = 3 GREATER_THAN_OR_EQUAL = 4 LESS_THAN_OR_EQUAL = 5 class Gathering(common.Structure): def __init__(self): super().__init__() self.id = 0 self.owner = 0 self.host = 0 self.min_participants = 0 self.max_participants = 0 self.participation_policy = 1 self.policy_argument = 0 self.flags = 512 self.state = 0 self.description = "" def check_required(self, settings, version): pass def load(self, stream, version): self.id = stream.u32() self.owner = stream.pid() self.host = stream.pid() self.min_participants = stream.u16() self.max_participants = stream.u16() self.participation_policy = stream.u32() self.policy_argument = stream.u32() self.flags = stream.u32() self.state = stream.u32() self.description = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.id) stream.pid(self.owner) stream.pid(self.host) stream.u16(self.min_participants) stream.u16(self.max_participants) stream.u32(self.participation_policy) stream.u32(self.policy_argument) stream.u32(self.flags) stream.u32(self.state) stream.string(self.description) class GatheringURLs(common.Structure): def __init__(self): super().__init__() self.gid = None self.urls = None def check_required(self, settings, version): for field in ['gid', 'urls']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.gid = stream.u32() self.urls = stream.list(stream.stationurl) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.gid) stream.list(self.urls, stream.stationurl) class GatheringStats(common.Structure): def __init__(self): super().__init__() self.pid = None self.flags = None self.values = None def check_required(self, settings, version): for field in ['pid', 'flags', 'values']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.flags = stream.u32() self.values = stream.list(stream.float) def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.u32(self.flags) stream.list(self.values, stream.float) class Invitation(common.Structure): def __init__(self): super().__init__() self.gid = None self.guest = None self.message = None def check_required(self, settings, version): for field in ['gid', 'guest', 'message']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.gid = stream.u32() self.guest = stream.u32() self.message = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.gid) stream.u32(self.guest) stream.string(self.message) class ParticipantDetails(common.Structure): def __init__(self): super().__init__() self.pid = None self.name = None self.message = None self.participants = None def check_required(self, settings, version): for field in ['pid', 'name', 'message', 'participants']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.name = stream.string() self.message = stream.string() self.participants = stream.u16() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.string(self.name) stream.string(self.message) stream.u16(self.participants) class DeletionEntry(common.Structure): def __init__(self): super().__init__() self.gid = None self.pid = None self.reason = None def check_required(self, settings, version): for field in ['gid', 'pid', 'reason']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.gid = stream.u32() self.pid = stream.pid() self.reason = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.gid) stream.pid(self.pid) stream.u32(self.reason) class MatchmakeParam(common.Structure): def __init__(self): super().__init__() self.param = {} def check_required(self, settings, version): pass def load(self, stream, version): self.param = stream.map(stream.string, stream.variant) def save(self, stream, version): self.check_required(stream.settings, version) stream.map(self.param, stream.string, stream.variant) class MatchmakeSessionSearchCriteria(common.Structure): def __init__(self): super().__init__() self.attribs = ["", "", "", "", "", ""] self.game_mode = "" self.min_participants = "" self.max_participants = "" self.matchmake_system = "" self.vacant_only = True self.exclude_locked = True self.exclude_non_host_pid = False self.selection_method = 0 self.vacant_participants = 1 self.param = MatchmakeParam() self.exclude_user_password = False self.exclude_system_password = False self.refer_gid = 0 self.codeword = "" self.range = common.ResultRange() def check_required(self, settings, version): if settings["nex.version"] >= 30500: pass if settings["nex.version"] >= 40000: pass def load(self, stream, version): self.attribs = stream.list(stream.string) self.game_mode = stream.string() self.min_participants = stream.string() self.max_participants = stream.string() self.matchmake_system = stream.string() self.vacant_only = stream.bool() self.exclude_locked = stream.bool() self.exclude_non_host_pid = stream.bool() self.selection_method = stream.u32() if stream.settings["nex.version"] >= 30500: self.vacant_participants = stream.u16() if stream.settings["nex.version"] >= 40000: self.param = stream.extract(MatchmakeParam) self.exclude_user_password = stream.bool() self.exclude_system_password = stream.bool() self.refer_gid = stream.u32() self.codeword = stream.string() self.range = stream.extract(common.ResultRange) def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.attribs, stream.string) stream.string(self.game_mode) stream.string(self.min_participants) stream.string(self.max_participants) stream.string(self.matchmake_system) stream.bool(self.vacant_only) stream.bool(self.exclude_locked) stream.bool(self.exclude_non_host_pid) stream.u32(self.selection_method) if stream.settings["nex.version"] >= 30500: stream.u16(self.vacant_participants) if stream.settings["nex.version"] >= 40000: stream.add(self.param) stream.bool(self.exclude_user_password) stream.bool(self.exclude_system_password) stream.u32(self.refer_gid) stream.string(self.codeword) stream.add(self.range) class MatchmakeSession(Gathering): def __init__(self): super().__init__() self.game_mode = 0 self.attribs = [0, 0, 0, 0, 0, 0] self.open_participation = True self.matchmake_system = 0 self.application_data = b"" self.num_participants = 0 self.progress_score = 100 self.session_key = b"" self.option = 0 self.param = MatchmakeParam() self.started_time = common.DateTime(0) self.user_password = "" self.refer_gid = 0 self.user_password_enabled = False self.system_password_enabled = False self.codeword = "" def max_version(self, settings): version = 0 if 30000 <= settings["nex.version"] < 40000: if settings["nex.version"] >= 30600: version = 1 if settings["nex.version"] >= 30700: version = 2 if settings["nex.version"] >= 30800: version = 3 return version def check_required(self, settings, version): if 30000 <= settings["nex.version"] < 40000: if settings["nex.version"] >= 30500: pass if settings["nex.version"] >= 30000: pass if settings["nex.version"] >= 30500: pass if settings["nex.version"] >= 30600: if version >= 1: pass if settings["nex.version"] >= 30700: if version >= 2: pass if settings["nex.version"] >= 30800: if version >= 3: pass if settings["nex.version"] >= 40000: pass def load(self, stream, version): self.game_mode = stream.u32() self.attribs = stream.list(stream.u32) self.open_participation = stream.bool() self.matchmake_system = stream.u32() self.application_data = stream.buffer() self.num_participants = stream.u32() if 30000 <= stream.settings["nex.version"] < 40000: if stream.settings["nex.version"] >= 30500: self.progress_score = stream.u8() if stream.settings["nex.version"] >= 30000: self.session_key = stream.buffer() if stream.settings["nex.version"] >= 30500: self.option = stream.u32() if stream.settings["nex.version"] >= 30600: if version >= 1: self.param = stream.extract(MatchmakeParam) self.started_time = stream.datetime() if stream.settings["nex.version"] >= 30700: if version >= 2: self.user_password = stream.string() if stream.settings["nex.version"] >= 30800: if version >= 3: self.refer_gid = stream.u32() self.user_password_enabled = stream.bool() self.system_password_enabled = stream.bool() if stream.settings["nex.version"] >= 40000: self.progress_score = stream.u8() self.session_key = stream.buffer() self.option = stream.u32() self.param = stream.extract(MatchmakeParam) self.started_time = stream.datetime() self.user_password = stream.string() self.refer_gid = stream.u32() self.user_password_enabled = stream.bool() self.system_password_enabled = stream.bool() self.codeword = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.game_mode) stream.list(self.attribs, stream.u32) stream.bool(self.open_participation) stream.u32(self.matchmake_system) stream.buffer(self.application_data) stream.u32(self.num_participants) if 30000 <= stream.settings["nex.version"] < 40000: if stream.settings["nex.version"] >= 30500: stream.u8(self.progress_score) if stream.settings["nex.version"] >= 30000: stream.buffer(self.session_key) if stream.settings["nex.version"] >= 30500: stream.u32(self.option) if stream.settings["nex.version"] >= 30600: if version >= 1: stream.add(self.param) stream.datetime(self.started_time) if stream.settings["nex.version"] >= 30700: if version >= 2: stream.string(self.user_password) if stream.settings["nex.version"] >= 30800: if version >= 3: stream.u32(self.refer_gid) stream.bool(self.user_password_enabled) stream.bool(self.system_password_enabled) if stream.settings["nex.version"] >= 40000: stream.u8(self.progress_score) stream.buffer(self.session_key) stream.u32(self.option) stream.add(self.param) stream.datetime(self.started_time) stream.string(self.user_password) stream.u32(self.refer_gid) stream.bool(self.user_password_enabled) stream.bool(self.system_password_enabled) stream.string(self.codeword) common.DataHolder.register(MatchmakeSession, "MatchmakeSession") class MatchmakeBlockListParam(common.Structure): def __init__(self): super().__init__() self.options = 0 def check_required(self, settings, version): pass def load(self, stream, version): self.options = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.options) class CreateMatchmakeSessionParam(common.Structure): def __init__(self): super().__init__() self.session = MatchmakeSession() self.additional_participants = None self.gid_for_participation_check = None self.options = None self.join_message = None self.num_participants = None def check_required(self, settings, version): for field in ['additional_participants', 'gid_for_participation_check', 'options', 'join_message', 'num_participants']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.session = stream.extract(MatchmakeSession) self.additional_participants = stream.list(stream.pid) self.gid_for_participation_check = stream.u32() self.options = stream.u32() self.join_message = stream.string() self.num_participants = stream.u16() def save(self, stream, version): self.check_required(stream.settings, version) stream.add(self.session) stream.list(self.additional_participants, stream.pid) stream.u32(self.gid_for_participation_check) stream.u32(self.options) stream.string(self.join_message) stream.u16(self.num_participants) class JoinMatchmakeSessionParam(common.Structure): def __init__(self): super().__init__() self.gid = None self.participants = None self.gid_for_participation_check = None self.options = None self.behavior = None self.user_password = None self.system_password = None self.join_message = None self.num_participants = None self.extra_participants = None self.block_list = MatchmakeBlockListParam() def check_required(self, settings, version): for field in ['gid', 'participants', 'gid_for_participation_check', 'options', 'behavior', 'user_password', 'system_password', 'join_message', 'num_participants', 'extra_participants']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.gid = stream.u32() self.participants = stream.list(stream.pid) self.gid_for_participation_check = stream.u32() self.options = stream.u32() self.behavior = stream.u8() self.user_password = stream.string() self.system_password = stream.string() self.join_message = stream.string() self.num_participants = stream.u16() self.extra_participants = stream.u16() self.block_list = stream.extract(MatchmakeBlockListParam) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.gid) stream.list(self.participants, stream.pid) stream.u32(self.gid_for_participation_check) stream.u32(self.options) stream.u8(self.behavior) stream.string(self.user_password) stream.string(self.system_password) stream.string(self.join_message) stream.u16(self.num_participants) stream.u16(self.extra_participants) stream.add(self.block_list) class UpdateMatchmakeSessionParam(common.Structure): def __init__(self): super().__init__() self.gid = None self.modification_flags = None self.attributes = None self.open_participation = None self.application_buffer = None self.progress_score = None self.param = MatchmakeParam() self.started_time = None self.user_password = None self.game_mode = None self.description = None self.min_participants = None self.max_participants = None self.matchmake_system = None self.participation_policy = None self.policy_argument = None self.codeword = None def check_required(self, settings, version): for field in ['gid', 'modification_flags', 'attributes', 'open_participation', 'application_buffer', 'progress_score', 'started_time', 'user_password', 'game_mode', 'description', 'min_participants', 'max_participants', 'matchmake_system', 'participation_policy', 'policy_argument', 'codeword']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.gid = stream.u32() self.modification_flags = stream.u32() self.attributes = stream.list(stream.u32) self.open_participation = stream.bool() self.application_buffer = stream.buffer() self.progress_score = stream.u8() self.param = stream.extract(MatchmakeParam) self.started_time = stream.datetime() self.user_password = stream.string() self.game_mode = stream.u32() self.description = stream.string() self.min_participants = stream.u16() self.max_participants = stream.u16() self.matchmake_system = stream.u32() self.participation_policy = stream.u32() self.policy_argument = stream.u32() self.codeword = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.gid) stream.u32(self.modification_flags) stream.list(self.attributes, stream.u32) stream.bool(self.open_participation) stream.buffer(self.application_buffer) stream.u8(self.progress_score) stream.add(self.param) stream.datetime(self.started_time) stream.string(self.user_password) stream.u32(self.game_mode) stream.string(self.description) stream.u16(self.min_participants) stream.u16(self.max_participants) stream.u32(self.matchmake_system) stream.u32(self.participation_policy) stream.u32(self.policy_argument) stream.string(self.codeword) class AutoMatchmakeParam(common.Structure): def __init__(self): super().__init__() self.session = MatchmakeSession() self.participants = None self.gid_for_participation_check = None self.options = None self.join_message = None self.num_participants = None self.search_criteria = None self.target_gids = None self.block_list = MatchmakeBlockListParam() def check_required(self, settings, version): for field in ['participants', 'gid_for_participation_check', 'options', 'join_message', 'num_participants', 'search_criteria', 'target_gids']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.session = stream.extract(MatchmakeSession) self.participants = stream.list(stream.pid) self.gid_for_participation_check = stream.u32() self.options = stream.u32() self.join_message = stream.string() self.num_participants = stream.u16() self.search_criteria = stream.list(MatchmakeSessionSearchCriteria) self.target_gids = stream.list(stream.u32) self.block_list = stream.extract(MatchmakeBlockListParam) def save(self, stream, version): self.check_required(stream.settings, version) stream.add(self.session) stream.list(self.participants, stream.pid) stream.u32(self.gid_for_participation_check) stream.u32(self.options) stream.string(self.join_message) stream.u16(self.num_participants) stream.list(self.search_criteria, stream.add) stream.list(self.target_gids, stream.u32) stream.add(self.block_list) class FindMatchmakeSessionByParticipantParam(common.Structure): def __init__(self): super().__init__() self.pids = None self.options = None self.block_list = MatchmakeBlockListParam() def check_required(self, settings, version): for field in ['pids', 'options']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pids = stream.list(stream.pid) self.options = stream.u32() self.block_list = stream.extract(MatchmakeBlockListParam) def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.pids, stream.pid) stream.u32(self.options) stream.add(self.block_list) class FindMatchmakeSessionByParticipantResult(common.Structure): def __init__(self): super().__init__() self.pid = None self.session = MatchmakeSession() def check_required(self, settings, version): for field in ['pid']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.session = stream.extract(MatchmakeSession) def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.add(self.session) class PersistentGathering(Gathering): def __init__(self): super().__init__() self.type = None self.password = None self.attribs = None self.application_buffer = None self.participation_start = None self.participation_end = None self.matchmake_session_count = None self.num_participants = None def check_required(self, settings, version): for field in ['type', 'password', 'attribs', 'application_buffer', 'participation_start', 'participation_end', 'matchmake_session_count', 'num_participants']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.type = stream.u32() self.password = stream.string() self.attribs = stream.list(stream.u32) self.application_buffer = stream.buffer() self.participation_start = stream.datetime() self.participation_end = stream.datetime() self.matchmake_session_count = stream.u32() self.num_participants = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.type) stream.string(self.password) stream.list(self.attribs, stream.u32) stream.buffer(self.application_buffer) stream.datetime(self.participation_start) stream.datetime(self.participation_end) stream.u32(self.matchmake_session_count) stream.u32(self.num_participants) common.DataHolder.register(PersistentGathering, "PersistentGathering") class SimpleCommunity(common.Structure): def __init__(self): super().__init__() self.gid = None self.matchmake_session_count = None def check_required(self, settings, version): for field in ['gid', 'matchmake_session_count']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.gid = stream.u32() self.matchmake_session_count = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.gid) stream.u32(self.matchmake_session_count) class PlayingSession(common.Structure): def __init__(self): super().__init__() self.pid = None self.gathering = None def check_required(self, settings, version): for field in ['pid', 'gathering']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.gathering = stream.anydata() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.anydata(self.gathering) class SimplePlayingSession(common.Structure): def __init__(self): super().__init__() self.pid = None self.gid = None self.game_mode = None self.attribute = None def check_required(self, settings, version): for field in ['pid', 'gid', 'game_mode', 'attribute']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.gid = stream.u32() self.game_mode = stream.u32() self.attribute = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.u32(self.gid) stream.u32(self.game_mode) stream.u32(self.attribute) class MatchmakeRefereeRound(common.Structure): def __init__(self): super().__init__() self.id = None self.gid = None self.state = None self.personal_data_category = None self.results = None def check_required(self, settings, version): for field in ['id', 'gid', 'state', 'personal_data_category', 'results']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.id = stream.u64() self.gid = stream.u32() self.state = stream.u32() self.personal_data_category = stream.u32() self.results = stream.list(MatchmakeRefereePersonalRoundResult) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.id) stream.u32(self.gid) stream.u32(self.state) stream.u32(self.personal_data_category) stream.list(self.results, stream.add) class MatchmakeRefereeStartRoundParam(common.Structure): def __init__(self): super().__init__() self.personal_data_category = None self.gid = None self.pids = None def check_required(self, settings, version): for field in ['personal_data_category', 'gid', 'pids']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.personal_data_category = stream.u32() self.gid = stream.u32() self.pids = stream.list(stream.pid) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.personal_data_category) stream.u32(self.gid) stream.list(self.pids, stream.pid) class MatchmakeRefereeEndRoundParam(common.Structure): def __init__(self): super().__init__() self.round_id = None self.results = None def check_required(self, settings, version): for field in ['round_id', 'results']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.round_id = stream.u64() self.results = stream.list(MatchmakeRefereePersonalRoundResult) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.round_id) stream.list(self.results, stream.add) class MatchmakeRefereePersonalRoundResult(common.Structure): def __init__(self): super().__init__() self.pid = None self.personal_round_result_flag = None self.round_win_loss = None self.rating_change = None self.buffer = None def check_required(self, settings, version): for field in ['pid', 'personal_round_result_flag', 'round_win_loss', 'rating_change', 'buffer']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.personal_round_result_flag = stream.u32() self.round_win_loss = stream.u32() self.rating_change = stream.s32() self.buffer = stream.qbuffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.u32(self.personal_round_result_flag) stream.u32(self.round_win_loss) stream.s32(self.rating_change) stream.qbuffer(self.buffer) class MatchmakeRefereeStats(common.Structure): def __init__(self): super().__init__() self.unique_id = None self.category = None self.pid = None self.recent_disconnection = None self.recent_violation = None self.recent_mismatch = None self.recent_win = None self.recent_loss = None self.recent_draw = None self.total_disconnect = None self.total_violation = None self.total_mismatch = None self.total_win = None self.total_loss = None self.total_draw = None self.rating_value = None def check_required(self, settings, version): for field in ['unique_id', 'category', 'pid', 'recent_disconnection', 'recent_violation', 'recent_mismatch', 'recent_win', 'recent_loss', 'recent_draw', 'total_disconnect', 'total_violation', 'total_mismatch', 'total_win', 'total_loss', 'total_draw', 'rating_value']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.unique_id = stream.u64() self.category = stream.u32() self.pid = stream.pid() self.recent_disconnection = stream.u32() self.recent_violation = stream.u32() self.recent_mismatch = stream.u32() self.recent_win = stream.u32() self.recent_loss = stream.u32() self.recent_draw = stream.u32() self.total_disconnect = stream.u32() self.total_violation = stream.u32() self.total_mismatch = stream.u32() self.total_win = stream.u32() self.total_loss = stream.u32() self.total_draw = stream.u32() self.rating_value = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.unique_id) stream.u32(self.category) stream.pid(self.pid) stream.u32(self.recent_disconnection) stream.u32(self.recent_violation) stream.u32(self.recent_mismatch) stream.u32(self.recent_win) stream.u32(self.recent_loss) stream.u32(self.recent_draw) stream.u32(self.total_disconnect) stream.u32(self.total_violation) stream.u32(self.total_mismatch) stream.u32(self.total_win) stream.u32(self.total_loss) stream.u32(self.total_draw) stream.u32(self.rating_value) class MatchmakeRefereeStatsTarget(common.Structure): def __init__(self): super().__init__() self.pid = None self.category = None def check_required(self, settings, version): for field in ['pid', 'category']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.category = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.u32(self.category) class MatchmakeRefereeStatsInitParam(common.Structure): def __init__(self): super().__init__() self.category = None self.initial_rating = None def check_required(self, settings, version): for field in ['category', 'initial_rating']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.category = stream.u32() self.initial_rating = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.category) stream.u32(self.initial_rating) class SimpleSearchObject(common.Structure): def __init__(self): super().__init__() self.id = None self.owner = None self.attributes = None self.metadata = None self.community_id = None self.community_code = None self.datetime = SimpleSearchDateTimeAttribute() self.liveliness_rate = None self.liveliness_update_time = None def max_version(self, settings): version = 0 if settings["nex.version"] >= 40000: version = 1 return version def check_required(self, settings, version): for field in ['id', 'owner', 'attributes', 'metadata', 'community_id', 'community_code']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) if settings["nex.version"] >= 40000: if version >= 1: for field in ['liveliness_rate', 'liveliness_update_time']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.id = stream.u32() self.owner = stream.pid() self.attributes = stream.list(stream.u32) self.metadata = stream.qbuffer() self.community_id = stream.u32() self.community_code = stream.string() self.datetime = stream.extract(SimpleSearchDateTimeAttribute) if stream.settings["nex.version"] >= 40000: if version >= 1: self.liveliness_rate = stream.u32() self.liveliness_update_time = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.id) stream.pid(self.owner) stream.list(self.attributes, stream.u32) stream.qbuffer(self.metadata) stream.u32(self.community_id) stream.string(self.community_code) stream.add(self.datetime) if stream.settings["nex.version"] >= 40000: if version >= 1: stream.u32(self.liveliness_rate) stream.datetime(self.liveliness_update_time) class SimpleSearchDateTimeAttribute(common.Structure): def __init__(self): super().__init__() self.start_daytime = None self.end_daytime = None self.start_time = None self.end_time = None self.start_datetime = None self.end_datetime = None def check_required(self, settings, version): for field in ['start_daytime', 'end_daytime', 'start_time', 'end_time', 'start_datetime', 'end_datetime']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.start_daytime = stream.u32() self.end_daytime = stream.u32() self.start_time = stream.u32() self.end_time = stream.u32() self.start_datetime = stream.datetime() self.end_datetime = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.start_daytime) stream.u32(self.end_daytime) stream.u32(self.start_time) stream.u32(self.end_time) stream.datetime(self.start_datetime) stream.datetime(self.end_datetime) class SimpleSearchParam(common.Structure): def __init__(self): super().__init__() self.id = 0 self.owner = 0 self.conditions = [] self.community_code = "" self.range = common.ResultRange() self.datetime = common.DateTime(0) def check_required(self, settings, version): pass def load(self, stream, version): self.id = stream.u32() self.owner = stream.pid() self.conditions = stream.list(SimpleSearchCondition) self.community_code = stream.string() self.range = stream.extract(common.ResultRange) self.datetime = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.id) stream.pid(self.owner) stream.list(self.conditions, stream.add) stream.string(self.community_code) stream.add(self.range) stream.datetime(self.datetime) class SimpleSearchCondition(common.Structure): def __init__(self): super().__init__() self.value = None self.operator = None def check_required(self, settings, version): for field in ['value', 'operator']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.value = stream.u32() self.operator = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.value) stream.u32(self.operator) class MatchMakingProtocol: METHOD_REGISTER_GATHERING = 1 METHOD_UNREGISTER_GATHERING = 2 METHOD_UNREGISTER_GATHERINGS = 3 METHOD_UPDATE_GATHERING = 4 METHOD_INVITE = 5 METHOD_ACCEPT_INVITATION = 6 METHOD_DECLINE_INVITATION = 7 METHOD_CANCEL_INVITATION = 8 METHOD_GET_INVITATIONS_SENT = 9 METHOD_GET_INVITATIONS_RECEIVED = 10 METHOD_PARTICIPATE = 11 METHOD_CANCEL_PARTICIPATION = 12 METHOD_GET_PARTICIPANTS = 13 METHOD_ADD_PARTICIPANTS = 14 METHOD_GET_DETAILED_PARTICIPANTS = 15 METHOD_GET_PARTICIPANTS_URLS = 16 METHOD_FIND_BY_TYPE = 17 METHOD_FIND_BY_DESCRIPTION = 18 METHOD_FIND_BY_DESCRIPTION_REGEX = 19 METHOD_FIND_BY_ID = 20 METHOD_FIND_BY_SINGLE_ID = 21 METHOD_FIND_BY_OWNER = 22 METHOD_FIND_BY_PARTICIPANTS = 23 METHOD_FIND_INVITATIONS = 24 METHOD_FIND_BY_SQL_QUERY = 25 METHOD_LAUNCH_SESSION = 26 METHOD_UPDATE_SESSION_URL = 27 METHOD_GET_SESSION_URL = 28 METHOD_GET_STATE = 29 METHOD_SET_STATE = 30 METHOD_REPORT_STATS = 31 METHOD_GET_STATS = 32 METHOD_DELETE_GATHERING = 33 METHOD_GET_PENDING_DELETIONS = 34 METHOD_DELETE_FROM_DELETIONS = 35 METHOD_MIGRATE_GATHERING_OWNERSHIP_V1 = 36 METHOD_FIND_BY_DESCRIPTION_LIKE = 37 METHOD_REGISTER_LOCAL_URL = 38 METHOD_REGISTER_LOCAL_URLS = 39 METHOD_UPDATE_SESSION_HOST_V1 = 40 METHOD_GET_SESSION_URLS = 41 METHOD_UPDATE_SESSION_HOST = 42 METHOD_UPDATE_GATHERING_OWNERSHIP = 43 METHOD_MIGRATE_GATHERING_OWNERSHIP = 44 PROTOCOL_ID = 0x15 class MatchMakingProtocolExt: METHOD_END_PARTICIPATION = 1 METHOD_GET_PARTICIPANTS = 2 METHOD_GET_DETAILED_PARTICIPANTS = 3 METHOD_GET_PARTICIPANTS_URLS = 4 METHOD_GET_GATHERING_RELATIONS = 5 METHOD_DELETE_FROM_DELETIONS = 6 PROTOCOL_ID = 0x32 class MatchmakeRefereeProtocol: METHOD_START_ROUND = 1 METHOD_GET_START_ROUND_PARAM = 2 METHOD_END_ROUND = 3 METHOD_END_ROUND_WITHOUT_REPORT = 4 METHOD_GET_ROUND_PARTICIPANTS = 5 METHOD_GET_NOT_SUMMARIZED_ROUND = 6 METHOD_GET_ROUND = 7 METHOD_GET_STATS_PRIMARY = 8 METHOD_GET_STATS_PRIMARIES = 9 METHOD_GET_STATS_ALL = 10 METHOD_CREATE_STATS = 11 METHOD_GET_OR_CREATE_STATS = 12 METHOD_RESET_STATS = 13 PROTOCOL_ID = 0x78 class MatchmakeExtensionProtocolMK8D: METHOD_CLOSE_PARTICIPATION = 1 METHOD_OPEN_PARTICIPATION = 2 METHOD_AUTO_MATCHMAKE_POSTPONE = 3 METHOD_BROWSE_MATCHMAKE_SESSION = 4 METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS = 5 METHOD_CREATE_MATCHMAKE_SESSION = 6 METHOD_JOIN_MATCHMAKE_SESSION = 7 METHOD_MODIFY_CURRENT_GAME_ATTRIBUTE = 8 METHOD_UPDATE_NOTIFICATION_DATA = 9 METHOD_GET_FRIEND_NOTIFICATION_DATA = 10 METHOD_UPDATE_APPLICATION_BUFFER = 11 METHOD_UPDATE_MATCHMAKE_SESSION_ATTRIBUTE = 12 METHOD_GET_FRIEND_NOTIFICATION_DATA_LIST = 13 METHOD_UPDATE_MATCHMAKE_SESSION = 14 METHOD_AUTO_MATCHMAKE_WITH_SEARCH_CRITERIA_POSTPONE = 15 METHOD_GET_PLAYING_SESSION = 16 METHOD_CREATE_COMMUNITY = 17 METHOD_UPDATE_COMMUNITY = 18 METHOD_JOIN_COMMUNITY = 19 METHOD_FIND_COMMUNITY_BY_GATHERING_ID = 20 METHOD_FIND_OFFICIAL_COMMUNITY = 21 METHOD_FIND_COMMUNITY_BY_PARTICIPANT = 22 METHOD_UPDATE_PRIVACY_SETTING = 23 METHOD_GET_MY_BLOCK_LIST = 24 METHOD_ADD_TO_BLOCK_LIST = 25 METHOD_REMOVE_FROM_BLOCK_LIST = 26 METHOD_CLEAR_MY_BLOCK_LIST = 27 METHOD_REPORT_VIOLATION = 28 METHOD_IS_VIOLATION_USER = 29 METHOD_JOIN_MATCHMAKE_SESSION_EX = 30 METHOD_GET_SIMPLE_PLAYING_SESSION = 31 METHOD_GET_SIMPLE_COMMUNITY = 32 METHOD_AUTO_MATCHMAKE_WITH_GATHERING_ID_POSTPONE = 33 METHOD_UPDATE_PROGRESS_SCORE = 34 METHOD_DEBUG_NOTIFY_EVENT = 35 METHOD_GENERATE_MATCHMAKE_SESSION_SYSTEM_PASSWORD = 36 METHOD_CLEAR_MATCHMAKE_SESSION_SYSTEM_PASSWORD = 37 METHOD_CREATE_MATCHMAKE_SESSION_WITH_PARAM = 38 METHOD_JOIN_MATCHMAKE_SESSION_WITH_PARAM = 39 METHOD_AUTO_MATCHMAKE_WITH_PARAM_POSTPONE = 40 METHOD_FIND_MATCHMAKE_SESSION_BY_GATHERING_ID_DETAIL = 41 METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER = 42 METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER = 43 METHOD_UPDATE_MATCHMAKE_SESSION_PART = 44 METHOD_REQUEST_MATCHMAKING = 45 METHOD_WITHDRAW_MATCHMAKING = 46 METHOD_WITHDRAW_MATCHMAKING_ALL = 47 METHOD_FIND_MATCHMAKE_SESSION_BY_GATHERING_ID = 48 METHOD_FIND_MATCHMAKE_SESSION_BY_SINGLE_GATHERING_ID = 49 METHOD_FIND_MATCHMAKE_SESSION_BY_OWNER = 50 METHOD_FIND_MATCHMAKE_SESSION_BY_PARTICIPANT = 51 METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER_NO_RESULT_RANGE = 52 METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER_NO_RESULT_RANGE = 53 METHOD_CREATE_SIMPLE_SEARCH_OBJECT = 54 METHOD_UPDATE_SIMPLE_SEARCH_OBJECT = 55 METHOD_DELETE_SIMPLE_SEARCH_OBJECT = 56 METHOD_SEARCH_SIMPLE_SEARCH_OBJECT = 57 METHOD_SEARCH_SIMPLE_SEARCH_OBJECT_BY_OBJECT_IDS = 58 METHOD_JOIN_MATCHMAKE_SESSION_WITH_EXTRA_PARTICIPANTS = 59 METHOD_CUSTOM_GET_SIMPLE_PLAYING_SESSION = 60 METHOD_CREATE_COMPETITION = 61 METHOD_DELETE_COMPETITION = 62 METHOD_REGISTER_FAVORITE_COMPETITION = 63 METHOD_UNREGISTER_FAVORITE_COMPETITION = 64 METHOD_GET_FAVORITE_COMPETITION = 65 METHOD_GET_TEAM_PARTICIPANTS = 66 METHOD_FIND_COMMUNITY_BY_OWNER = 67 PROTOCOL_ID = 0x6D class MatchMakingClient(MatchMakingProtocol): def __init__(self, client): self.settings = client.settings self.client = client async def register_gathering(self, gathering): logger.info("MatchMakingClient.register_gathering()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(gathering) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REGISTER_GATHERING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gid = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.register_gathering -> done") return gid async def unregister_gathering(self, gid): logger.info("MatchMakingClient.unregister_gathering()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UNREGISTER_GATHERING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.unregister_gathering -> done") return result async def unregister_gatherings(self, gids): logger.info("MatchMakingClient.unregister_gatherings()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UNREGISTER_GATHERINGS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.unregister_gatherings -> done") return result async def update_gathering(self, gathering): logger.info("MatchMakingClient.update_gathering()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(gathering) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_GATHERING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.update_gathering -> done") return result async def invite(self, gid, pids, message): logger.info("MatchMakingClient.invite()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(pids, stream.pid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_INVITE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.invite -> done") return result async def accept_invitation(self, gid, message): logger.info("MatchMakingClient.accept_invitation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_ACCEPT_INVITATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.accept_invitation -> done") return result async def decline_invitation(self, gid, message): logger.info("MatchMakingClient.decline_invitation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DECLINE_INVITATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.decline_invitation -> done") return result async def cancel_invitation(self, gid, pids, message): logger.info("MatchMakingClient.cancel_invitation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(pids, stream.pid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CANCEL_INVITATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.cancel_invitation -> done") return result async def get_invitations_sent(self, gid): logger.info("MatchMakingClient.get_invitations_sent()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_INVITATIONS_SENT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) invitations = stream.list(Invitation) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_invitations_sent -> done") return invitations async def get_invitations_received(self): logger.info("MatchMakingClient.get_invitations_received()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_INVITATIONS_RECEIVED, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) invitations = stream.list(Invitation) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_invitations_received -> done") return invitations async def participate(self, gid, message): logger.info("MatchMakingClient.participate()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PARTICIPATE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.participate -> done") return result async def cancel_participation(self, gid, message): logger.info("MatchMakingClient.cancel_participation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CANCEL_PARTICIPATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.cancel_participation -> done") return result async def get_participants(self, gid): logger.info("MatchMakingClient.get_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) participants = stream.list(stream.pid) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_participants -> done") return participants async def add_participants(self, gid, pids, message): logger.info("MatchMakingClient.add_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(pids, stream.pid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_ADD_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.add_participants -> done") return result async def get_detailed_participants(self, gid): logger.info("MatchMakingClient.get_detailed_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_DETAILED_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) details = stream.list(ParticipantDetails) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_detailed_participants -> done") return details async def get_participants_urls(self, gid): logger.info("MatchMakingClient.get_participants_urls()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PARTICIPANTS_URLS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) urls = stream.list(stream.stationurl) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_participants_urls -> done") return urls async def find_by_type(self, type, range): logger.info("MatchMakingClient.find_by_type()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(type) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_TYPE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_type -> done") return gatherings async def find_by_description(self, description, range): logger.info("MatchMakingClient.find_by_description()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(description) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_DESCRIPTION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_description -> done") return gatherings async def find_by_description_regex(self, regex, range): logger.info("MatchMakingClient.find_by_description_regex()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(regex) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_DESCRIPTION_REGEX, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_description_regex -> done") return gatherings async def find_by_id(self, ids): logger.info("MatchMakingClient.find_by_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(ids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_id -> done") return gatherings async def find_by_single_id(self, gid): logger.info("MatchMakingClient.find_by_single_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_SINGLE_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.gathering = stream.anydata() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_single_id -> done") return obj async def find_by_owner(self, owner, range): logger.info("MatchMakingClient.find_by_owner()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(owner) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_OWNER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_owner -> done") return gatherings async def find_by_participants(self, pids): logger.info("MatchMakingClient.find_by_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_participants -> done") return gatherings async def find_invitations(self, range): logger.info("MatchMakingClient.find_invitations()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_INVITATIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_invitations -> done") return gatherings async def find_by_sql_query(self, query, range): logger.info("MatchMakingClient.find_by_sql_query()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(query) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_SQL_QUERY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_sql_query -> done") return gatherings async def launch_session(self, gid, url): logger.info("MatchMakingClient.launch_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(url) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_LAUNCH_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.launch_session -> done") return result async def update_session_url(self, gid, url): logger.info("MatchMakingClient.update_session_url()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(url) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_SESSION_URL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.update_session_url -> done") return result async def get_session_url(self, gid): logger.info("MatchMakingClient.get_session_url()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SESSION_URL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.url = stream.string() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_session_url -> done") return obj async def get_state(self, gid): logger.info("MatchMakingClient.get_state()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.state = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_state -> done") return obj async def set_state(self, gid, state): logger.info("MatchMakingClient.set_state()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.u32(state) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SET_STATE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.set_state -> done") return result async def report_stats(self, gid, stats): logger.info("MatchMakingClient.report_stats()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(stats, stream.add) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REPORT_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.report_stats -> done") return result async def get_stats(self, gid, pids, columns): logger.info("MatchMakingClient.get_stats()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(pids, stream.pid) stream.list(columns, stream.u8) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.stats = stream.list(GatheringStats) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_stats -> done") return obj async def delete_gathering(self, gid): logger.info("MatchMakingClient.delete_gathering()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_GATHERING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.delete_gathering -> done") return result async def get_pending_deletions(self, reason, range): logger.info("MatchMakingClient.get_pending_deletions()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(reason) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PENDING_DELETIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.deletions = stream.list(DeletionEntry) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_pending_deletions -> done") return obj async def delete_from_deletions(self, deletions): logger.info("MatchMakingClient.delete_from_deletions()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(deletions, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_FROM_DELETIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.delete_from_deletions -> done") return result async def migrate_gathering_ownership_v1(self, gid, potential_owners): logger.info("MatchMakingClient.migrate_gathering_ownership_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(potential_owners, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_MIGRATE_GATHERING_OWNERSHIP_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.migrate_gathering_ownership_v1 -> done") return result async def find_by_description_like(self, description, range): logger.info("MatchMakingClient.find_by_description_like()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(description) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_BY_DESCRIPTION_LIKE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.find_by_description_like -> done") return gatherings async def register_local_url(self, gid, url): logger.info("MatchMakingClient.register_local_url()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.stationurl(url) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REGISTER_LOCAL_URL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.register_local_url -> done") async def register_local_urls(self, gid, urls): logger.info("MatchMakingClient.register_local_urls()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(urls, stream.stationurl) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REGISTER_LOCAL_URLS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.register_local_urls -> done") async def update_session_host_v1(self, gid): logger.info("MatchMakingClient.update_session_host_v1()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_SESSION_HOST_V1, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.update_session_host_v1 -> done") async def get_session_urls(self, gid): logger.info("MatchMakingClient.get_session_urls()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SESSION_URLS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) urls = stream.list(stream.stationurl) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.get_session_urls -> done") return urls async def update_session_host(self, gid, is_migrate_owner): logger.info("MatchMakingClient.update_session_host()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.bool(is_migrate_owner) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_SESSION_HOST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.update_session_host -> done") async def update_gathering_ownership(self, gid, participants_only): logger.info("MatchMakingClient.update_gathering_ownership()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.bool(participants_only) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_GATHERING_OWNERSHIP, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.update_gathering_ownership -> done") return result async def migrate_gathering_ownership(self, gid, potential_owners, participants_only): logger.info("MatchMakingClient.migrate_gathering_ownership()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(potential_owners, stream.pid) stream.bool(participants_only) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_MIGRATE_GATHERING_OWNERSHIP, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClient.migrate_gathering_ownership -> done") class MatchMakingClientExt(MatchMakingProtocolExt): def __init__(self, client): self.settings = client.settings self.client = client async def end_participation(self, gid, message): logger.info("MatchMakingClientExt.end_participation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_END_PARTICIPATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.end_participation -> done") return result async def get_participants(self, gid, only_active): logger.info("MatchMakingClientExt.get_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.bool(only_active) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) participants = stream.list(stream.pid) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.get_participants -> done") return participants async def get_detailed_participants(self, gid, only_active): logger.info("MatchMakingClientExt.get_detailed_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.bool(only_active) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_DETAILED_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) details = stream.list(ParticipantDetails) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.get_detailed_participants -> done") return details async def get_participants_urls(self, gids): logger.info("MatchMakingClientExt.get_participants_urls()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PARTICIPANTS_URLS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) urls = stream.list(GatheringURLs) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.get_participants_urls -> done") return urls async def get_gathering_relations(self, id, descr): logger.info("MatchMakingClientExt.get_gathering_relations()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(id) stream.string(descr) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_GATHERING_RELATIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.string() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.get_gathering_relations -> done") return result async def delete_from_deletions(self, deletions, pid): logger.info("MatchMakingClientExt.delete_from_deletions()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(deletions, stream.u32) stream.pid(pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_FROM_DELETIONS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchMakingClientExt.delete_from_deletions -> done") class MatchmakeRefereeClient(MatchmakeRefereeProtocol): def __init__(self, client): self.settings = client.settings self.client = client async def start_round(self, param): logger.info("MatchmakeRefereeClient.start_round()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_START_ROUND, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) round_id = stream.u64() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.start_round -> done") return round_id async def get_start_round_param(self, round_id): logger.info("MatchmakeRefereeClient.get_start_round_param()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(round_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_START_ROUND_PARAM, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) param = stream.extract(MatchmakeRefereeStartRoundParam) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_start_round_param -> done") return param async def end_round(self, param): logger.info("MatchmakeRefereeClient.end_round()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_END_ROUND, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.end_round -> done") async def end_round_without_report(self, round_id): logger.info("MatchmakeRefereeClient.end_round_without_report()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(round_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_END_ROUND_WITHOUT_REPORT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.end_round_without_report -> done") async def get_round_participants(self, round_id): logger.info("MatchmakeRefereeClient.get_round_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(round_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_ROUND_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) pids = stream.list(stream.pid) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_round_participants -> done") return pids async def get_not_summarized_round(self): logger.info("MatchmakeRefereeClient.get_not_summarized_round()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_NOT_SUMMARIZED_ROUND, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) rounds = stream.list(MatchmakeRefereeRound) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_not_summarized_round -> done") return rounds async def get_round(self, round): logger.info("MatchmakeRefereeClient.get_round()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(round) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_ROUND, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) round = stream.extract(MatchmakeRefereeRound) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_round -> done") return round async def get_stats_primary(self, target): logger.info("MatchmakeRefereeClient.get_stats_primary()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATS_PRIMARY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) stats = stream.extract(MatchmakeRefereeStats) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_stats_primary -> done") return stats async def get_stats_primaries(self, targets): logger.info("MatchmakeRefereeClient.get_stats_primaries()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(targets, stream.add) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATS_PRIMARIES, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.stats = stream.list(MatchmakeRefereeStats) obj.results = stream.list(stream.result) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_stats_primaries -> done") return obj async def get_stats_all(self, target): logger.info("MatchmakeRefereeClient.get_stats_all()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(target) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATS_ALL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) stats = stream.list(MatchmakeRefereeStats) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_stats_all -> done") return stats async def create_stats(self, param): logger.info("MatchmakeRefereeClient.create_stats()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CREATE_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) stats = stream.extract(MatchmakeRefereeStats) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.create_stats -> done") return stats async def get_or_create_stats(self, param): logger.info("MatchmakeRefereeClient.get_or_create_stats()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_OR_CREATE_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) stats = stream.extract(MatchmakeRefereeStats) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.get_or_create_stats -> done") return stats async def reset_stats(self): logger.info("MatchmakeRefereeClient.reset_stats()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RESET_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeRefereeClient.reset_stats -> done") class MatchmakeExtensionClientMK8D(MatchmakeExtensionProtocolMK8D): def __init__(self, client): self.settings = client.settings self.client = client async def close_participation(self, gid): logger.info("MatchmakeExtensionClientMK8D.close_participation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CLOSE_PARTICIPATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.close_participation -> done") async def open_participation(self, gid): logger.info("MatchmakeExtensionClientMK8D.open_participation()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_OPEN_PARTICIPATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.open_participation -> done") async def auto_matchmake_postpone(self, gathering, message): logger.info("MatchmakeExtensionClientMK8D.auto_matchmake_postpone()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(gathering) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_AUTO_MATCHMAKE_POSTPONE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gathering = stream.anydata() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.auto_matchmake_postpone -> done") return gathering async def browse_matchmake_session(self, search_criteria, range): logger.info("MatchmakeExtensionClientMK8D.browse_matchmake_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gatherings = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.browse_matchmake_session -> done") return gatherings async def browse_matchmake_session_with_host_urls(self, search_criteria, range): logger.info("MatchmakeExtensionClientMK8D.browse_matchmake_session_with_host_urls()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.gatherings = stream.list(stream.anydata) obj.urls = stream.list(GatheringURLs) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.browse_matchmake_session_with_host_urls -> done") return obj async def create_matchmake_session(self, gathering, description, num_participants): logger.info("MatchmakeExtensionClientMK8D.create_matchmake_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(gathering) stream.string(description) stream.u16(num_participants) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CREATE_MATCHMAKE_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.gid = stream.u32() obj.session_key = stream.buffer() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.create_matchmake_session -> done") return obj async def join_matchmake_session(self, gid, message): logger.info("MatchmakeExtensionClientMK8D.join_matchmake_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_JOIN_MATCHMAKE_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session_key = stream.buffer() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.join_matchmake_session -> done") return session_key async def modify_current_game_attribute(self, gid, attrib, value): logger.info("MatchmakeExtensionClientMK8D.modify_current_game_attribute()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.u32(attrib) stream.u32(value) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_MODIFY_CURRENT_GAME_ATTRIBUTE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.modify_current_game_attribute -> done") async def update_notification_data(self, type, param1, param2, param3): logger.info("MatchmakeExtensionClientMK8D.update_notification_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(type) stream.pid(param1) stream.pid(param2) stream.string(param3) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_NOTIFICATION_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.update_notification_data -> done") async def get_friend_notification_data(self, type): logger.info("MatchmakeExtensionClientMK8D.get_friend_notification_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.s32(type) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_FRIEND_NOTIFICATION_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) notifications = stream.list(notification.NotificationEvent) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.get_friend_notification_data -> done") return notifications async def update_application_buffer(self, gid, buffer): logger.info("MatchmakeExtensionClientMK8D.update_application_buffer()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.buffer(buffer) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_APPLICATION_BUFFER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.update_application_buffer -> done") async def update_matchmake_session_attribute(self, gid, attribs): logger.info("MatchmakeExtensionClientMK8D.update_matchmake_session_attribute()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.list(attribs, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_MATCHMAKE_SESSION_ATTRIBUTE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.update_matchmake_session_attribute -> done") async def get_friend_notification_data_list(self, types): logger.info("MatchmakeExtensionClientMK8D.get_friend_notification_data_list()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(types, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_FRIEND_NOTIFICATION_DATA_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) notifications = stream.list(notification.NotificationEvent) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.get_friend_notification_data_list -> done") return notifications async def update_matchmake_session(self, gathering): logger.info("MatchmakeExtensionClientMK8D.update_matchmake_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(gathering) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_MATCHMAKE_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.update_matchmake_session -> done") async def auto_matchmake_with_search_criteria_postpone(self, search_criteria, gathering, message): logger.info("MatchmakeExtensionClientMK8D.auto_matchmake_with_search_criteria_postpone()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(search_criteria, stream.add) stream.anydata(gathering) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_AUTO_MATCHMAKE_WITH_SEARCH_CRITERIA_POSTPONE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gathering = stream.anydata() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.auto_matchmake_with_search_criteria_postpone -> done") return gathering async def get_playing_session(self, pids): logger.info("MatchmakeExtensionClientMK8D.get_playing_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_PLAYING_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) sessions = stream.list(PlayingSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.get_playing_session -> done") return sessions async def create_community(self, community, message): logger.info("MatchmakeExtensionClientMK8D.create_community()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(community) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CREATE_COMMUNITY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) gid = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.create_community -> done") return gid async def update_community(self, community): logger.info("MatchmakeExtensionClientMK8D.update_community()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(community) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_COMMUNITY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.update_community -> done") async def join_community(self, gid, message, password): logger.info("MatchmakeExtensionClientMK8D.join_community()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(message) stream.string(password) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_JOIN_COMMUNITY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.join_community -> done") async def find_community_by_gathering_id(self, gids): logger.info("MatchmakeExtensionClientMK8D.find_community_by_gathering_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_COMMUNITY_BY_GATHERING_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) communities = stream.list(PersistentGathering) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.find_community_by_gathering_id -> done") return communities async def find_official_community(self, available_only, range): logger.info("MatchmakeExtensionClientMK8D.find_official_community()") #--- request --- stream = streams.StreamOut(self.settings) stream.bool(available_only) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_OFFICIAL_COMMUNITY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) communities = stream.list(PersistentGathering) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.find_official_community -> done") return communities async def find_community_by_participant(self, pid, range): logger.info("MatchmakeExtensionClientMK8D.find_community_by_participant()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_COMMUNITY_BY_PARTICIPANT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) communities = stream.list(PersistentGathering) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.find_community_by_participant -> done") return communities async def update_privacy_setting(self, online_status, community_participation): logger.info("MatchmakeExtensionClientMK8D.update_privacy_setting()") #--- request --- stream = streams.StreamOut(self.settings) stream.bool(online_status) stream.bool(community_participation) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_PRIVACY_SETTING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.update_privacy_setting -> done") async def get_my_block_list(self): logger.info("MatchmakeExtensionClientMK8D.get_my_block_list()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_MY_BLOCK_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) pids = stream.list(stream.pid) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.get_my_block_list -> done") return pids async def add_to_block_list(self, pids): logger.info("MatchmakeExtensionClientMK8D.add_to_block_list()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_ADD_TO_BLOCK_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.add_to_block_list -> done") async def remove_from_block_list(self, pids): logger.info("MatchmakeExtensionClientMK8D.remove_from_block_list()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REMOVE_FROM_BLOCK_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.remove_from_block_list -> done") async def clear_my_block_list(self): logger.info("MatchmakeExtensionClientMK8D.clear_my_block_list()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CLEAR_MY_BLOCK_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.clear_my_block_list -> done") async def report_violation(self, pid, username, violation_code): logger.info("MatchmakeExtensionClientMK8D.report_violation()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) stream.string(username) stream.u32(violation_code) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REPORT_VIOLATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.report_violation -> done") async def is_violation_user(self): logger.info("MatchmakeExtensionClientMK8D.is_violation_user()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_IS_VIOLATION_USER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.flag = stream.bool() obj.score = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.is_violation_user -> done") return obj async def join_matchmake_session_ex(self, gid, gmessage, ignore_block_list, num_participants): logger.info("MatchmakeExtensionClientMK8D.join_matchmake_session_ex()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(gmessage) stream.bool(ignore_block_list) stream.u16(num_participants) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_JOIN_MATCHMAKE_SESSION_EX, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session_key = stream.buffer() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.join_matchmake_session_ex -> done") return session_key async def get_simple_playing_session(self, pids, include_login_user): logger.info("MatchmakeExtensionClientMK8D.get_simple_playing_session()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) stream.bool(include_login_user) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SIMPLE_PLAYING_SESSION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session = stream.list(SimplePlayingSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.get_simple_playing_session -> done") return session async def get_simple_community(self, gids): logger.info("MatchmakeExtensionClientMK8D.get_simple_community()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SIMPLE_COMMUNITY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) communities = stream.list(SimpleCommunity) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.get_simple_community -> done") return communities async def auto_matchmake_with_gathering_id_postpone(self, gids, gathering, message): logger.info("MatchmakeExtensionClientMK8D.auto_matchmake_with_gathering_id_postpone()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) stream.anydata(gathering) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_AUTO_MATCHMAKE_WITH_GATHERING_ID_POSTPONE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) joined_gathering = stream.anydata() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.auto_matchmake_with_gathering_id_postpone -> done") return joined_gathering async def update_progress_score(self, gid, score): logger.info("MatchmakeExtensionClientMK8D.update_progress_score()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.u8(score) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_PROGRESS_SCORE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.update_progress_score -> done") async def debug_notify_event(self, pid, main_type, sub_type, param1, param2, param3): logger.info("MatchmakeExtensionClientMK8D.debug_notify_event()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) stream.u32(main_type) stream.u32(sub_type) stream.u64(param1) stream.u64(param2) stream.string(param3) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DEBUG_NOTIFY_EVENT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.debug_notify_event -> done") async def generate_matchmake_session_system_password(self, gid): logger.info("MatchmakeExtensionClientMK8D.generate_matchmake_session_system_password()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GENERATE_MATCHMAKE_SESSION_SYSTEM_PASSWORD, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) password = stream.string() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.generate_matchmake_session_system_password -> done") return password async def clear_matchmake_session_system_password(self, gid): logger.info("MatchmakeExtensionClientMK8D.clear_matchmake_session_system_password()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CLEAR_MATCHMAKE_SESSION_SYSTEM_PASSWORD, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.clear_matchmake_session_system_password -> done") async def create_matchmake_session_with_param(self, param): logger.info("MatchmakeExtensionClientMK8D.create_matchmake_session_with_param()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CREATE_MATCHMAKE_SESSION_WITH_PARAM, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session = stream.extract(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.create_matchmake_session_with_param -> done") return session async def join_matchmake_session_with_param(self, param): logger.info("MatchmakeExtensionClientMK8D.join_matchmake_session_with_param()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_JOIN_MATCHMAKE_SESSION_WITH_PARAM, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session = stream.extract(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.join_matchmake_session_with_param -> done") return session async def auto_matchmake_with_param_postpone(self, param): logger.info("MatchmakeExtensionClientMK8D.auto_matchmake_with_param_postpone()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_AUTO_MATCHMAKE_WITH_PARAM_POSTPONE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session = stream.extract(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.auto_matchmake_with_param_postpone -> done") return session async def find_matchmake_session_by_gathering_id_detail(self, gid): logger.info("MatchmakeExtensionClientMK8D.find_matchmake_session_by_gathering_id_detail()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_MATCHMAKE_SESSION_BY_GATHERING_ID_DETAIL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session = stream.extract(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.find_matchmake_session_by_gathering_id_detail -> done") return session async def browse_matchmake_session_no_holder(self, search_criteria, range): logger.info("MatchmakeExtensionClientMK8D.browse_matchmake_session_no_holder()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) sessions = stream.list(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.browse_matchmake_session_no_holder -> done") return sessions async def browse_matchmake_session_with_host_urls_no_holder(self, search_criteria, range): logger.info("MatchmakeExtensionClientMK8D.browse_matchmake_session_with_host_urls_no_holder()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.sessions = stream.list(MatchmakeSession) obj.urls = stream.list(GatheringURLs) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.browse_matchmake_session_with_host_urls_no_holder -> done") return obj async def update_matchmake_session_part(self, param): logger.info("MatchmakeExtensionClientMK8D.update_matchmake_session_part()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_MATCHMAKE_SESSION_PART, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.update_matchmake_session_part -> done") async def request_matchmaking(self, param): logger.info("MatchmakeExtensionClientMK8D.request_matchmaking()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REQUEST_MATCHMAKING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) request_id = stream.u64() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.request_matchmaking -> done") return request_id async def withdraw_matchmaking(self, request_id): logger.info("MatchmakeExtensionClientMK8D.withdraw_matchmaking()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(request_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_WITHDRAW_MATCHMAKING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.withdraw_matchmaking -> done") async def withdraw_matchmaking_all(self): logger.info("MatchmakeExtensionClientMK8D.withdraw_matchmaking_all()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_WITHDRAW_MATCHMAKING_ALL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.withdraw_matchmaking_all -> done") async def find_matchmake_session_by_gathering_id(self, gids): logger.info("MatchmakeExtensionClientMK8D.find_matchmake_session_by_gathering_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(gids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_MATCHMAKE_SESSION_BY_GATHERING_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) sessions = stream.list(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.find_matchmake_session_by_gathering_id -> done") return sessions async def find_matchmake_session_by_single_gathering_id(self, gid): logger.info("MatchmakeExtensionClientMK8D.find_matchmake_session_by_single_gathering_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_MATCHMAKE_SESSION_BY_SINGLE_GATHERING_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session = stream.extract(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.find_matchmake_session_by_single_gathering_id -> done") return session async def find_matchmake_session_by_owner(self, pid, range): logger.info("MatchmakeExtensionClientMK8D.find_matchmake_session_by_owner()") #--- request --- stream = streams.StreamOut(self.settings) stream.pid(pid) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_MATCHMAKE_SESSION_BY_OWNER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) sessions = stream.list(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.find_matchmake_session_by_owner -> done") return sessions async def find_matchmake_session_by_participant(self, param): logger.info("MatchmakeExtensionClientMK8D.find_matchmake_session_by_participant()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_FIND_MATCHMAKE_SESSION_BY_PARTICIPANT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.list(FindMatchmakeSessionByParticipantResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.find_matchmake_session_by_participant -> done") return result async def browse_matchmake_session_no_holder_no_result_range(self, search_criteria): logger.info("MatchmakeExtensionClientMK8D.browse_matchmake_session_no_holder_no_result_range()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER_NO_RESULT_RANGE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) sessions = stream.list(MatchmakeSession) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.browse_matchmake_session_no_holder_no_result_range -> done") return sessions async def browse_matchmake_session_with_host_urls_no_holder_no_result_range(self, search_criteria): logger.info("MatchmakeExtensionClientMK8D.browse_matchmake_session_with_host_urls_no_holder_no_result_range()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(search_criteria) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER_NO_RESULT_RANGE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.sessions = stream.list(MatchmakeSession) obj.urls = stream.list(GatheringURLs) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.browse_matchmake_session_with_host_urls_no_holder_no_result_range -> done") return obj async def create_simple_search_object(self, object): logger.info("MatchmakeExtensionClientMK8D.create_simple_search_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(object) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CREATE_SIMPLE_SEARCH_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) id = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.create_simple_search_object -> done") return id async def update_simple_search_object(self, id, object): logger.info("MatchmakeExtensionClientMK8D.update_simple_search_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(id) stream.add(object) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_SIMPLE_SEARCH_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.update_simple_search_object -> done") async def delete_simple_search_object(self, id): logger.info("MatchmakeExtensionClientMK8D.delete_simple_search_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_SIMPLE_SEARCH_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.delete_simple_search_object -> done") async def search_simple_search_object(self, param): logger.info("MatchmakeExtensionClientMK8D.search_simple_search_object()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_SIMPLE_SEARCH_OBJECT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) objects = stream.list(SimpleSearchObject) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.search_simple_search_object -> done") return objects async def search_simple_search_object_by_object_ids(self, ids): logger.info("MatchmakeExtensionClientMK8D.search_simple_search_object_by_object_ids()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(ids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEARCH_SIMPLE_SEARCH_OBJECT_BY_OBJECT_IDS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) objects = stream.list(SimpleSearchObject) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.search_simple_search_object_by_object_ids -> done") return objects async def join_matchmake_session_with_extra_participants(self, gid, join_message, ignore_blacklist, participation_count, extra_participants): logger.info("MatchmakeExtensionClientMK8D.join_matchmake_session_with_extra_participants()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(gid) stream.string(join_message) stream.bool(ignore_blacklist) stream.u16(participation_count) stream.u32(extra_participants) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_JOIN_MATCHMAKE_SESSION_WITH_EXTRA_PARTICIPANTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) session_key = stream.buffer() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.join_matchmake_session_with_extra_participants -> done") return session_key async def create_competition(self, competition): logger.info("MatchmakeExtensionClientMK8D.create_competition()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(competition) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CREATE_COMPETITION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) competition = stream.extract(SimpleSearchObject) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.create_competition -> done") return competition async def delete_competition(self, id): logger.info("MatchmakeExtensionClientMK8D.delete_competition()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_COMPETITION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.delete_competition -> done") async def register_favorite_competition(self, id): logger.info("MatchmakeExtensionClientMK8D.register_favorite_competition()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REGISTER_FAVORITE_COMPETITION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.register_favorite_competition -> done") async def unregister_favorite_competition(self, id): logger.info("MatchmakeExtensionClientMK8D.unregister_favorite_competition()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UNREGISTER_FAVORITE_COMPETITION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.unregister_favorite_competition -> done") async def get_favorite_competition(self): logger.info("MatchmakeExtensionClientMK8D.get_favorite_competition()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_FAVORITE_COMPETITION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) competitions = stream.list(SimpleSearchObject) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MatchmakeExtensionClientMK8D.get_favorite_competition -> done") return competitions class MatchMakingServer(MatchMakingProtocol): def __init__(self): self.methods = { self.METHOD_REGISTER_GATHERING: self.handle_register_gathering, self.METHOD_UNREGISTER_GATHERING: self.handle_unregister_gathering, self.METHOD_UNREGISTER_GATHERINGS: self.handle_unregister_gatherings, self.METHOD_UPDATE_GATHERING: self.handle_update_gathering, self.METHOD_INVITE: self.handle_invite, self.METHOD_ACCEPT_INVITATION: self.handle_accept_invitation, self.METHOD_DECLINE_INVITATION: self.handle_decline_invitation, self.METHOD_CANCEL_INVITATION: self.handle_cancel_invitation, self.METHOD_GET_INVITATIONS_SENT: self.handle_get_invitations_sent, self.METHOD_GET_INVITATIONS_RECEIVED: self.handle_get_invitations_received, self.METHOD_PARTICIPATE: self.handle_participate, self.METHOD_CANCEL_PARTICIPATION: self.handle_cancel_participation, self.METHOD_GET_PARTICIPANTS: self.handle_get_participants, self.METHOD_ADD_PARTICIPANTS: self.handle_add_participants, self.METHOD_GET_DETAILED_PARTICIPANTS: self.handle_get_detailed_participants, self.METHOD_GET_PARTICIPANTS_URLS: self.handle_get_participants_urls, self.METHOD_FIND_BY_TYPE: self.handle_find_by_type, self.METHOD_FIND_BY_DESCRIPTION: self.handle_find_by_description, self.METHOD_FIND_BY_DESCRIPTION_REGEX: self.handle_find_by_description_regex, self.METHOD_FIND_BY_ID: self.handle_find_by_id, self.METHOD_FIND_BY_SINGLE_ID: self.handle_find_by_single_id, self.METHOD_FIND_BY_OWNER: self.handle_find_by_owner, self.METHOD_FIND_BY_PARTICIPANTS: self.handle_find_by_participants, self.METHOD_FIND_INVITATIONS: self.handle_find_invitations, self.METHOD_FIND_BY_SQL_QUERY: self.handle_find_by_sql_query, self.METHOD_LAUNCH_SESSION: self.handle_launch_session, self.METHOD_UPDATE_SESSION_URL: self.handle_update_session_url, self.METHOD_GET_SESSION_URL: self.handle_get_session_url, self.METHOD_GET_STATE: self.handle_get_state, self.METHOD_SET_STATE: self.handle_set_state, self.METHOD_REPORT_STATS: self.handle_report_stats, self.METHOD_GET_STATS: self.handle_get_stats, self.METHOD_DELETE_GATHERING: self.handle_delete_gathering, self.METHOD_GET_PENDING_DELETIONS: self.handle_get_pending_deletions, self.METHOD_DELETE_FROM_DELETIONS: self.handle_delete_from_deletions, self.METHOD_MIGRATE_GATHERING_OWNERSHIP_V1: self.handle_migrate_gathering_ownership_v1, self.METHOD_FIND_BY_DESCRIPTION_LIKE: self.handle_find_by_description_like, self.METHOD_REGISTER_LOCAL_URL: self.handle_register_local_url, self.METHOD_REGISTER_LOCAL_URLS: self.handle_register_local_urls, self.METHOD_UPDATE_SESSION_HOST_V1: self.handle_update_session_host_v1, self.METHOD_GET_SESSION_URLS: self.handle_get_session_urls, self.METHOD_UPDATE_SESSION_HOST: self.handle_update_session_host, self.METHOD_UPDATE_GATHERING_OWNERSHIP: self.handle_update_gathering_ownership, self.METHOD_MIGRATE_GATHERING_OWNERSHIP: self.handle_migrate_gathering_ownership, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on MatchMakingServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_register_gathering(self, client, input, output): logger.info("MatchMakingServer.register_gathering()") #--- request --- gathering = input.anydata() response = await self.register_gathering(client, gathering) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u32(response) async def handle_unregister_gathering(self, client, input, output): logger.info("MatchMakingServer.unregister_gathering()") #--- request --- gid = input.u32() response = await self.unregister_gathering(client, gid) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_unregister_gatherings(self, client, input, output): logger.info("MatchMakingServer.unregister_gatherings()") #--- request --- gids = input.list(input.u32) response = await self.unregister_gatherings(client, gids) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_update_gathering(self, client, input, output): logger.info("MatchMakingServer.update_gathering()") #--- request --- gathering = input.anydata() response = await self.update_gathering(client, gathering) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_invite(self, client, input, output): logger.info("MatchMakingServer.invite()") #--- request --- gid = input.u32() pids = input.list(input.pid) message = input.string() response = await self.invite(client, gid, pids, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_accept_invitation(self, client, input, output): logger.info("MatchMakingServer.accept_invitation()") #--- request --- gid = input.u32() message = input.string() response = await self.accept_invitation(client, gid, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_decline_invitation(self, client, input, output): logger.info("MatchMakingServer.decline_invitation()") #--- request --- gid = input.u32() message = input.string() response = await self.decline_invitation(client, gid, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_cancel_invitation(self, client, input, output): logger.info("MatchMakingServer.cancel_invitation()") #--- request --- gid = input.u32() pids = input.list(input.pid) message = input.string() response = await self.cancel_invitation(client, gid, pids, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_invitations_sent(self, client, input, output): logger.info("MatchMakingServer.get_invitations_sent()") #--- request --- gid = input.u32() response = await self.get_invitations_sent(client, gid) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_invitations_received(self, client, input, output): logger.info("MatchMakingServer.get_invitations_received()") #--- request --- response = await self.get_invitations_received(client) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_participate(self, client, input, output): logger.info("MatchMakingServer.participate()") #--- request --- gid = input.u32() message = input.string() response = await self.participate(client, gid, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_cancel_participation(self, client, input, output): logger.info("MatchMakingServer.cancel_participation()") #--- request --- gid = input.u32() message = input.string() response = await self.cancel_participation(client, gid, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_participants(self, client, input, output): logger.info("MatchMakingServer.get_participants()") #--- request --- gid = input.u32() response = await self.get_participants(client, gid) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.pid) async def handle_add_participants(self, client, input, output): logger.info("MatchMakingServer.add_participants()") #--- request --- gid = input.u32() pids = input.list(input.pid) message = input.string() response = await self.add_participants(client, gid, pids, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_detailed_participants(self, client, input, output): logger.info("MatchMakingServer.get_detailed_participants()") #--- request --- gid = input.u32() response = await self.get_detailed_participants(client, gid) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_participants_urls(self, client, input, output): logger.info("MatchMakingServer.get_participants_urls()") #--- request --- gid = input.u32() response = await self.get_participants_urls(client, gid) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.stationurl) async def handle_find_by_type(self, client, input, output): logger.info("MatchMakingServer.find_by_type()") #--- request --- type = input.string() range = input.extract(common.ResultRange) response = await self.find_by_type(client, type, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_description(self, client, input, output): logger.info("MatchMakingServer.find_by_description()") #--- request --- description = input.string() range = input.extract(common.ResultRange) response = await self.find_by_description(client, description, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_description_regex(self, client, input, output): logger.info("MatchMakingServer.find_by_description_regex()") #--- request --- regex = input.string() range = input.extract(common.ResultRange) response = await self.find_by_description_regex(client, regex, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_id(self, client, input, output): logger.info("MatchMakingServer.find_by_id()") #--- request --- ids = input.list(input.u32) response = await self.find_by_id(client, ids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_single_id(self, client, input, output): logger.info("MatchMakingServer.find_by_single_id()") #--- request --- gid = input.u32() response = await self.find_by_single_id(client, gid) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'gathering']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.anydata(response.gathering) async def handle_find_by_owner(self, client, input, output): logger.info("MatchMakingServer.find_by_owner()") #--- request --- owner = input.pid() range = input.extract(common.ResultRange) response = await self.find_by_owner(client, owner, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_participants(self, client, input, output): logger.info("MatchMakingServer.find_by_participants()") #--- request --- pids = input.list(input.pid) response = await self.find_by_participants(client, pids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_invitations(self, client, input, output): logger.info("MatchMakingServer.find_invitations()") #--- request --- range = input.extract(common.ResultRange) response = await self.find_invitations(client, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_find_by_sql_query(self, client, input, output): logger.info("MatchMakingServer.find_by_sql_query()") #--- request --- query = input.string() range = input.extract(common.ResultRange) response = await self.find_by_sql_query(client, query, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_launch_session(self, client, input, output): logger.info("MatchMakingServer.launch_session()") #--- request --- gid = input.u32() url = input.string() response = await self.launch_session(client, gid, url) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_update_session_url(self, client, input, output): logger.info("MatchMakingServer.update_session_url()") #--- request --- gid = input.u32() url = input.string() response = await self.update_session_url(client, gid, url) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_session_url(self, client, input, output): logger.info("MatchMakingServer.get_session_url()") #--- request --- gid = input.u32() response = await self.get_session_url(client, gid) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'url']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.string(response.url) async def handle_get_state(self, client, input, output): logger.info("MatchMakingServer.get_state()") #--- request --- gid = input.u32() response = await self.get_state(client, gid) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'state']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.u32(response.state) async def handle_set_state(self, client, input, output): logger.info("MatchMakingServer.set_state()") #--- request --- gid = input.u32() state = input.u32() response = await self.set_state(client, gid, state) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_report_stats(self, client, input, output): logger.info("MatchMakingServer.report_stats()") #--- request --- gid = input.u32() stats = input.list(GatheringStats) response = await self.report_stats(client, gid, stats) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_stats(self, client, input, output): logger.info("MatchMakingServer.get_stats()") #--- request --- gid = input.u32() pids = input.list(input.pid) columns = input.list(input.u8) response = await self.get_stats(client, gid, pids, columns) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'stats']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.list(response.stats, output.add) async def handle_delete_gathering(self, client, input, output): logger.info("MatchMakingServer.delete_gathering()") #--- request --- gid = input.u32() response = await self.delete_gathering(client, gid) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_pending_deletions(self, client, input, output): logger.info("MatchMakingServer.get_pending_deletions()") #--- request --- reason = input.u32() range = input.extract(common.ResultRange) response = await self.get_pending_deletions(client, reason, range) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'deletions']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.list(response.deletions, output.add) async def handle_delete_from_deletions(self, client, input, output): logger.info("MatchMakingServer.delete_from_deletions()") #--- request --- deletions = input.list(input.u32) response = await self.delete_from_deletions(client, deletions) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_migrate_gathering_ownership_v1(self, client, input, output): logger.info("MatchMakingServer.migrate_gathering_ownership_v1()") #--- request --- gid = input.u32() potential_owners = input.list(input.pid) response = await self.migrate_gathering_ownership_v1(client, gid, potential_owners) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_find_by_description_like(self, client, input, output): logger.info("MatchMakingServer.find_by_description_like()") #--- request --- description = input.string() range = input.extract(common.ResultRange) response = await self.find_by_description_like(client, description, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_register_local_url(self, client, input, output): logger.info("MatchMakingServer.register_local_url()") #--- request --- gid = input.u32() url = input.stationurl() await self.register_local_url(client, gid, url) async def handle_register_local_urls(self, client, input, output): logger.info("MatchMakingServer.register_local_urls()") #--- request --- gid = input.u32() urls = input.list(input.stationurl) await self.register_local_urls(client, gid, urls) async def handle_update_session_host_v1(self, client, input, output): logger.info("MatchMakingServer.update_session_host_v1()") #--- request --- gid = input.u32() await self.update_session_host_v1(client, gid) async def handle_get_session_urls(self, client, input, output): logger.info("MatchMakingServer.get_session_urls()") #--- request --- gid = input.u32() response = await self.get_session_urls(client, gid) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.stationurl) async def handle_update_session_host(self, client, input, output): logger.info("MatchMakingServer.update_session_host()") #--- request --- gid = input.u32() is_migrate_owner = input.bool() await self.update_session_host(client, gid, is_migrate_owner) async def handle_update_gathering_ownership(self, client, input, output): logger.info("MatchMakingServer.update_gathering_ownership()") #--- request --- gid = input.u32() participants_only = input.bool() response = await self.update_gathering_ownership(client, gid, participants_only) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_migrate_gathering_ownership(self, client, input, output): logger.info("MatchMakingServer.migrate_gathering_ownership()") #--- request --- gid = input.u32() potential_owners = input.list(input.pid) participants_only = input.bool() await self.migrate_gathering_ownership(client, gid, potential_owners, participants_only) async def register_gathering(self, *args): logger.warning("MatchMakingServer.register_gathering not implemented") raise common.RMCError("Core::NotImplemented") async def unregister_gathering(self, *args): logger.warning("MatchMakingServer.unregister_gathering not implemented") raise common.RMCError("Core::NotImplemented") async def unregister_gatherings(self, *args): logger.warning("MatchMakingServer.unregister_gatherings not implemented") raise common.RMCError("Core::NotImplemented") async def update_gathering(self, *args): logger.warning("MatchMakingServer.update_gathering not implemented") raise common.RMCError("Core::NotImplemented") async def invite(self, *args): logger.warning("MatchMakingServer.invite not implemented") raise common.RMCError("Core::NotImplemented") async def accept_invitation(self, *args): logger.warning("MatchMakingServer.accept_invitation not implemented") raise common.RMCError("Core::NotImplemented") async def decline_invitation(self, *args): logger.warning("MatchMakingServer.decline_invitation not implemented") raise common.RMCError("Core::NotImplemented") async def cancel_invitation(self, *args): logger.warning("MatchMakingServer.cancel_invitation not implemented") raise common.RMCError("Core::NotImplemented") async def get_invitations_sent(self, *args): logger.warning("MatchMakingServer.get_invitations_sent not implemented") raise common.RMCError("Core::NotImplemented") async def get_invitations_received(self, *args): logger.warning("MatchMakingServer.get_invitations_received not implemented") raise common.RMCError("Core::NotImplemented") async def participate(self, *args): logger.warning("MatchMakingServer.participate not implemented") raise common.RMCError("Core::NotImplemented") async def cancel_participation(self, *args): logger.warning("MatchMakingServer.cancel_participation not implemented") raise common.RMCError("Core::NotImplemented") async def get_participants(self, *args): logger.warning("MatchMakingServer.get_participants not implemented") raise common.RMCError("Core::NotImplemented") async def add_participants(self, *args): logger.warning("MatchMakingServer.add_participants not implemented") raise common.RMCError("Core::NotImplemented") async def get_detailed_participants(self, *args): logger.warning("MatchMakingServer.get_detailed_participants not implemented") raise common.RMCError("Core::NotImplemented") async def get_participants_urls(self, *args): logger.warning("MatchMakingServer.get_participants_urls not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_type(self, *args): logger.warning("MatchMakingServer.find_by_type not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_description(self, *args): logger.warning("MatchMakingServer.find_by_description not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_description_regex(self, *args): logger.warning("MatchMakingServer.find_by_description_regex not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_id(self, *args): logger.warning("MatchMakingServer.find_by_id not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_single_id(self, *args): logger.warning("MatchMakingServer.find_by_single_id not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_owner(self, *args): logger.warning("MatchMakingServer.find_by_owner not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_participants(self, *args): logger.warning("MatchMakingServer.find_by_participants not implemented") raise common.RMCError("Core::NotImplemented") async def find_invitations(self, *args): logger.warning("MatchMakingServer.find_invitations not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_sql_query(self, *args): logger.warning("MatchMakingServer.find_by_sql_query not implemented") raise common.RMCError("Core::NotImplemented") async def launch_session(self, *args): logger.warning("MatchMakingServer.launch_session not implemented") raise common.RMCError("Core::NotImplemented") async def update_session_url(self, *args): logger.warning("MatchMakingServer.update_session_url not implemented") raise common.RMCError("Core::NotImplemented") async def get_session_url(self, *args): logger.warning("MatchMakingServer.get_session_url not implemented") raise common.RMCError("Core::NotImplemented") async def get_state(self, *args): logger.warning("MatchMakingServer.get_state not implemented") raise common.RMCError("Core::NotImplemented") async def set_state(self, *args): logger.warning("MatchMakingServer.set_state not implemented") raise common.RMCError("Core::NotImplemented") async def report_stats(self, *args): logger.warning("MatchMakingServer.report_stats not implemented") raise common.RMCError("Core::NotImplemented") async def get_stats(self, *args): logger.warning("MatchMakingServer.get_stats not implemented") raise common.RMCError("Core::NotImplemented") async def delete_gathering(self, *args): logger.warning("MatchMakingServer.delete_gathering not implemented") raise common.RMCError("Core::NotImplemented") async def get_pending_deletions(self, *args): logger.warning("MatchMakingServer.get_pending_deletions not implemented") raise common.RMCError("Core::NotImplemented") async def delete_from_deletions(self, *args): logger.warning("MatchMakingServer.delete_from_deletions not implemented") raise common.RMCError("Core::NotImplemented") async def migrate_gathering_ownership_v1(self, *args): logger.warning("MatchMakingServer.migrate_gathering_ownership_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def find_by_description_like(self, *args): logger.warning("MatchMakingServer.find_by_description_like not implemented") raise common.RMCError("Core::NotImplemented") async def register_local_url(self, *args): logger.warning("MatchMakingServer.register_local_url not implemented") raise common.RMCError("Core::NotImplemented") async def register_local_urls(self, *args): logger.warning("MatchMakingServer.register_local_urls not implemented") raise common.RMCError("Core::NotImplemented") async def update_session_host_v1(self, *args): logger.warning("MatchMakingServer.update_session_host_v1 not implemented") raise common.RMCError("Core::NotImplemented") async def get_session_urls(self, *args): logger.warning("MatchMakingServer.get_session_urls not implemented") raise common.RMCError("Core::NotImplemented") async def update_session_host(self, *args): logger.warning("MatchMakingServer.update_session_host not implemented") raise common.RMCError("Core::NotImplemented") async def update_gathering_ownership(self, *args): logger.warning("MatchMakingServer.update_gathering_ownership not implemented") raise common.RMCError("Core::NotImplemented") async def migrate_gathering_ownership(self, *args): logger.warning("MatchMakingServer.migrate_gathering_ownership not implemented") raise common.RMCError("Core::NotImplemented") class MatchMakingServerExt(MatchMakingProtocolExt): def __init__(self): self.methods = { self.METHOD_END_PARTICIPATION: self.handle_end_participation, self.METHOD_GET_PARTICIPANTS: self.handle_get_participants, self.METHOD_GET_DETAILED_PARTICIPANTS: self.handle_get_detailed_participants, self.METHOD_GET_PARTICIPANTS_URLS: self.handle_get_participants_urls, self.METHOD_GET_GATHERING_RELATIONS: self.handle_get_gathering_relations, self.METHOD_DELETE_FROM_DELETIONS: self.handle_delete_from_deletions, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on MatchMakingServerExt: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_end_participation(self, client, input, output): logger.info("MatchMakingServerExt.end_participation()") #--- request --- gid = input.u32() message = input.string() response = await self.end_participation(client, gid, message) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_participants(self, client, input, output): logger.info("MatchMakingServerExt.get_participants()") #--- request --- gid = input.u32() only_active = input.bool() response = await self.get_participants(client, gid, only_active) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.pid) async def handle_get_detailed_participants(self, client, input, output): logger.info("MatchMakingServerExt.get_detailed_participants()") #--- request --- gid = input.u32() only_active = input.bool() response = await self.get_detailed_participants(client, gid, only_active) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_participants_urls(self, client, input, output): logger.info("MatchMakingServerExt.get_participants_urls()") #--- request --- gids = input.list(input.u32) response = await self.get_participants_urls(client, gids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_gathering_relations(self, client, input, output): logger.info("MatchMakingServerExt.get_gathering_relations()") #--- request --- id = input.u32() descr = input.string() response = await self.get_gathering_relations(client, id, descr) #--- response --- if not isinstance(response, str): raise RuntimeError("Expected str, got %s" %response.__class__.__name__) output.string(response) async def handle_delete_from_deletions(self, client, input, output): logger.info("MatchMakingServerExt.delete_from_deletions()") #--- request --- deletions = input.list(input.u32) pid = input.pid() await self.delete_from_deletions(client, deletions, pid) async def end_participation(self, *args): logger.warning("MatchMakingServerExt.end_participation not implemented") raise common.RMCError("Core::NotImplemented") async def get_participants(self, *args): logger.warning("MatchMakingServerExt.get_participants not implemented") raise common.RMCError("Core::NotImplemented") async def get_detailed_participants(self, *args): logger.warning("MatchMakingServerExt.get_detailed_participants not implemented") raise common.RMCError("Core::NotImplemented") async def get_participants_urls(self, *args): logger.warning("MatchMakingServerExt.get_participants_urls not implemented") raise common.RMCError("Core::NotImplemented") async def get_gathering_relations(self, *args): logger.warning("MatchMakingServerExt.get_gathering_relations not implemented") raise common.RMCError("Core::NotImplemented") async def delete_from_deletions(self, *args): logger.warning("MatchMakingServerExt.delete_from_deletions not implemented") raise common.RMCError("Core::NotImplemented") class MatchmakeRefereeServer(MatchmakeRefereeProtocol): def __init__(self): self.methods = { self.METHOD_START_ROUND: self.handle_start_round, self.METHOD_GET_START_ROUND_PARAM: self.handle_get_start_round_param, self.METHOD_END_ROUND: self.handle_end_round, self.METHOD_END_ROUND_WITHOUT_REPORT: self.handle_end_round_without_report, self.METHOD_GET_ROUND_PARTICIPANTS: self.handle_get_round_participants, self.METHOD_GET_NOT_SUMMARIZED_ROUND: self.handle_get_not_summarized_round, self.METHOD_GET_ROUND: self.handle_get_round, self.METHOD_GET_STATS_PRIMARY: self.handle_get_stats_primary, self.METHOD_GET_STATS_PRIMARIES: self.handle_get_stats_primaries, self.METHOD_GET_STATS_ALL: self.handle_get_stats_all, self.METHOD_CREATE_STATS: self.handle_create_stats, self.METHOD_GET_OR_CREATE_STATS: self.handle_get_or_create_stats, self.METHOD_RESET_STATS: self.handle_reset_stats, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on MatchmakeRefereeServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_start_round(self, client, input, output): logger.info("MatchmakeRefereeServer.start_round()") #--- request --- param = input.extract(MatchmakeRefereeStartRoundParam) response = await self.start_round(client, param) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u64(response) async def handle_get_start_round_param(self, client, input, output): logger.info("MatchmakeRefereeServer.get_start_round_param()") #--- request --- round_id = input.u64() response = await self.get_start_round_param(client, round_id) #--- response --- if not isinstance(response, MatchmakeRefereeStartRoundParam): raise RuntimeError("Expected MatchmakeRefereeStartRoundParam, got %s" %response.__class__.__name__) output.add(response) async def handle_end_round(self, client, input, output): logger.info("MatchmakeRefereeServer.end_round()") #--- request --- param = input.extract(MatchmakeRefereeEndRoundParam) await self.end_round(client, param) async def handle_end_round_without_report(self, client, input, output): logger.info("MatchmakeRefereeServer.end_round_without_report()") #--- request --- round_id = input.u64() await self.end_round_without_report(client, round_id) async def handle_get_round_participants(self, client, input, output): logger.info("MatchmakeRefereeServer.get_round_participants()") #--- request --- round_id = input.u64() response = await self.get_round_participants(client, round_id) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.pid) async def handle_get_not_summarized_round(self, client, input, output): logger.info("MatchmakeRefereeServer.get_not_summarized_round()") #--- request --- response = await self.get_not_summarized_round(client) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_round(self, client, input, output): logger.info("MatchmakeRefereeServer.get_round()") #--- request --- round = input.u64() response = await self.get_round(client, round) #--- response --- if not isinstance(response, MatchmakeRefereeRound): raise RuntimeError("Expected MatchmakeRefereeRound, got %s" %response.__class__.__name__) output.add(response) async def handle_get_stats_primary(self, client, input, output): logger.info("MatchmakeRefereeServer.get_stats_primary()") #--- request --- target = input.extract(MatchmakeRefereeStatsTarget) response = await self.get_stats_primary(client, target) #--- response --- if not isinstance(response, MatchmakeRefereeStats): raise RuntimeError("Expected MatchmakeRefereeStats, got %s" %response.__class__.__name__) output.add(response) async def handle_get_stats_primaries(self, client, input, output): logger.info("MatchmakeRefereeServer.get_stats_primaries()") #--- request --- targets = input.list(MatchmakeRefereeStatsTarget) response = await self.get_stats_primaries(client, targets) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['stats', 'results']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.stats, output.add) output.list(response.results, output.result) async def handle_get_stats_all(self, client, input, output): logger.info("MatchmakeRefereeServer.get_stats_all()") #--- request --- target = input.extract(MatchmakeRefereeStatsTarget) response = await self.get_stats_all(client, target) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_create_stats(self, client, input, output): logger.info("MatchmakeRefereeServer.create_stats()") #--- request --- param = input.extract(MatchmakeRefereeStatsInitParam) response = await self.create_stats(client, param) #--- response --- if not isinstance(response, MatchmakeRefereeStats): raise RuntimeError("Expected MatchmakeRefereeStats, got %s" %response.__class__.__name__) output.add(response) async def handle_get_or_create_stats(self, client, input, output): logger.info("MatchmakeRefereeServer.get_or_create_stats()") #--- request --- param = input.extract(MatchmakeRefereeStatsInitParam) response = await self.get_or_create_stats(client, param) #--- response --- if not isinstance(response, MatchmakeRefereeStats): raise RuntimeError("Expected MatchmakeRefereeStats, got %s" %response.__class__.__name__) output.add(response) async def handle_reset_stats(self, client, input, output): logger.info("MatchmakeRefereeServer.reset_stats()") #--- request --- await self.reset_stats(client) async def start_round(self, *args): logger.warning("MatchmakeRefereeServer.start_round not implemented") raise common.RMCError("Core::NotImplemented") async def get_start_round_param(self, *args): logger.warning("MatchmakeRefereeServer.get_start_round_param not implemented") raise common.RMCError("Core::NotImplemented") async def end_round(self, *args): logger.warning("MatchmakeRefereeServer.end_round not implemented") raise common.RMCError("Core::NotImplemented") async def end_round_without_report(self, *args): logger.warning("MatchmakeRefereeServer.end_round_without_report not implemented") raise common.RMCError("Core::NotImplemented") async def get_round_participants(self, *args): logger.warning("MatchmakeRefereeServer.get_round_participants not implemented") raise common.RMCError("Core::NotImplemented") async def get_not_summarized_round(self, *args): logger.warning("MatchmakeRefereeServer.get_not_summarized_round not implemented") raise common.RMCError("Core::NotImplemented") async def get_round(self, *args): logger.warning("MatchmakeRefereeServer.get_round not implemented") raise common.RMCError("Core::NotImplemented") async def get_stats_primary(self, *args): logger.warning("MatchmakeRefereeServer.get_stats_primary not implemented") raise common.RMCError("Core::NotImplemented") async def get_stats_primaries(self, *args): logger.warning("MatchmakeRefereeServer.get_stats_primaries not implemented") raise common.RMCError("Core::NotImplemented") async def get_stats_all(self, *args): logger.warning("MatchmakeRefereeServer.get_stats_all not implemented") raise common.RMCError("Core::NotImplemented") async def create_stats(self, *args): logger.warning("MatchmakeRefereeServer.create_stats not implemented") raise common.RMCError("Core::NotImplemented") async def get_or_create_stats(self, *args): logger.warning("MatchmakeRefereeServer.get_or_create_stats not implemented") raise common.RMCError("Core::NotImplemented") async def reset_stats(self, *args): logger.warning("MatchmakeRefereeServer.reset_stats not implemented") raise common.RMCError("Core::NotImplemented") class MatchmakeExtensionServerMK8D(MatchmakeExtensionProtocolMK8D): def __init__(self): self.methods = { self.METHOD_CLOSE_PARTICIPATION: self.handle_close_participation, self.METHOD_OPEN_PARTICIPATION: self.handle_open_participation, self.METHOD_AUTO_MATCHMAKE_POSTPONE: self.handle_auto_matchmake_postpone, self.METHOD_BROWSE_MATCHMAKE_SESSION: self.handle_browse_matchmake_session, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS: self.handle_browse_matchmake_session_with_host_urls, self.METHOD_CREATE_MATCHMAKE_SESSION: self.handle_create_matchmake_session, self.METHOD_JOIN_MATCHMAKE_SESSION: self.handle_join_matchmake_session, self.METHOD_MODIFY_CURRENT_GAME_ATTRIBUTE: self.handle_modify_current_game_attribute, self.METHOD_UPDATE_NOTIFICATION_DATA: self.handle_update_notification_data, self.METHOD_GET_FRIEND_NOTIFICATION_DATA: self.handle_get_friend_notification_data, self.METHOD_UPDATE_APPLICATION_BUFFER: self.handle_update_application_buffer, self.METHOD_UPDATE_MATCHMAKE_SESSION_ATTRIBUTE: self.handle_update_matchmake_session_attribute, self.METHOD_GET_FRIEND_NOTIFICATION_DATA_LIST: self.handle_get_friend_notification_data_list, self.METHOD_UPDATE_MATCHMAKE_SESSION: self.handle_update_matchmake_session, self.METHOD_AUTO_MATCHMAKE_WITH_SEARCH_CRITERIA_POSTPONE: self.handle_auto_matchmake_with_search_criteria_postpone, self.METHOD_GET_PLAYING_SESSION: self.handle_get_playing_session, self.METHOD_CREATE_COMMUNITY: self.handle_create_community, self.METHOD_UPDATE_COMMUNITY: self.handle_update_community, self.METHOD_JOIN_COMMUNITY: self.handle_join_community, self.METHOD_FIND_COMMUNITY_BY_GATHERING_ID: self.handle_find_community_by_gathering_id, self.METHOD_FIND_OFFICIAL_COMMUNITY: self.handle_find_official_community, self.METHOD_FIND_COMMUNITY_BY_PARTICIPANT: self.handle_find_community_by_participant, self.METHOD_UPDATE_PRIVACY_SETTING: self.handle_update_privacy_setting, self.METHOD_GET_MY_BLOCK_LIST: self.handle_get_my_block_list, self.METHOD_ADD_TO_BLOCK_LIST: self.handle_add_to_block_list, self.METHOD_REMOVE_FROM_BLOCK_LIST: self.handle_remove_from_block_list, self.METHOD_CLEAR_MY_BLOCK_LIST: self.handle_clear_my_block_list, self.METHOD_REPORT_VIOLATION: self.handle_report_violation, self.METHOD_IS_VIOLATION_USER: self.handle_is_violation_user, self.METHOD_JOIN_MATCHMAKE_SESSION_EX: self.handle_join_matchmake_session_ex, self.METHOD_GET_SIMPLE_PLAYING_SESSION: self.handle_get_simple_playing_session, self.METHOD_GET_SIMPLE_COMMUNITY: self.handle_get_simple_community, self.METHOD_AUTO_MATCHMAKE_WITH_GATHERING_ID_POSTPONE: self.handle_auto_matchmake_with_gathering_id_postpone, self.METHOD_UPDATE_PROGRESS_SCORE: self.handle_update_progress_score, self.METHOD_DEBUG_NOTIFY_EVENT: self.handle_debug_notify_event, self.METHOD_GENERATE_MATCHMAKE_SESSION_SYSTEM_PASSWORD: self.handle_generate_matchmake_session_system_password, self.METHOD_CLEAR_MATCHMAKE_SESSION_SYSTEM_PASSWORD: self.handle_clear_matchmake_session_system_password, self.METHOD_CREATE_MATCHMAKE_SESSION_WITH_PARAM: self.handle_create_matchmake_session_with_param, self.METHOD_JOIN_MATCHMAKE_SESSION_WITH_PARAM: self.handle_join_matchmake_session_with_param, self.METHOD_AUTO_MATCHMAKE_WITH_PARAM_POSTPONE: self.handle_auto_matchmake_with_param_postpone, self.METHOD_FIND_MATCHMAKE_SESSION_BY_GATHERING_ID_DETAIL: self.handle_find_matchmake_session_by_gathering_id_detail, self.METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER: self.handle_browse_matchmake_session_no_holder, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER: self.handle_browse_matchmake_session_with_host_urls_no_holder, self.METHOD_UPDATE_MATCHMAKE_SESSION_PART: self.handle_update_matchmake_session_part, self.METHOD_REQUEST_MATCHMAKING: self.handle_request_matchmaking, self.METHOD_WITHDRAW_MATCHMAKING: self.handle_withdraw_matchmaking, self.METHOD_WITHDRAW_MATCHMAKING_ALL: self.handle_withdraw_matchmaking_all, self.METHOD_FIND_MATCHMAKE_SESSION_BY_GATHERING_ID: self.handle_find_matchmake_session_by_gathering_id, self.METHOD_FIND_MATCHMAKE_SESSION_BY_SINGLE_GATHERING_ID: self.handle_find_matchmake_session_by_single_gathering_id, self.METHOD_FIND_MATCHMAKE_SESSION_BY_OWNER: self.handle_find_matchmake_session_by_owner, self.METHOD_FIND_MATCHMAKE_SESSION_BY_PARTICIPANT: self.handle_find_matchmake_session_by_participant, self.METHOD_BROWSE_MATCHMAKE_SESSION_NO_HOLDER_NO_RESULT_RANGE: self.handle_browse_matchmake_session_no_holder_no_result_range, self.METHOD_BROWSE_MATCHMAKE_SESSION_WITH_HOST_URLS_NO_HOLDER_NO_RESULT_RANGE: self.handle_browse_matchmake_session_with_host_urls_no_holder_no_result_range, self.METHOD_CREATE_SIMPLE_SEARCH_OBJECT: self.handle_create_simple_search_object, self.METHOD_UPDATE_SIMPLE_SEARCH_OBJECT: self.handle_update_simple_search_object, self.METHOD_DELETE_SIMPLE_SEARCH_OBJECT: self.handle_delete_simple_search_object, self.METHOD_SEARCH_SIMPLE_SEARCH_OBJECT: self.handle_search_simple_search_object, self.METHOD_SEARCH_SIMPLE_SEARCH_OBJECT_BY_OBJECT_IDS: self.handle_search_simple_search_object_by_object_ids, self.METHOD_JOIN_MATCHMAKE_SESSION_WITH_EXTRA_PARTICIPANTS: self.handle_join_matchmake_session_with_extra_participants, self.METHOD_CUSTOM_GET_SIMPLE_PLAYING_SESSION: self.handle_custom_get_simple_playing_session, self.METHOD_CREATE_COMPETITION: self.handle_create_competition, self.METHOD_DELETE_COMPETITION: self.handle_delete_competition, self.METHOD_REGISTER_FAVORITE_COMPETITION: self.handle_register_favorite_competition, self.METHOD_UNREGISTER_FAVORITE_COMPETITION: self.handle_unregister_favorite_competition, self.METHOD_GET_FAVORITE_COMPETITION: self.handle_get_favorite_competition, self.METHOD_GET_TEAM_PARTICIPANTS: self.handle_get_team_participants, self.METHOD_FIND_COMMUNITY_BY_OWNER: self.handle_find_community_by_owner, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on MatchmakeExtensionServerMK8D: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_close_participation(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.close_participation()") #--- request --- gid = input.u32() await self.close_participation(client, gid) async def handle_open_participation(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.open_participation()") #--- request --- gid = input.u32() await self.open_participation(client, gid) async def handle_auto_matchmake_postpone(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.auto_matchmake_postpone()") #--- request --- gathering = input.anydata() message = input.string() response = await self.auto_matchmake_postpone(client, gathering, message) #--- response --- if not isinstance(response, Gathering): raise RuntimeError("Expected Gathering, got %s" %response.__class__.__name__) output.anydata(response) async def handle_browse_matchmake_session(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.browse_matchmake_session()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) range = input.extract(common.ResultRange) response = await self.browse_matchmake_session(client, search_criteria, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_browse_matchmake_session_with_host_urls(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.browse_matchmake_session_with_host_urls()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) range = input.extract(common.ResultRange) response = await self.browse_matchmake_session_with_host_urls(client, search_criteria, range) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['gatherings', 'urls']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.gatherings, output.anydata) output.list(response.urls, output.add) async def handle_create_matchmake_session(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.create_matchmake_session()") #--- request --- gathering = input.anydata() description = input.string() num_participants = input.u16() response = await self.create_matchmake_session(client, gathering, description, num_participants) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['gid', 'session_key']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.u32(response.gid) output.buffer(response.session_key) async def handle_join_matchmake_session(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.join_matchmake_session()") #--- request --- gid = input.u32() message = input.string() response = await self.join_matchmake_session(client, gid, message) #--- response --- if not isinstance(response, bytes): raise RuntimeError("Expected bytes, got %s" %response.__class__.__name__) output.buffer(response) async def handle_modify_current_game_attribute(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.modify_current_game_attribute()") #--- request --- gid = input.u32() attrib = input.u32() value = input.u32() await self.modify_current_game_attribute(client, gid, attrib, value) async def handle_update_notification_data(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.update_notification_data()") #--- request --- type = input.u32() param1 = input.pid() param2 = input.pid() param3 = input.string() await self.update_notification_data(client, type, param1, param2, param3) async def handle_get_friend_notification_data(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.get_friend_notification_data()") #--- request --- type = input.s32() response = await self.get_friend_notification_data(client, type) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_update_application_buffer(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.update_application_buffer()") #--- request --- gid = input.u32() buffer = input.buffer() await self.update_application_buffer(client, gid, buffer) async def handle_update_matchmake_session_attribute(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.update_matchmake_session_attribute()") #--- request --- gid = input.u32() attribs = input.list(input.u32) await self.update_matchmake_session_attribute(client, gid, attribs) async def handle_get_friend_notification_data_list(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.get_friend_notification_data_list()") #--- request --- types = input.list(input.u32) response = await self.get_friend_notification_data_list(client, types) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_update_matchmake_session(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.update_matchmake_session()") #--- request --- gathering = input.anydata() await self.update_matchmake_session(client, gathering) async def handle_auto_matchmake_with_search_criteria_postpone(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.auto_matchmake_with_search_criteria_postpone()") #--- request --- search_criteria = input.list(MatchmakeSessionSearchCriteria) gathering = input.anydata() message = input.string() response = await self.auto_matchmake_with_search_criteria_postpone(client, search_criteria, gathering, message) #--- response --- if not isinstance(response, Gathering): raise RuntimeError("Expected Gathering, got %s" %response.__class__.__name__) output.anydata(response) async def handle_get_playing_session(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.get_playing_session()") #--- request --- pids = input.list(input.pid) response = await self.get_playing_session(client, pids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_create_community(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.create_community()") #--- request --- community = input.extract(PersistentGathering) message = input.string() response = await self.create_community(client, community, message) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u32(response) async def handle_update_community(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.update_community()") #--- request --- community = input.extract(PersistentGathering) await self.update_community(client, community) async def handle_join_community(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.join_community()") #--- request --- gid = input.u32() message = input.string() password = input.string() await self.join_community(client, gid, message, password) async def handle_find_community_by_gathering_id(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.find_community_by_gathering_id()") #--- request --- gids = input.list(input.u32) response = await self.find_community_by_gathering_id(client, gids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_find_official_community(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.find_official_community()") #--- request --- available_only = input.bool() range = input.extract(common.ResultRange) response = await self.find_official_community(client, available_only, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_find_community_by_participant(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.find_community_by_participant()") #--- request --- pid = input.pid() range = input.extract(common.ResultRange) response = await self.find_community_by_participant(client, pid, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_update_privacy_setting(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.update_privacy_setting()") #--- request --- online_status = input.bool() community_participation = input.bool() await self.update_privacy_setting(client, online_status, community_participation) async def handle_get_my_block_list(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.get_my_block_list()") #--- request --- response = await self.get_my_block_list(client) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.pid) async def handle_add_to_block_list(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.add_to_block_list()") #--- request --- pids = input.list(input.pid) await self.add_to_block_list(client, pids) async def handle_remove_from_block_list(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.remove_from_block_list()") #--- request --- pids = input.list(input.pid) await self.remove_from_block_list(client, pids) async def handle_clear_my_block_list(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.clear_my_block_list()") #--- request --- await self.clear_my_block_list(client) async def handle_report_violation(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.report_violation()") #--- request --- pid = input.pid() username = input.string() violation_code = input.u32() await self.report_violation(client, pid, username, violation_code) async def handle_is_violation_user(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.is_violation_user()") #--- request --- response = await self.is_violation_user(client) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['flag', 'score']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.flag) output.u32(response.score) async def handle_join_matchmake_session_ex(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.join_matchmake_session_ex()") #--- request --- gid = input.u32() gmessage = input.string() ignore_block_list = input.bool() num_participants = input.u16() response = await self.join_matchmake_session_ex(client, gid, gmessage, ignore_block_list, num_participants) #--- response --- if not isinstance(response, bytes): raise RuntimeError("Expected bytes, got %s" %response.__class__.__name__) output.buffer(response) async def handle_get_simple_playing_session(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.get_simple_playing_session()") #--- request --- pids = input.list(input.pid) include_login_user = input.bool() response = await self.get_simple_playing_session(client, pids, include_login_user) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_simple_community(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.get_simple_community()") #--- request --- gids = input.list(input.u32) response = await self.get_simple_community(client, gids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_auto_matchmake_with_gathering_id_postpone(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.auto_matchmake_with_gathering_id_postpone()") #--- request --- gids = input.list(input.u32) gathering = input.anydata() message = input.string() response = await self.auto_matchmake_with_gathering_id_postpone(client, gids, gathering, message) #--- response --- if not isinstance(response, Gathering): raise RuntimeError("Expected Gathering, got %s" %response.__class__.__name__) output.anydata(response) async def handle_update_progress_score(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.update_progress_score()") #--- request --- gid = input.u32() score = input.u8() await self.update_progress_score(client, gid, score) async def handle_debug_notify_event(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.debug_notify_event()") #--- request --- pid = input.pid() main_type = input.u32() sub_type = input.u32() param1 = input.u64() param2 = input.u64() param3 = input.string() await self.debug_notify_event(client, pid, main_type, sub_type, param1, param2, param3) async def handle_generate_matchmake_session_system_password(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.generate_matchmake_session_system_password()") #--- request --- gid = input.u32() response = await self.generate_matchmake_session_system_password(client, gid) #--- response --- if not isinstance(response, str): raise RuntimeError("Expected str, got %s" %response.__class__.__name__) output.string(response) async def handle_clear_matchmake_session_system_password(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.clear_matchmake_session_system_password()") #--- request --- gid = input.u32() await self.clear_matchmake_session_system_password(client, gid) async def handle_create_matchmake_session_with_param(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.create_matchmake_session_with_param()") #--- request --- param = input.extract(CreateMatchmakeSessionParam) response = await self.create_matchmake_session_with_param(client, param) #--- response --- if not isinstance(response, MatchmakeSession): raise RuntimeError("Expected MatchmakeSession, got %s" %response.__class__.__name__) output.add(response) async def handle_join_matchmake_session_with_param(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.join_matchmake_session_with_param()") #--- request --- param = input.extract(JoinMatchmakeSessionParam) response = await self.join_matchmake_session_with_param(client, param) #--- response --- if not isinstance(response, MatchmakeSession): raise RuntimeError("Expected MatchmakeSession, got %s" %response.__class__.__name__) output.add(response) async def handle_auto_matchmake_with_param_postpone(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.auto_matchmake_with_param_postpone()") #--- request --- param = input.extract(AutoMatchmakeParam) response = await self.auto_matchmake_with_param_postpone(client, param) #--- response --- if not isinstance(response, MatchmakeSession): raise RuntimeError("Expected MatchmakeSession, got %s" %response.__class__.__name__) output.add(response) async def handle_find_matchmake_session_by_gathering_id_detail(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.find_matchmake_session_by_gathering_id_detail()") #--- request --- gid = input.u32() response = await self.find_matchmake_session_by_gathering_id_detail(client, gid) #--- response --- if not isinstance(response, MatchmakeSession): raise RuntimeError("Expected MatchmakeSession, got %s" %response.__class__.__name__) output.add(response) async def handle_browse_matchmake_session_no_holder(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.browse_matchmake_session_no_holder()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) range = input.extract(common.ResultRange) response = await self.browse_matchmake_session_no_holder(client, search_criteria, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_browse_matchmake_session_with_host_urls_no_holder(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.browse_matchmake_session_with_host_urls_no_holder()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) range = input.extract(common.ResultRange) response = await self.browse_matchmake_session_with_host_urls_no_holder(client, search_criteria, range) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['sessions', 'urls']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.sessions, output.add) output.list(response.urls, output.add) async def handle_update_matchmake_session_part(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.update_matchmake_session_part()") #--- request --- param = input.extract(UpdateMatchmakeSessionParam) await self.update_matchmake_session_part(client, param) async def handle_request_matchmaking(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.request_matchmaking()") #--- request --- param = input.extract(AutoMatchmakeParam) response = await self.request_matchmaking(client, param) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u64(response) async def handle_withdraw_matchmaking(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.withdraw_matchmaking()") #--- request --- request_id = input.u64() await self.withdraw_matchmaking(client, request_id) async def handle_withdraw_matchmaking_all(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.withdraw_matchmaking_all()") #--- request --- await self.withdraw_matchmaking_all(client) async def handle_find_matchmake_session_by_gathering_id(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.find_matchmake_session_by_gathering_id()") #--- request --- gids = input.list(input.u32) response = await self.find_matchmake_session_by_gathering_id(client, gids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_find_matchmake_session_by_single_gathering_id(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.find_matchmake_session_by_single_gathering_id()") #--- request --- gid = input.u32() response = await self.find_matchmake_session_by_single_gathering_id(client, gid) #--- response --- if not isinstance(response, MatchmakeSession): raise RuntimeError("Expected MatchmakeSession, got %s" %response.__class__.__name__) output.add(response) async def handle_find_matchmake_session_by_owner(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.find_matchmake_session_by_owner()") #--- request --- pid = input.pid() range = input.extract(common.ResultRange) response = await self.find_matchmake_session_by_owner(client, pid, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_find_matchmake_session_by_participant(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.find_matchmake_session_by_participant()") #--- request --- param = input.extract(FindMatchmakeSessionByParticipantParam) response = await self.find_matchmake_session_by_participant(client, param) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_browse_matchmake_session_no_holder_no_result_range(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.browse_matchmake_session_no_holder_no_result_range()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) response = await self.browse_matchmake_session_no_holder_no_result_range(client, search_criteria) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_browse_matchmake_session_with_host_urls_no_holder_no_result_range(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.browse_matchmake_session_with_host_urls_no_holder_no_result_range()") #--- request --- search_criteria = input.extract(MatchmakeSessionSearchCriteria) response = await self.browse_matchmake_session_with_host_urls_no_holder_no_result_range(client, search_criteria) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['sessions', 'urls']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.list(response.sessions, output.add) output.list(response.urls, output.add) async def handle_create_simple_search_object(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.create_simple_search_object()") #--- request --- object = input.extract(SimpleSearchObject) response = await self.create_simple_search_object(client, object) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u32(response) async def handle_update_simple_search_object(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.update_simple_search_object()") #--- request --- id = input.u32() object = input.extract(SimpleSearchObject) await self.update_simple_search_object(client, id, object) async def handle_delete_simple_search_object(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.delete_simple_search_object()") #--- request --- id = input.u32() await self.delete_simple_search_object(client, id) async def handle_search_simple_search_object(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.search_simple_search_object()") #--- request --- param = input.extract(SimpleSearchParam) response = await self.search_simple_search_object(client, param) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_search_simple_search_object_by_object_ids(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.search_simple_search_object_by_object_ids()") #--- request --- ids = input.list(input.u32) response = await self.search_simple_search_object_by_object_ids(client, ids) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_join_matchmake_session_with_extra_participants(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.join_matchmake_session_with_extra_participants()") #--- request --- gid = input.u32() join_message = input.string() ignore_blacklist = input.bool() participation_count = input.u16() extra_participants = input.u32() response = await self.join_matchmake_session_with_extra_participants(client, gid, join_message, ignore_blacklist, participation_count, extra_participants) #--- response --- if not isinstance(response, bytes): raise RuntimeError("Expected bytes, got %s" %response.__class__.__name__) output.buffer(response) async def handle_custom_get_simple_playing_session(self, client, input, output): logger.warning("MatchmakeExtensionServerMK8D.custom_get_simple_playing_session is not supported") raise common.RMCError("Core::NotImplemented") async def handle_create_competition(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.create_competition()") #--- request --- competition = input.extract(SimpleSearchObject) response = await self.create_competition(client, competition) #--- response --- if not isinstance(response, SimpleSearchObject): raise RuntimeError("Expected SimpleSearchObject, got %s" %response.__class__.__name__) output.add(response) async def handle_delete_competition(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.delete_competition()") #--- request --- id = input.u32() await self.delete_competition(client, id) async def handle_register_favorite_competition(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.register_favorite_competition()") #--- request --- id = input.u32() await self.register_favorite_competition(client, id) async def handle_unregister_favorite_competition(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.unregister_favorite_competition()") #--- request --- id = input.u32() await self.unregister_favorite_competition(client, id) async def handle_get_favorite_competition(self, client, input, output): logger.info("MatchmakeExtensionServerMK8D.get_favorite_competition()") #--- request --- response = await self.get_favorite_competition(client) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_team_participants(self, client, input, output): logger.warning("MatchmakeExtensionServerMK8D.get_team_participants is not supported") raise common.RMCError("Core::NotImplemented") async def handle_find_community_by_owner(self, client, input, output): logger.warning("MatchmakeExtensionServerMK8D.find_community_by_owner is not supported") raise common.RMCError("Core::NotImplemented") async def close_participation(self, *args): logger.warning("MatchmakeExtensionServerMK8D.close_participation not implemented") raise common.RMCError("Core::NotImplemented") async def open_participation(self, *args): logger.warning("MatchmakeExtensionServerMK8D.open_participation not implemented") raise common.RMCError("Core::NotImplemented") async def auto_matchmake_postpone(self, *args): logger.warning("MatchmakeExtensionServerMK8D.auto_matchmake_postpone not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session(self, *args): logger.warning("MatchmakeExtensionServerMK8D.browse_matchmake_session not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session_with_host_urls(self, *args): logger.warning("MatchmakeExtensionServerMK8D.browse_matchmake_session_with_host_urls not implemented") raise common.RMCError("Core::NotImplemented") async def create_matchmake_session(self, *args): logger.warning("MatchmakeExtensionServerMK8D.create_matchmake_session not implemented") raise common.RMCError("Core::NotImplemented") async def join_matchmake_session(self, *args): logger.warning("MatchmakeExtensionServerMK8D.join_matchmake_session not implemented") raise common.RMCError("Core::NotImplemented") async def modify_current_game_attribute(self, *args): logger.warning("MatchmakeExtensionServerMK8D.modify_current_game_attribute not implemented") raise common.RMCError("Core::NotImplemented") async def update_notification_data(self, *args): logger.warning("MatchmakeExtensionServerMK8D.update_notification_data not implemented") raise common.RMCError("Core::NotImplemented") async def get_friend_notification_data(self, *args): logger.warning("MatchmakeExtensionServerMK8D.get_friend_notification_data not implemented") raise common.RMCError("Core::NotImplemented") async def update_application_buffer(self, *args): logger.warning("MatchmakeExtensionServerMK8D.update_application_buffer not implemented") raise common.RMCError("Core::NotImplemented") async def update_matchmake_session_attribute(self, *args): logger.warning("MatchmakeExtensionServerMK8D.update_matchmake_session_attribute not implemented") raise common.RMCError("Core::NotImplemented") async def get_friend_notification_data_list(self, *args): logger.warning("MatchmakeExtensionServerMK8D.get_friend_notification_data_list not implemented") raise common.RMCError("Core::NotImplemented") async def update_matchmake_session(self, *args): logger.warning("MatchmakeExtensionServerMK8D.update_matchmake_session not implemented") raise common.RMCError("Core::NotImplemented") async def auto_matchmake_with_search_criteria_postpone(self, *args): logger.warning("MatchmakeExtensionServerMK8D.auto_matchmake_with_search_criteria_postpone not implemented") raise common.RMCError("Core::NotImplemented") async def get_playing_session(self, *args): logger.warning("MatchmakeExtensionServerMK8D.get_playing_session not implemented") raise common.RMCError("Core::NotImplemented") async def create_community(self, *args): logger.warning("MatchmakeExtensionServerMK8D.create_community not implemented") raise common.RMCError("Core::NotImplemented") async def update_community(self, *args): logger.warning("MatchmakeExtensionServerMK8D.update_community not implemented") raise common.RMCError("Core::NotImplemented") async def join_community(self, *args): logger.warning("MatchmakeExtensionServerMK8D.join_community not implemented") raise common.RMCError("Core::NotImplemented") async def find_community_by_gathering_id(self, *args): logger.warning("MatchmakeExtensionServerMK8D.find_community_by_gathering_id not implemented") raise common.RMCError("Core::NotImplemented") async def find_official_community(self, *args): logger.warning("MatchmakeExtensionServerMK8D.find_official_community not implemented") raise common.RMCError("Core::NotImplemented") async def find_community_by_participant(self, *args): logger.warning("MatchmakeExtensionServerMK8D.find_community_by_participant not implemented") raise common.RMCError("Core::NotImplemented") async def update_privacy_setting(self, *args): logger.warning("MatchmakeExtensionServerMK8D.update_privacy_setting not implemented") raise common.RMCError("Core::NotImplemented") async def get_my_block_list(self, *args): logger.warning("MatchmakeExtensionServerMK8D.get_my_block_list not implemented") raise common.RMCError("Core::NotImplemented") async def add_to_block_list(self, *args): logger.warning("MatchmakeExtensionServerMK8D.add_to_block_list not implemented") raise common.RMCError("Core::NotImplemented") async def remove_from_block_list(self, *args): logger.warning("MatchmakeExtensionServerMK8D.remove_from_block_list not implemented") raise common.RMCError("Core::NotImplemented") async def clear_my_block_list(self, *args): logger.warning("MatchmakeExtensionServerMK8D.clear_my_block_list not implemented") raise common.RMCError("Core::NotImplemented") async def report_violation(self, *args): logger.warning("MatchmakeExtensionServerMK8D.report_violation not implemented") raise common.RMCError("Core::NotImplemented") async def is_violation_user(self, *args): logger.warning("MatchmakeExtensionServerMK8D.is_violation_user not implemented") raise common.RMCError("Core::NotImplemented") async def join_matchmake_session_ex(self, *args): logger.warning("MatchmakeExtensionServerMK8D.join_matchmake_session_ex not implemented") raise common.RMCError("Core::NotImplemented") async def get_simple_playing_session(self, *args): logger.warning("MatchmakeExtensionServerMK8D.get_simple_playing_session not implemented") raise common.RMCError("Core::NotImplemented") async def get_simple_community(self, *args): logger.warning("MatchmakeExtensionServerMK8D.get_simple_community not implemented") raise common.RMCError("Core::NotImplemented") async def auto_matchmake_with_gathering_id_postpone(self, *args): logger.warning("MatchmakeExtensionServerMK8D.auto_matchmake_with_gathering_id_postpone not implemented") raise common.RMCError("Core::NotImplemented") async def update_progress_score(self, *args): logger.warning("MatchmakeExtensionServerMK8D.update_progress_score not implemented") raise common.RMCError("Core::NotImplemented") async def debug_notify_event(self, *args): logger.warning("MatchmakeExtensionServerMK8D.debug_notify_event not implemented") raise common.RMCError("Core::NotImplemented") async def generate_matchmake_session_system_password(self, *args): logger.warning("MatchmakeExtensionServerMK8D.generate_matchmake_session_system_password not implemented") raise common.RMCError("Core::NotImplemented") async def clear_matchmake_session_system_password(self, *args): logger.warning("MatchmakeExtensionServerMK8D.clear_matchmake_session_system_password not implemented") raise common.RMCError("Core::NotImplemented") async def create_matchmake_session_with_param(self, *args): logger.warning("MatchmakeExtensionServerMK8D.create_matchmake_session_with_param not implemented") raise common.RMCError("Core::NotImplemented") async def join_matchmake_session_with_param(self, *args): logger.warning("MatchmakeExtensionServerMK8D.join_matchmake_session_with_param not implemented") raise common.RMCError("Core::NotImplemented") async def auto_matchmake_with_param_postpone(self, *args): logger.warning("MatchmakeExtensionServerMK8D.auto_matchmake_with_param_postpone not implemented") raise common.RMCError("Core::NotImplemented") async def find_matchmake_session_by_gathering_id_detail(self, *args): logger.warning("MatchmakeExtensionServerMK8D.find_matchmake_session_by_gathering_id_detail not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session_no_holder(self, *args): logger.warning("MatchmakeExtensionServerMK8D.browse_matchmake_session_no_holder not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session_with_host_urls_no_holder(self, *args): logger.warning("MatchmakeExtensionServerMK8D.browse_matchmake_session_with_host_urls_no_holder not implemented") raise common.RMCError("Core::NotImplemented") async def update_matchmake_session_part(self, *args): logger.warning("MatchmakeExtensionServerMK8D.update_matchmake_session_part not implemented") raise common.RMCError("Core::NotImplemented") async def request_matchmaking(self, *args): logger.warning("MatchmakeExtensionServerMK8D.request_matchmaking not implemented") raise common.RMCError("Core::NotImplemented") async def withdraw_matchmaking(self, *args): logger.warning("MatchmakeExtensionServerMK8D.withdraw_matchmaking not implemented") raise common.RMCError("Core::NotImplemented") async def withdraw_matchmaking_all(self, *args): logger.warning("MatchmakeExtensionServerMK8D.withdraw_matchmaking_all not implemented") raise common.RMCError("Core::NotImplemented") async def find_matchmake_session_by_gathering_id(self, *args): logger.warning("MatchmakeExtensionServerMK8D.find_matchmake_session_by_gathering_id not implemented") raise common.RMCError("Core::NotImplemented") async def find_matchmake_session_by_single_gathering_id(self, *args): logger.warning("MatchmakeExtensionServerMK8D.find_matchmake_session_by_single_gathering_id not implemented") raise common.RMCError("Core::NotImplemented") async def find_matchmake_session_by_owner(self, *args): logger.warning("MatchmakeExtensionServerMK8D.find_matchmake_session_by_owner not implemented") raise common.RMCError("Core::NotImplemented") async def find_matchmake_session_by_participant(self, *args): logger.warning("MatchmakeExtensionServerMK8D.find_matchmake_session_by_participant not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session_no_holder_no_result_range(self, *args): logger.warning("MatchmakeExtensionServerMK8D.browse_matchmake_session_no_holder_no_result_range not implemented") raise common.RMCError("Core::NotImplemented") async def browse_matchmake_session_with_host_urls_no_holder_no_result_range(self, *args): logger.warning("MatchmakeExtensionServerMK8D.browse_matchmake_session_with_host_urls_no_holder_no_result_range not implemented") raise common.RMCError("Core::NotImplemented") async def create_simple_search_object(self, *args): logger.warning("MatchmakeExtensionServerMK8D.create_simple_search_object not implemented") raise common.RMCError("Core::NotImplemented") async def update_simple_search_object(self, *args): logger.warning("MatchmakeExtensionServerMK8D.update_simple_search_object not implemented") raise common.RMCError("Core::NotImplemented") async def delete_simple_search_object(self, *args): logger.warning("MatchmakeExtensionServerMK8D.delete_simple_search_object not implemented") raise common.RMCError("Core::NotImplemented") async def search_simple_search_object(self, *args): logger.warning("MatchmakeExtensionServerMK8D.search_simple_search_object not implemented") raise common.RMCError("Core::NotImplemented") async def search_simple_search_object_by_object_ids(self, *args): logger.warning("MatchmakeExtensionServerMK8D.search_simple_search_object_by_object_ids not implemented") raise common.RMCError("Core::NotImplemented") async def join_matchmake_session_with_extra_participants(self, *args): logger.warning("MatchmakeExtensionServerMK8D.join_matchmake_session_with_extra_participants not implemented") raise common.RMCError("Core::NotImplemented") async def create_competition(self, *args): logger.warning("MatchmakeExtensionServerMK8D.create_competition not implemented") raise common.RMCError("Core::NotImplemented") async def delete_competition(self, *args): logger.warning("MatchmakeExtensionServerMK8D.delete_competition not implemented") raise common.RMCError("Core::NotImplemented") async def register_favorite_competition(self, *args): logger.warning("MatchmakeExtensionServerMK8D.register_favorite_competition not implemented") raise common.RMCError("Core::NotImplemented") async def unregister_favorite_competition(self, *args): logger.warning("MatchmakeExtensionServerMK8D.unregister_favorite_competition not implemented") raise common.RMCError("Core::NotImplemented") async def get_favorite_competition(self, *args): logger.warning("MatchmakeExtensionServerMK8D.get_favorite_competition not implemented") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/messaging.py ================================================ # This file was generated automatically by generate_protocols.py from nintendo.nex import notification, rmc, common, streams import logging logger = logging.getLogger(__name__) class RecipientType: PRINCIPAL = 1 GATHERING = 2 class MessageRecipient(common.Structure): def __init__(self): super().__init__() self.type = None self.pid = None self.gid = None def check_required(self, settings, version): for field in ['type', 'pid', 'gid']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.type = stream.u32() self.pid = stream.pid() self.gid = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.type) stream.pid(self.pid) stream.u32(self.gid) class UserMessage(common.Data): def __init__(self): super().__init__() self.id = None self.parent_id = None self.sender = None self.reception_time = None self.life_time = None self.flags = None self.subject = None self.sender_name = None self.recipient = MessageRecipient() def check_required(self, settings, version): for field in ['id', 'parent_id', 'sender', 'reception_time', 'life_time', 'flags', 'subject', 'sender_name']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.id = stream.u32() self.parent_id = stream.u32() self.sender = stream.pid() self.reception_time = stream.datetime() self.life_time = stream.u32() self.flags = stream.u32() self.subject = stream.string() self.sender_name = stream.string() self.recipient = stream.extract(MessageRecipient) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.id) stream.u32(self.parent_id) stream.pid(self.sender) stream.datetime(self.reception_time) stream.u32(self.life_time) stream.u32(self.flags) stream.string(self.subject) stream.string(self.sender_name) stream.add(self.recipient) common.DataHolder.register(UserMessage, "UserMessage") class TextMessage(UserMessage): def __init__(self): super().__init__() self.body = None def check_required(self, settings, version): for field in ['body']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.body = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.body) common.DataHolder.register(TextMessage, "TextMessage") class BinaryMessage(UserMessage): def __init__(self): super().__init__() self.body = None def check_required(self, settings, version): for field in ['body']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.body = stream.qbuffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.qbuffer(self.body) common.DataHolder.register(BinaryMessage, "BinaryMessage") class MessagingProtocol: METHOD_DELIVER_MESSAGE = 1 METHOD_GET_NUMBER_OF_MESSAGES = 2 METHOD_GET_MESSAGE_HEADERS = 3 METHOD_RETRIEVE_ALL_MESSAGES_WITHIN_RANGE = 4 METHOD_RETRIEVE_MESSAGES = 5 METHOD_DELETE_MESSAGES = 6 METHOD_DELETE_ALL_MESSAGES = 7 PROTOCOL_ID = 0x17 class MessageDeliveryProtocol: NORESPONSE = True METHOD_DELIVER_MESSAGE = 1 PROTOCOL_ID = 0x1B class MessagingClient(MessagingProtocol): def __init__(self, client): self.settings = client.settings self.client = client async def deliver_message(self, message): logger.info("MessagingClient.deliver_message()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELIVER_MESSAGE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.modified_message = stream.anydata() obj.sandbox_node_ids = stream.list(stream.u32) obj.participants = stream.list(stream.pid) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MessagingClient.deliver_message -> done") return obj async def get_number_of_messages(self, recipient): logger.info("MessagingClient.get_number_of_messages()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(recipient) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_NUMBER_OF_MESSAGES, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) number = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MessagingClient.get_number_of_messages -> done") return number async def get_message_headers(self, recipient, range): logger.info("MessagingClient.get_message_headers()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(recipient) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_MESSAGE_HEADERS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) headers = stream.list(UserMessage) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MessagingClient.get_message_headers -> done") return headers async def retrieve_all_messages_within_range(self, recipient, range): logger.info("MessagingClient.retrieve_all_messages_within_range()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(recipient) stream.add(range) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RETRIEVE_ALL_MESSAGES_WITHIN_RANGE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) messages = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MessagingClient.retrieve_all_messages_within_range -> done") return messages async def retrieve_messages(self, recipient, message_ids, leave_on_server): logger.info("MessagingClient.retrieve_messages()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(recipient) stream.list(message_ids, stream.u32) stream.bool(leave_on_server) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_RETRIEVE_MESSAGES, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) messages = stream.list(stream.anydata) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MessagingClient.retrieve_messages -> done") return messages async def delete_messages(self, recipient, message_ids): logger.info("MessagingClient.delete_messages()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(recipient) stream.list(message_ids, stream.u32) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_MESSAGES, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MessagingClient.delete_messages -> done") async def delete_all_messages(self, recipient): logger.info("MessagingClient.delete_all_messages()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(recipient) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_ALL_MESSAGES, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) number_deleted = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MessagingClient.delete_all_messages -> done") return number_deleted class MessageDeliveryClient(MessageDeliveryProtocol): def __init__(self, client): self.settings = client.settings self.client = client async def deliver_message(self, message): logger.info("MessageDeliveryClient.deliver_message()") #--- request --- stream = streams.StreamOut(self.settings) stream.anydata(message) await self.client.request(self.PROTOCOL_ID, self.METHOD_DELIVER_MESSAGE, stream.get(), True) class MessagingServer(MessagingProtocol): def __init__(self): self.methods = { self.METHOD_DELIVER_MESSAGE: self.handle_deliver_message, self.METHOD_GET_NUMBER_OF_MESSAGES: self.handle_get_number_of_messages, self.METHOD_GET_MESSAGE_HEADERS: self.handle_get_message_headers, self.METHOD_RETRIEVE_ALL_MESSAGES_WITHIN_RANGE: self.handle_retrieve_all_messages_within_range, self.METHOD_RETRIEVE_MESSAGES: self.handle_retrieve_messages, self.METHOD_DELETE_MESSAGES: self.handle_delete_messages, self.METHOD_DELETE_ALL_MESSAGES: self.handle_delete_all_messages, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on MessagingServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_deliver_message(self, client, input, output): logger.info("MessagingServer.deliver_message()") #--- request --- message = input.anydata() response = await self.deliver_message(client, message) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['modified_message', 'sandbox_node_ids', 'participants']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.anydata(response.modified_message) output.list(response.sandbox_node_ids, output.u32) output.list(response.participants, output.pid) async def handle_get_number_of_messages(self, client, input, output): logger.info("MessagingServer.get_number_of_messages()") #--- request --- recipient = input.extract(MessageRecipient) response = await self.get_number_of_messages(client, recipient) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u32(response) async def handle_get_message_headers(self, client, input, output): logger.info("MessagingServer.get_message_headers()") #--- request --- recipient = input.extract(MessageRecipient) range = input.extract(common.ResultRange) response = await self.get_message_headers(client, recipient, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_retrieve_all_messages_within_range(self, client, input, output): logger.info("MessagingServer.retrieve_all_messages_within_range()") #--- request --- recipient = input.extract(MessageRecipient) range = input.extract(common.ResultRange) response = await self.retrieve_all_messages_within_range(client, recipient, range) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_retrieve_messages(self, client, input, output): logger.info("MessagingServer.retrieve_messages()") #--- request --- recipient = input.extract(MessageRecipient) message_ids = input.list(input.u32) leave_on_server = input.bool() response = await self.retrieve_messages(client, recipient, message_ids, leave_on_server) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.anydata) async def handle_delete_messages(self, client, input, output): logger.info("MessagingServer.delete_messages()") #--- request --- recipient = input.extract(MessageRecipient) message_ids = input.list(input.u32) await self.delete_messages(client, recipient, message_ids) async def handle_delete_all_messages(self, client, input, output): logger.info("MessagingServer.delete_all_messages()") #--- request --- recipient = input.extract(MessageRecipient) response = await self.delete_all_messages(client, recipient) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u32(response) async def deliver_message(self, *args): logger.warning("MessagingServer.deliver_message not implemented") raise common.RMCError("Core::NotImplemented") async def get_number_of_messages(self, *args): logger.warning("MessagingServer.get_number_of_messages not implemented") raise common.RMCError("Core::NotImplemented") async def get_message_headers(self, *args): logger.warning("MessagingServer.get_message_headers not implemented") raise common.RMCError("Core::NotImplemented") async def retrieve_all_messages_within_range(self, *args): logger.warning("MessagingServer.retrieve_all_messages_within_range not implemented") raise common.RMCError("Core::NotImplemented") async def retrieve_messages(self, *args): logger.warning("MessagingServer.retrieve_messages not implemented") raise common.RMCError("Core::NotImplemented") async def delete_messages(self, *args): logger.warning("MessagingServer.delete_messages not implemented") raise common.RMCError("Core::NotImplemented") async def delete_all_messages(self, *args): logger.warning("MessagingServer.delete_all_messages not implemented") raise common.RMCError("Core::NotImplemented") class MessageDeliveryServer(MessageDeliveryProtocol): def __init__(self): self.methods = { self.METHOD_DELIVER_MESSAGE: self.handle_deliver_message, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on MessageDeliveryServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_deliver_message(self, client, input, output): logger.info("MessageDeliveryServer.deliver_message()") #--- request --- message = input.anydata() await self.deliver_message(client, message) async def deliver_message(self, *args): logger.warning("MessageDeliveryServer.deliver_message not implemented") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/monitoring.py ================================================ # This file was generated automatically by generate_protocols.py from nintendo.nex import notification, rmc, common, streams import logging logger = logging.getLogger(__name__) class MonitoringProtocol: METHOD_PING_DAEMON = 1 METHOD_GET_CLUSTER_MEMBERS = 2 PROTOCOL_ID = 0x13 class MonitoringClient(MonitoringProtocol): def __init__(self, client): self.settings = client.settings self.client = client async def ping_daemon(self): logger.info("MonitoringClient.ping_daemon()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PING_DAEMON, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MonitoringClient.ping_daemon -> done") return result async def get_cluster_members(self): logger.info("MonitoringClient.get_cluster_members()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_CLUSTER_MEMBERS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) members = stream.list(stream.string) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("MonitoringClient.get_cluster_members -> done") return members class MonitoringServer(MonitoringProtocol): def __init__(self): self.methods = { self.METHOD_PING_DAEMON: self.handle_ping_daemon, self.METHOD_GET_CLUSTER_MEMBERS: self.handle_get_cluster_members, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on MonitoringServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_ping_daemon(self, client, input, output): logger.info("MonitoringServer.ping_daemon()") #--- request --- response = await self.ping_daemon(client) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_cluster_members(self, client, input, output): logger.info("MonitoringServer.get_cluster_members()") #--- request --- response = await self.get_cluster_members(client) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.string) async def ping_daemon(self, *args): logger.warning("MonitoringServer.ping_daemon not implemented") raise common.RMCError("Core::NotImplemented") async def get_cluster_members(self, *args): logger.warning("MonitoringServer.get_cluster_members not implemented") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/natcheck.py ================================================ from anynet import util import struct PRIMARY_ADDRESS = "nncs1-lp1.n.n.srv.nintendo.net" PRIMARY_PORT = 10025 async def detect_external_address(socket): message = struct.pack(">IIII", 1, 0, 0, 0) await socket.send(message, (PRIMARY_ADDRESS, PRIMARY_PORT)) while True: response = (await socket.recv())[0] if len(response) == 16: type, port, host, extra = struct.unpack(">IIII", response) if type == 1: return util.ip_from_hex(host), port ================================================ FILE: nintendo/nex/nattraversal.py ================================================ # This file was generated automatically by generate_protocols.py from nintendo.nex import notification, rmc, common, streams import logging logger = logging.getLogger(__name__) class NATTraversalProtocol: METHOD_REQUEST_PROBE_INITIATION = 1 METHOD_INITIATE_PROBE = 2 METHOD_REQUEST_PROBE_INITIATION_EXT = 3 METHOD_REPORT_NAT_TRAVERSAL_RESULT = 4 METHOD_REPORT_NAT_PROPERTIES = 5 METHOD_GET_RELAY_SIGNATURE_KEY = 6 METHOD_REPORT_NAT_TRAVERSAL_RESULT_DETAIL = 7 PROTOCOL_ID = 0x3 class NATTraversalClient(NATTraversalProtocol): def __init__(self, client): self.settings = client.settings self.client = client async def request_probe_initiation(self, target_urls): logger.info("NATTraversalClient.request_probe_initiation()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(target_urls, stream.stationurl) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REQUEST_PROBE_INITIATION, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("NATTraversalClient.request_probe_initiation -> done") async def initiate_probe(self, station_to_probe): logger.info("NATTraversalClient.initiate_probe()") #--- request --- stream = streams.StreamOut(self.settings) stream.stationurl(station_to_probe) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_INITIATE_PROBE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("NATTraversalClient.initiate_probe -> done") async def request_probe_initiation_ext(self, target_urls, station_to_probe): logger.info("NATTraversalClient.request_probe_initiation_ext()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(target_urls, stream.stationurl) stream.stationurl(station_to_probe) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REQUEST_PROBE_INITIATION_EXT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("NATTraversalClient.request_probe_initiation_ext -> done") async def report_nat_traversal_result(self, cid, result): logger.info("NATTraversalClient.report_nat_traversal_result()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(cid) stream.bool(result) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REPORT_NAT_TRAVERSAL_RESULT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("NATTraversalClient.report_nat_traversal_result -> done") async def report_nat_properties(self, natm, natf, rtt): logger.info("NATTraversalClient.report_nat_properties()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(natm) stream.u32(natf) stream.u32(rtt) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REPORT_NAT_PROPERTIES, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("NATTraversalClient.report_nat_properties -> done") async def get_relay_signature_key(self): logger.info("NATTraversalClient.get_relay_signature_key()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RELAY_SIGNATURE_KEY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.mode = stream.s32() obj.time = stream.datetime() obj.address = stream.string() obj.port = stream.u16() obj.address_type = stream.s32() obj.game_server_id = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("NATTraversalClient.get_relay_signature_key -> done") return obj async def report_nat_traversal_result_detail(self, cid, result, detail, rtt): logger.info("NATTraversalClient.report_nat_traversal_result_detail()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(cid) stream.bool(result) stream.s32(detail) stream.u32(rtt) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REPORT_NAT_TRAVERSAL_RESULT_DETAIL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("NATTraversalClient.report_nat_traversal_result_detail -> done") class NATTraversalServer(NATTraversalProtocol): def __init__(self): self.methods = { self.METHOD_REQUEST_PROBE_INITIATION: self.handle_request_probe_initiation, self.METHOD_INITIATE_PROBE: self.handle_initiate_probe, self.METHOD_REQUEST_PROBE_INITIATION_EXT: self.handle_request_probe_initiation_ext, self.METHOD_REPORT_NAT_TRAVERSAL_RESULT: self.handle_report_nat_traversal_result, self.METHOD_REPORT_NAT_PROPERTIES: self.handle_report_nat_properties, self.METHOD_GET_RELAY_SIGNATURE_KEY: self.handle_get_relay_signature_key, self.METHOD_REPORT_NAT_TRAVERSAL_RESULT_DETAIL: self.handle_report_nat_traversal_result_detail, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on NATTraversalServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_request_probe_initiation(self, client, input, output): logger.info("NATTraversalServer.request_probe_initiation()") #--- request --- target_urls = input.list(input.stationurl) await self.request_probe_initiation(client, target_urls) async def handle_initiate_probe(self, client, input, output): logger.info("NATTraversalServer.initiate_probe()") #--- request --- station_to_probe = input.stationurl() await self.initiate_probe(client, station_to_probe) async def handle_request_probe_initiation_ext(self, client, input, output): logger.info("NATTraversalServer.request_probe_initiation_ext()") #--- request --- target_urls = input.list(input.stationurl) station_to_probe = input.stationurl() await self.request_probe_initiation_ext(client, target_urls, station_to_probe) async def handle_report_nat_traversal_result(self, client, input, output): logger.info("NATTraversalServer.report_nat_traversal_result()") #--- request --- cid = input.u32() result = input.bool() await self.report_nat_traversal_result(client, cid, result) async def handle_report_nat_properties(self, client, input, output): logger.info("NATTraversalServer.report_nat_properties()") #--- request --- natm = input.u32() natf = input.u32() rtt = input.u32() await self.report_nat_properties(client, natm, natf, rtt) async def handle_get_relay_signature_key(self, client, input, output): logger.info("NATTraversalServer.get_relay_signature_key()") #--- request --- response = await self.get_relay_signature_key(client) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['mode', 'time', 'address', 'port', 'address_type', 'game_server_id']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.s32(response.mode) output.datetime(response.time) output.string(response.address) output.u16(response.port) output.s32(response.address_type) output.u32(response.game_server_id) async def handle_report_nat_traversal_result_detail(self, client, input, output): logger.info("NATTraversalServer.report_nat_traversal_result_detail()") #--- request --- cid = input.u32() result = input.bool() detail = input.s32() rtt = input.u32() await self.report_nat_traversal_result_detail(client, cid, result, detail, rtt) async def request_probe_initiation(self, *args): logger.warning("NATTraversalServer.request_probe_initiation not implemented") raise common.RMCError("Core::NotImplemented") async def initiate_probe(self, *args): logger.warning("NATTraversalServer.initiate_probe not implemented") raise common.RMCError("Core::NotImplemented") async def request_probe_initiation_ext(self, *args): logger.warning("NATTraversalServer.request_probe_initiation_ext not implemented") raise common.RMCError("Core::NotImplemented") async def report_nat_traversal_result(self, *args): logger.warning("NATTraversalServer.report_nat_traversal_result not implemented") raise common.RMCError("Core::NotImplemented") async def report_nat_properties(self, *args): logger.warning("NATTraversalServer.report_nat_properties not implemented") raise common.RMCError("Core::NotImplemented") async def get_relay_signature_key(self, *args): logger.warning("NATTraversalServer.get_relay_signature_key not implemented") raise common.RMCError("Core::NotImplemented") async def report_nat_traversal_result_detail(self, *args): logger.warning("NATTraversalServer.report_nat_traversal_result_detail not implemented") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/nintendonotification.py ================================================ # This file was generated automatically by generate_protocols.py from nintendo.nex import notification, rmc, common, streams import logging logger = logging.getLogger(__name__) class NintendoNotificationType: LOGOUT = 10 PRESENCE_CHANGE = 24 UNFRIENDED = 26 FRIENDED = 30 STATUS_CHANGE = 33 class u8KeyValue(common.Data): def __init__(self): super().__init__() self.key = None self.value = None def check_required(self, settings, version): for field in ['key', 'value']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.key = stream.u8() self.value = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.key) stream.u8(self.value) common.DataHolder.register(u8KeyValue, "u8KeyValue") class u32KeyValue(common.Data): def __init__(self): super().__init__() self.key = None self.value = None def check_required(self, settings, version): for field in ['key', 'value']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.key = stream.u8() self.value = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.key) stream.u32(self.value) common.DataHolder.register(u32KeyValue, "u32KeyValue") class u64KeyValue(common.Data): def __init__(self): super().__init__() self.key = None self.value = None def check_required(self, settings, version): for field in ['key', 'value']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.key = stream.u8() self.value = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.key) stream.u64(self.value) common.DataHolder.register(u64KeyValue, "u64KeyValue") class StringKeyValue(common.Data): def __init__(self): super().__init__() self.key = None self.value = None def check_required(self, settings, version): for field in ['key', 'value']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.key = stream.u8() self.value = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.key) stream.string(self.value) common.DataHolder.register(StringKeyValue, "StringKeyValue") class NintendoNotificationEvent(common.Structure): def __init__(self): super().__init__() self.type = None self.pid = None self.data = None def check_required(self, settings, version): for field in ['type', 'pid', 'data']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.type = stream.u32() self.pid = stream.pid() self.data = stream.anydata() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.type) stream.pid(self.pid) stream.anydata(self.data) class NintendoNotificationEventGeneral(common.Data): def __init__(self): super().__init__() self.param1 = None self.param2 = None self.param3 = None self.text = None def check_required(self, settings, version): for field in ['param1', 'param2', 'param3', 'text']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.param1 = stream.u32() self.param2 = stream.u64() self.param3 = stream.u64() self.text = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.param1) stream.u64(self.param2) stream.u64(self.param3) stream.string(self.text) common.DataHolder.register(NintendoNotificationEventGeneral, "NintendoNotificationEventGeneral") class NintendoNotificationEventKeyValue(common.Data): def __init__(self): super().__init__() self.u8 = None self.u32 = None self.u64 = None self.string = None def check_required(self, settings, version): for field in ['u8', 'u32', 'u64', 'string']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.u8 = stream.list(u8KeyValue) self.u32 = stream.list(u32KeyValue) self.u64 = stream.list(u64KeyValue) self.string = stream.list(StringKeyValue) def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.u8, stream.add) stream.list(self.u32, stream.add) stream.list(self.u64, stream.add) stream.list(self.string, stream.add) common.DataHolder.register(NintendoNotificationEventKeyValue, "NintendoNotificationEventKeyValue") class NintendoNotificationEventProfile(common.Data): def __init__(self): super().__init__() self.region = None self.country = None self.area = None self.language = None self.platform = None def check_required(self, settings, version): for field in ['region', 'country', 'area', 'language', 'platform']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.region = stream.u8() self.country = stream.u8() self.area = stream.u8() self.language = stream.u8() self.platform = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.region) stream.u8(self.country) stream.u8(self.area) stream.u8(self.language) stream.u8(self.platform) common.DataHolder.register(NintendoNotificationEventProfile, "NintendoNotificationEventProfile") class NintendoNotificationProtocol: NORESPONSE = True METHOD_PROCESS_NINTENDO_NOTIFICATION_EVENT = 1 METHOD_PROCESS_NINTENDO_NOTIFICATION_EVENT_ALT = 2 PROTOCOL_ID = 0x64 class NintendoNotificationClient(NintendoNotificationProtocol): def __init__(self, client): self.settings = client.settings self.client = client async def process_nintendo_notification_event(self, event): logger.info("NintendoNotificationClient.process_nintendo_notification_event()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(event) await self.client.request(self.PROTOCOL_ID, self.METHOD_PROCESS_NINTENDO_NOTIFICATION_EVENT, stream.get(), True) async def process_nintendo_notification_event_alt(self, event): logger.info("NintendoNotificationClient.process_nintendo_notification_event_alt()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(event) await self.client.request(self.PROTOCOL_ID, self.METHOD_PROCESS_NINTENDO_NOTIFICATION_EVENT_ALT, stream.get(), True) class NintendoNotificationServer(NintendoNotificationProtocol): def __init__(self): self.methods = { self.METHOD_PROCESS_NINTENDO_NOTIFICATION_EVENT: self.handle_process_nintendo_notification_event, self.METHOD_PROCESS_NINTENDO_NOTIFICATION_EVENT_ALT: self.handle_process_nintendo_notification_event_alt, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on NintendoNotificationServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_process_nintendo_notification_event(self, client, input, output): logger.info("NintendoNotificationServer.process_nintendo_notification_event()") #--- request --- event = input.extract(NintendoNotificationEvent) await self.process_nintendo_notification_event(client, event) async def handle_process_nintendo_notification_event_alt(self, client, input, output): logger.info("NintendoNotificationServer.process_nintendo_notification_event_alt()") #--- request --- event = input.extract(NintendoNotificationEvent) await self.process_nintendo_notification_event_alt(client, event) async def process_nintendo_notification_event(self, *args): logger.warning("NintendoNotificationServer.process_nintendo_notification_event not implemented") raise common.RMCError("Core::NotImplemented") async def process_nintendo_notification_event_alt(self, *args): logger.warning("NintendoNotificationServer.process_nintendo_notification_event_alt not implemented") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/notification.py ================================================ # This file was generated automatically by generate_protocols.py from nintendo.nex import notification, rmc, common, streams import logging logger = logging.getLogger(__name__) class NotificationEvent(common.Structure): def __init__(self): super().__init__() self.pid = None self.type = None self.param1 = 0 self.param2 = 0 self.text = "" self.param3 = 0 self.map = {} def max_version(self, settings): version = 0 if settings["nex.version"] >= 40000: version = 1 return version def check_required(self, settings, version): for field in ['pid', 'type']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) if settings["nex.version"] >= 30500: pass if settings["nex.version"] >= 40000: if version >= 1: pass def load(self, stream, version): self.pid = stream.pid() self.type = stream.u32() self.param1 = stream.pid() self.param2 = stream.pid() self.text = stream.string() if stream.settings["nex.version"] >= 30500: self.param3 = stream.pid() if stream.settings["nex.version"] >= 40000: if version >= 1: self.map = stream.map(stream.string, stream.variant) def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.u32(self.type) stream.pid(self.param1) stream.pid(self.param2) stream.string(self.text) if stream.settings["nex.version"] >= 30500: stream.pid(self.param3) if stream.settings["nex.version"] >= 40000: if version >= 1: stream.map(self.map, stream.string, stream.variant) class NotificationProtocol: NORESPONSE = True METHOD_PROCESS_NOTIFICATION_EVENT = 1 PROTOCOL_ID = 0xE class NotificationClient(NotificationProtocol): def __init__(self, client): self.settings = client.settings self.client = client async def process_notification_event(self, event): logger.info("NotificationClient.process_notification_event()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(event) await self.client.request(self.PROTOCOL_ID, self.METHOD_PROCESS_NOTIFICATION_EVENT, stream.get(), True) class NotificationServer(NotificationProtocol): def __init__(self): self.methods = { self.METHOD_PROCESS_NOTIFICATION_EVENT: self.handle_process_notification_event, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on NotificationServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_process_notification_event(self, client, input, output): logger.info("NotificationServer.process_notification_event()") #--- request --- event = input.extract(NotificationEvent) await self.process_notification_event(client, event) async def process_notification_event(self, *args): logger.warning("NotificationServer.process_notification_event not implemented") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/prudp.py ================================================ from Crypto.Cipher import ARC4 from anynet import udp, tls, websocket, util, \ scheduler, streams, queue from nintendo.nex import kerberos, streams as streams_nex import contextlib import hashlib import struct import random import socket import anyio import zlib import hmac import time import logging logger = logging.getLogger(__name__) TYPE_SYN = 0 TYPE_CONNECT = 1 TYPE_DATA = 2 TYPE_DISCONNECT = 3 TYPE_PING = 4 TYPE_USER = 5 TYPE_ROUTE = 6 TYPE_RAW = 7 FLAG_ACK = 1 FLAG_RELIABLE = 2 FLAG_NEED_ACK = 4 FLAG_HAS_SIZE = 8 FLAG_MULTI_ACK = 0x200 TYPE_NAMES = ["TYPE_SYN", "TYPE_CONNECT", "TYPE_DATA", "TYPE_DISCONNECT", "TYPE_PING", "TYPE_USER", "TYPE_ROUTE", "TYPE_RAW"] FLAG_NAMES = { FLAG_ACK: "ACK", FLAG_NEED_ACK: "NEED_ACK", FLAG_MULTI_ACK: "MULTI_ACK", FLAG_RELIABLE: "RELIABLE", FLAG_HAS_SIZE: "HAS_SIZE" } FLAG_LIST = [FLAG_ACK, FLAG_NEED_ACK, FLAG_MULTI_ACK, FLAG_RELIABLE, FLAG_HAS_SIZE] OPTION_SUPPORT = 0 OPTION_CONNECTION_SIG = 1 OPTION_FRAGMENT_ID = 2 OPTION_UNRELIABLE_SEQ_ID = 3 OPTION_MAX_SUBSTREAM_ID = 4 OPTION_CONNECTION_SIG_LITE = 128 OPTIONS = { OPTION_SUPPORT: (4, "OPTION_SUPPORT", "I"), OPTION_CONNECTION_SIG: (16, "OPTION_CONNECTION_SIG", "16s"), OPTION_FRAGMENT_ID: (1, "OPTION_FRAGMENT_ID", "B"), OPTION_UNRELIABLE_SEQ_ID: (2, "OPTION_UNRELIABLE_SEQ_ID", "H"), OPTION_MAX_SUBSTREAM_ID: (1, "OPTION_MAX_SUBSTREAM_ID", "B"), OPTION_CONNECTION_SIG_LITE: (16, "OPTION_CONNECTION_SIG_LITE", "16s") } STATE_CONNECTING = 0 STATE_CONNECTED = 1 STATE_DISCONNECTING = 2 STATE_DISCONNECTED = 3 def encode_options(options): data = b"" for k, v in options.items(): size, name, type = OPTIONS[k] data += struct.pack("" %( TYPE_NAMES[self.type], flags, self.packet_id, self.fragment_id ) class PRUDPMessageV0: def __init__(self, settings): self.signature_version = settings["prudp_v0.signature_version"] self.checksum_version = settings["prudp_v0.checksum_version"] self.flags_version = settings["prudp_v0.flags_version"] self.access_key = settings["prudp.access_key"].encode() def signature_size(self): return 4 def calc_checksum(self, data): checksum = sum(self.access_key) if self.checksum_version == 0: data = data.ljust((len(data) + 3) & ~3, b"\0") words = struct.unpack("<%iI" %(len(data) // 4), data) return ((checksum & 0xFF) + sum(words)) & 0xFFFFFFFF else: words = struct.unpack_from("<%iI" %(len(data) // 4), data) temp = sum(words) & 0xFFFFFFFF checksum += sum(data[len(data) & ~3:]) checksum += sum(struct.pack("H", addr[1]) return hashlib.md5(data).digest()[3::-1] def encode(self, packet): stream = streams.StreamOut("<") stream.u8(packet.source_port | (packet.source_type << 4)) stream.u8(packet.dest_port | (packet.dest_type << 4)) if self.flags_version == 0: stream.u8(packet.type | (packet.flags << 3)) else: stream.u16(packet.type | (packet.flags << 4)) stream.u8(packet.session_id) stream.write(packet.signature) stream.u16(packet.packet_id) self.encode_options(packet, stream) stream.write(packet.payload) data = stream.get() if self.checksum_version == 0: data += struct.pack("> 4 packet.source_port = source & 0xF packet.dest_type = dest >> 4 packet.dest_port = dest & 0xF if self.flags_version == 0: type_flags = stream.u8() packet.flags = type_flags >> 3 packet.type = type_flags & 7 else: type_flags = stream.u16() packet.flags = type_flags >> 4 packet.type = type_flags & 0xF packet.session_id = stream.u8() packet.signature = stream.read(4) packet.packet_id = stream.u16() if packet.type in [TYPE_SYN, TYPE_CONNECT]: packet.connection_signature = stream.read(4) if packet.type == TYPE_DATA: packet.fragment_id = stream.u8() if packet.flags & FLAG_HAS_SIZE: payload_size = stream.u16() else: if self.checksum_version == 0: payload_size = stream.available() - 4 else: payload_size = stream.available() - 1 packet.payload = stream.read(payload_size) # Check packet checksum end = stream.tell() checksum_data = stream.get()[start : end] expected_checksum = self.calc_checksum(checksum_data) if self.checksum_version == 0: checksum = stream.u32() else: checksum = stream.u8() if checksum != expected_checksum: raise ValueError("(V0) Invalid checksum (expected %i, got %i)" %(expected_checksum, checksum)) # Checksum is good! packets.append(packet) return packets class PRUDPMessageV1: def __init__(self, settings): self.access_key = settings["prudp.access_key"].encode() def signature_size(self): return 16 def calc_packet_signature(self, packet, session_key, connection_signature): options = self.encode_options(packet) header = self.encode_header(packet, len(options)) key = hashlib.md5(self.access_key).digest() mac = hmac.new(key, digestmod=hashlib.md5) mac.update(header[4:]) mac.update(session_key) mac.update(struct.pack("H", addr[1]) return hmac.digest(key, data, hashlib.md5) def encode(self, packet): options = self.encode_options(packet) header = self.encode_header(packet, len(options)) return b"\xEA\xD0" + header + packet.signature + options + packet.payload def encode_header(self, packet, option_size): stream = streams.StreamOut("<") stream.u8(1) # PRUDP version stream.u8(option_size) stream.u16(len(packet.payload)) stream.u8(packet.source_port | (packet.source_type << 4)) stream.u8(packet.dest_port | (packet.dest_type << 4)) stream.u16(packet.type | (packet.flags << 4)) stream.u8(packet.session_id) stream.u8(packet.substream_id) stream.u16(packet.packet_id) return stream.get() def encode_options(self, packet): options = {} if packet.type in [TYPE_SYN, TYPE_CONNECT]: options[OPTION_SUPPORT] = packet.minor_version | (packet.supported_functions << 8) options[OPTION_CONNECTION_SIG] = packet.connection_signature if packet.type == TYPE_CONNECT: options[OPTION_UNRELIABLE_SEQ_ID] = packet.initial_unreliable_id options[OPTION_MAX_SUBSTREAM_ID] = packet.max_substream_id elif packet.type == TYPE_DATA: options[OPTION_FRAGMENT_ID] = packet.fragment_id return encode_options(options) def verify_options(self, packet, options): keys = set(options) if packet.type == TYPE_SYN: return keys == {OPTION_SUPPORT, OPTION_CONNECTION_SIG, OPTION_MAX_SUBSTREAM_ID} if packet.type == TYPE_CONNECT: return keys == {OPTION_SUPPORT, OPTION_CONNECTION_SIG, OPTION_UNRELIABLE_SEQ_ID, OPTION_MAX_SUBSTREAM_ID} if packet.type == TYPE_DATA: return keys == {OPTION_FRAGMENT_ID} return keys == set() def decode(self, data): packets = [] stream = streams.StreamIn(data, "<") while not stream.eof(): if stream.read(2) != b"\xEA\xD0": raise ValueError("(V1) Invalid magic number") header = stream.peek(12) if stream.u8() != 1: raise ValueError("(V1) Version check failed") option_size = stream.u8() payload_size = stream.u16() source = stream.u8() dest = stream.u8() type_flags = stream.u16() packet = PRUDPPacket() packet.version = 1 packet.source_type = source >> 4 packet.source_port = source & 0xF packet.dest_type = dest >> 4 packet.dest_port = dest & 0xF packet.flags = type_flags >> 4 packet.type = type_flags & 0xF packet.session_id = stream.u8() packet.substream_id = stream.u8() packet.packet_id = stream.u16() packet.signature = stream.read(16) option_data = stream.read(option_size) options = decode_options(option_data) if not self.verify_options(packet, options): raise ValueError("(V1) Received unexpected set of options") if packet.type in [TYPE_SYN, TYPE_CONNECT]: packet.minor_version = options[OPTION_SUPPORT] & 0xFF packet.supported_functions = options[OPTION_SUPPORT] >> 8 packet.connection_signature = options[OPTION_CONNECTION_SIG] packet.max_substream_id = options[OPTION_MAX_SUBSTREAM_ID] if packet.type == TYPE_CONNECT: packet.initial_unreliable_id = options[OPTION_UNRELIABLE_SEQ_ID] if packet.type == TYPE_DATA: packet.fragment_id = options[OPTION_FRAGMENT_ID] packet.payload = stream.read(payload_size) packets.append(packet) return packets class PRUDPLiteMessage: def __init__(self, settings): self.access_key = settings["prudp.access_key"].encode() self.buffer = b"" def signature_size(self): return 16 def calc_packet_signature(self, packet, session_key, connection_signature): if packet.type == TYPE_CONNECT and packet.flags & FLAG_NEED_ACK: key = hashlib.md5(self.access_key).digest() return hmac.digest(key, key + connection_signature, hashlib.md5) return None def calc_connection_signature(self, addr): key = bytes.fromhex("26c31f381e46d6eb38e1af6ab70d11") data = socket.inet_aton(addr[0]) + struct.pack(">H", addr[1]) return hmac.digest(key, data, hashlib.md5) def encode(self, packet): options = self.encode_options(packet) header = self.encode_header(packet, len(options)) return header + options + packet.payload def encode_header(self, packet, option_size): stream = streams.StreamOut("<") stream.u8(0x80) stream.u8(option_size) stream.u16(len(packet.payload)) stream.u8((packet.source_type << 4) | packet.dest_type) stream.u8(packet.source_port) stream.u8(packet.dest_port) stream.u8(packet.fragment_id) stream.u16(packet.type | (packet.flags << 4)) stream.u16(packet.packet_id) return stream.get() def encode_options(self, packet): options = {} if packet.type in [TYPE_SYN, TYPE_CONNECT]: options[OPTION_SUPPORT] = packet.minor_version | (packet.supported_functions << 8) if packet.type == TYPE_SYN and packet.flags & FLAG_ACK: options[OPTION_CONNECTION_SIG] = packet.connection_signature if packet.type == TYPE_CONNECT and not packet.flags & FLAG_ACK: options[OPTION_CONNECTION_SIG_LITE] = packet.signature return encode_options(options) def verify_options(self, packet, options): keys = set(options) if packet.type in [TYPE_SYN, TYPE_CONNECT]: if packet.type == TYPE_SYN and packet.flags & FLAG_ACK: return keys == {OPTION_SUPPORT, OPTION_CONNECTION_SIG} if packet.type == TYPE_CONNECT and not packet.flags & FLAG_ACK: return keys == {OPTION_SUPPORT, OPTION_CONNECTION_SIG_LITE} return keys == {OPTION_SUPPORT} return keys == set() def decode(self, data): self.buffer += data packets = [] while self.buffer: if len(self.buffer) < 12: return packets stream = streams.StreamIn(self.buffer, "<") if stream.u8() != 0x80: raise ValueError("(Lite) Invalid magic number") option_size = stream.u8() payload_size = stream.u16() if len(self.buffer) < 12 + option_size + payload_size: return packets self.buffer = self.buffer[12 + option_size + payload_size:] packet = PRUDPPacket() stream_types = stream.u8() packet.source_type = stream_types >> 4 packet.dest_type = stream_types & 0xF packet.source_port = stream.u8() packet.dest_port = stream.u8() packet.fragment_id = stream.u8() type_flags = stream.u16() packet.flags = type_flags >> 4 packet.type = type_flags & 0xF packet.packet_id = stream.u16() packet.session_id = 0 option_data = stream.read(option_size) options = decode_options(option_data) if not self.verify_options(packet, options): raise ValueError("(Lite) Received unexpected set of options") packet.connection_signature = b"" if packet.type in [TYPE_SYN, TYPE_CONNECT]: packet.minor_version = options[OPTION_SUPPORT] & 0xFF packet.supported_functions = options[OPTION_SUPPORT] >> 8 if packet.type == TYPE_SYN and packet.flags & FLAG_ACK: packet.connection_signature = options[OPTION_CONNECTION_SIG] if packet.type == TYPE_CONNECT and not packet.flags & FLAG_ACK: packet.signature = options[OPTION_CONNECTION_SIG_LITE] packet.payload = stream.read(payload_size) packets.append(packet) return packets class PRUDPMessageSelector: def __init__(self, settings): self.settings = settings self.v0 = PRUDPMessageV0(settings) self.v1 = PRUDPMessageV1(settings) self.lite = PRUDPLiteMessage(settings) def select(self, version): if self.settings["prudp.transport"] == self.settings.TRANSPORT_UDP: if version == 0: return self.v0 return self.v1 return self.lite def analyze(self, data): if self.settings["prudp.transport"] == self.settings.TRANSPORT_UDP: if self.settings["prudp.version"] == 2: if data[:3] == b"\xEA\xD0\x01": return self.v1 return self.v0 return self.select(self.settings["prudp.version"]) def signature_size(self, version=None): return self.select(version).signature_size() def calc_packet_signature(self, packet, session_key, connection_signature): return self.select(packet.version).calc_packet_signature(packet, session_key, connection_signature) def calc_connection_signature(self, addr, version=None): return self.select(version).calc_connection_signature(addr) def encode(self, packet): return self.select(packet.version).encode(packet) def decode(self, data): return self.analyze(data).decode(data) class RC4Encryption: def __init__(self, key): self.rc4enc = ARC4.new(key) self.rc4dec = ARC4.new(key) def set_key(self, key): self.rc4enc = ARC4.new(key) self.rc4dec = ARC4.new(key) def encrypt(self, data): return self.rc4enc.encrypt(data) def decrypt(self, data): return self.rc4dec.decrypt(data) class DummyEncryption: def set_key(self, key): pass def encrypt(self, data): return data def decrypt(self, data): return data class ZlibCompression: def compress(self, data): compressed = zlib.compress(data) ratio = int(len(data) / len(compressed) + 1) return bytes([ratio]) + compressed def decompress(self, data): if data[0] == 0: return data[1:] decompressed = zlib.decompress(data[1:]) ratio = int(len(decompressed) / (len(data) - 1) + 1) if ratio != data[0]: raise ValueError("Unexpected compression ratio (expected %i, got %i)" %ratio, data[0]) return decompressed class DummyCompression: def compress(self, data): return data def decompress(self, data): return data class PayloadEncoder: DEFAULT_KEY = b"CD&ML" def __init__(self, settings): substreams = settings["prudp.max_substream_id"] + 1 self.reliable_encryption = [self.create_encryption(settings) for i in range(substreams)] self.unreliable_encryption = self.create_encryption(settings) self.unreliable_key = bytes(0x20) if settings["prudp.compression"] == settings.COMPRESSION_NONE: self.compression = DummyCompression() else: self.compression = ZlibCompression() def create_encryption(self, settings): if settings["prudp.transport"] == settings.TRANSPORT_UDP: return RC4Encryption(self.DEFAULT_KEY) return DummyEncryption() def encode(self, packet): data = packet.payload if packet.type == TYPE_DATA and data: data = self.compression.compress(data) if packet.flags & FLAG_RELIABLE: data = self.reliable_encryption[packet.substream_id].encrypt(data) else: key = self.make_unreliable_key(packet) self.unreliable_encryption.set_key(key) data = self.unreliable_encryption.encrypt(data) return data def decode(self, packet): data = packet.payload if packet.type == TYPE_DATA and data: if packet.flags & FLAG_RELIABLE: data = self.reliable_encryption[packet.substream_id].decrypt(data) else: key = self.make_unreliable_key(packet) self.unreliable_encryption.set_key(key) data = self.unreliable_encryption.decrypt(data) data = self.compression.decompress(data) return data def make_unreliable_key(self, packet): key = list(self.unreliable_key) key[0] = (key[0] + packet.packet_id) & 0xFF key[1] = (key[1] + (packet.packet_id >> 8)) & 0xFF key[31] = (key[31] + packet.session_id) & 0xFF return bytes(key) def modify_key(self, key): chars = list(key) add = len(chars) // 2 + 1 for i in range(len(chars) // 2): chars[i] = (chars[i] + add - i) & 0xFF return bytes(chars) def combine_keys(self, key1, key2): return hashlib.md5(key1 + key2).digest() def init_unreliable_key(self, key): part1 = self.combine_keys(key, bytes.fromhex("18d8233437e4e3fe")) part2 = self.combine_keys(key, bytes.fromhex("233e600123cdab80")) return part1 + part2 def set_session_key(self, key): self.reliable_encryption[0].set_key(key) temp_key = key for encryption in self.reliable_encryption[1:]: temp_key = self.modify_key(temp_key) encryption.set_key(temp_key) self.unreliable_key = self.init_unreliable_key(key) class SequenceCounter: def __init__(self, initial = 1): self.next_id = initial def next(self): current = self.next_id self.next_id = (self.next_id + 1) & 0xFFFF return current class SequenceMgr: def __init__(self, settings): substreams = settings["prudp.max_substream_id"] + 1 self.initial_unreliable_id = 1 if settings["prudp.transport"] == settings.TRANSPORT_UDP: if settings["prudp.version"] != 0: self.initial_unreliable_id = random.randint(0, 0xFFFF) self.counters = [SequenceCounter() for i in range(substreams)] self.unreliable_counter = SequenceCounter(self.initial_unreliable_id) self.ping_counter = SequenceCounter() def assign(self, packet): if packet.flags & FLAG_RELIABLE: return self.counters[packet.substream_id].next() if packet.type == TYPE_DATA: return self.unreliable_counter.next() if packet.type == TYPE_PING: return self.ping_counter.next() return 0 class SlidingWindow: def __init__(self): self.next = 1 self.packets = {} def skip(self): self.next = (self.next + 1) & 0xFFFF def update(self, packet): packets = [] if packet.packet_id < self.next or packet.packet_id in self.packets: logger.debug("Received duplicate packet: %s", packet) else: self.packets[packet.packet_id] = packet while self.next in self.packets: packet = self.packets.pop(self.next) packets.append(packet) self.skip() return packets class PRUDPClient: def __init__(self, settings, transport, version): self.fragment_size = settings["prudp.fragment_size"] self.resend_timeout = settings["prudp.resend_timeout"] self.resend_limit = settings["prudp.resend_limit"] self.ping_timeout = settings["prudp.ping_timeout"] self.max_substream_id = settings["prudp.max_substream_id"] self.supported_functions = settings["prudp.supported_functions"] self.minor_ver = settings["prudp.minor_version"] self.settings = settings self.transport = transport self.version = version self.packet_encoder = PRUDPMessageSelector(settings).select(version) self.payload_encoder = PayloadEncoder(settings) self.sequence_mgr = SequenceMgr(settings) substreams = self.max_substream_id + 1 self.sliding_windows = [SlidingWindow() for i in range(substreams)] self.fragment_buffers = [b""] * substreams self.packets = [queue.create() for i in range(substreams)] self.unreliable_packets = queue.create() self.group = None self.scheduler = None self.ping_event = None self.ack_events = {} self.connection_check = random.randint(0, 0xFFFFFFFF) self.local_session_id = random.randint(0, 0xFF) self.remote_session_id = None self.remote_signature = None self.local_addr = None self.local_port = None self.local_type = None self.remote_addr = None self.remote_port = None self.remote_type = None self.user_pid = None self.user_cid = None self.session_key = b"" self.credentials = None self.handshake_event = anyio.Event() self.close_event = anyio.Event() self.state = STATE_CONNECTING async def __aenter__(self): return self async def __aexit__(self, typ, val, tb): await self.cleanup() def bind(self, addr, port, type): self.local_addr = addr self.local_port = port self.local_type = type def connect(self, addr, port, type): self.remote_addr = addr self.remote_port = port self.remote_type = type def login(self, pid, cid, session_key): self.user_pid = pid self.user_cid = cid self.session_key = session_key self.payload_encoder.set_session_key(session_key) def configure(self, max_substream_id, supported_functions, minor_version): self.max_substream_id = max_substream_id self.supported_functions = supported_functions self.minor_ver = minor_version def remote(self, connection_signature, session_id): self.remote_signature = connection_signature self.remote_session_id = session_id async def handshake(self, credentials, group): self.group = group self.scheduler = scheduler.Scheduler(group) self.scheduler.start() self.credentials = credentials if self.credentials: self.login(credentials.pid, credentials.cid, credentials.ticket.session_key) await self.send_syn() await self.handshake_event.wait() if self.state != STATE_CONNECTED: raise RuntimeError("PRUDP connection failed") self.ping_event = self.scheduler.repeat(self.send_ping, self.ping_timeout) async def serve(self, group): self.group = group self.state = STATE_CONNECTED self.sliding_windows[0].skip() self.scheduler = scheduler.Scheduler(group) self.scheduler.start() self.ping_event = self.scheduler.repeat(self.send_ping, self.ping_timeout) async def send(self, data, substream=0): if self.state != STATE_CONNECTED: raise anyio.ClosedResourceError("PRUDP connection is closed") if not 0 <= substream <= self.max_substream_id: raise ValueError("Substream id is invalid") fragment_id = 1 while data: if len(data) <= self.fragment_size: fragment_id = 0 await self.send_fragment(data[:self.fragment_size], fragment_id, substream) data = data[self.fragment_size:] fragment_id += 1 async def send_fragment(self, data, fragment_id, substream): packet = PRUDPPacket(TYPE_DATA, FLAG_RELIABLE | FLAG_NEED_ACK | FLAG_HAS_SIZE) packet.fragment_id = fragment_id packet.substream_id = substream packet.payload = data await self.send_packet(packet) async def send_unreliable(self, data): if self.state != STATE_CONNECTED: raise anyio.ClosedResourceError("PRUDP connection is closed") packet = PRUDPPacket(TYPE_DATA, FLAG_NEED_ACK | FLAG_HAS_SIZE) packet.payload = data await self.send_packet(packet) async def send_ping(self): packet = PRUDPPacket(TYPE_PING, FLAG_RELIABLE | FLAG_NEED_ACK) await self.send_packet(packet) async def send_syn(self): packet = PRUDPPacket(TYPE_SYN, FLAG_NEED_ACK) packet.connection_signature = bytes(self.packet_encoder.signature_size()) packet.max_substream_id = self.max_substream_id packet.supported_functions = self.supported_functions packet.minor_version = self.minor_ver await self.send_packet(packet) async def send_connect(self): connection_signature = self.packet_encoder.calc_connection_signature(self.remote_addr) packet = PRUDPPacket(TYPE_CONNECT, FLAG_RELIABLE | FLAG_NEED_ACK | FLAG_HAS_SIZE) packet.connection_signature = connection_signature packet.initial_unreliable_id = self.sequence_mgr.initial_unreliable_id packet.max_substream_id = self.max_substream_id packet.minor_version = self.minor_ver packet.supported_functions = self.supported_functions packet.payload = self.build_connection_request() await self.send_packet(packet) async def send_ack(self, packet): ack = PRUDPPacket(packet.type, FLAG_ACK) ack.packet_id = packet.packet_id ack.fragment_id = packet.fragment_id ack.substream_id = packet.substream_id await self.send_packet(ack) if packet.type == TYPE_DISCONNECT: await self.send_packet(ack) await self.send_packet(ack) async def send_packet(self, packet): packet.version = self.version packet.source_port = self.local_port packet.source_type = self.local_type packet.dest_port = self.remote_port packet.dest_type = self.remote_type if not packet.flags & (FLAG_ACK | FLAG_MULTI_ACK): packet.packet_id = self.sequence_mgr.assign(packet) if packet.type != TYPE_SYN: packet.session_id = self.local_session_id if packet.type == TYPE_DATA and not packet.flags & (FLAG_ACK | FLAG_MULTI_ACK): packet.payload = self.payload_encoder.encode(packet) if packet.type == TYPE_SYN: packet.signature = self.packet_encoder.calc_packet_signature(packet, b"", b"") elif packet.type == TYPE_CONNECT: packet.signature = self.packet_encoder.calc_packet_signature(packet, b"", self.remote_signature) else: packet.signature = self.packet_encoder.calc_packet_signature(packet, self.session_key, self.remote_signature) try: await self.transport.send(packet, self.remote_addr) except util.StreamError: await self.cleanup() return if (packet.flags & FLAG_RELIABLE or packet.type == TYPE_SYN) and packet.flags & FLAG_NEED_ACK: self.schedule_timeout(packet) async def resend_packet(self, packet, counter): key = (packet.type, packet.substream_id, packet.packet_id) if counter < self.resend_limit: logger.debug("[%i] Resending packet: %s", self.local_session_id, packet) try: await self.transport.send(packet, self.remote_addr) except util.StreamError: await self.cleanup() return handle = self.scheduler.schedule(self.resend_packet, self.resend_timeout, packet, counter + 1) self.ack_events[key] = handle else: logger.error("Packet timed out: %s" %packet) await self.cleanup() def schedule_timeout(self, packet): key = (packet.type, packet.substream_id, packet.packet_id) handle = self.scheduler.schedule(self.resend_packet, self.resend_timeout, packet, 0) self.ack_events[key] = handle def build_connection_request(self): if self.credentials is None: return b"" stream = streams_nex.StreamOut(self.settings) stream.buffer(self.credentials.ticket.internal) substream = streams_nex.StreamOut(self.settings) substream.pid(self.credentials.pid) substream.u32(self.credentials.cid) substream.u32(self.connection_check) kerb = kerberos.KerberosEncryption(self.credentials.ticket.session_key) stream.buffer(kerb.encrypt(substream.get())) return stream.get() def check_connection_response(self, data): if self.credentials is not None: if len(data) != 8: raise ValueError("Connection response has wrong size") length, check_value = struct.unpack(" self.max_substream_id or \ packet.minor_version > self.minor_ver or \ packet.supported_functions & ~self.supported_functions: raise ValueError("Received SYN/ACK packet with invalid negotiation parameters") key = (packet.type, packet.substream_id, packet.packet_id) if key in self.ack_events: self.state = STATE_CONNECTED self.max_substream_id = packet.max_substream_id self.minor_ver = packet.minor_version self.supported_functions = packet.supported_functions self.remote_signature = packet.connection_signature await self.send_connect() async def process_connect(self, packet): connection_signature = self.packet_encoder.calc_connection_signature(self.remote_addr) if packet.signature != self.packet_encoder.calc_packet_signature(packet, b"", connection_signature): raise ValueError("Received CONNECT packet with invalid signature") if not packet.flags & FLAG_ACK: raise ValueError("Received unexpected CONNECT packet") if packet.packet_id != 1 or packet.fragment_id != 0 or \ packet.substream_id != 0 or any(packet.connection_signature): raise ValueError("Received invalid CONNECT/ACK packet") if packet.max_substream_id != self.max_substream_id or \ packet.minor_version != self.minor_ver or \ packet.supported_functions != self.supported_functions: raise ValueError("Received CONNECT/ACK packet with invalid negotiation parameters") key = (packet.type, packet.substream_id, packet.packet_id) if key in self.ack_events: self.check_connection_response(packet.payload) self.remote_session_id = packet.session_id self.handshake_event.set() async def process_other(self, packet): connection_signature = self.packet_encoder.calc_connection_signature(self.remote_addr) if packet.signature != self.packet_encoder.calc_packet_signature(packet, self.session_key, connection_signature): raise ValueError("Received packet with invalid signature") if packet.flags & FLAG_MULTI_ACK: self.handle_aggregate_ack(packet) else: if packet.substream_id > self.max_substream_id: raise ValueError("Received packet with invalid substream id: %i", packet.substream_id) if packet.session_id != self.remote_session_id: raise ValueError("Received packet with invalid session id") if not packet.flags & FLAG_ACK: if packet.flags & FLAG_NEED_ACK: await self.send_ack(packet) if packet.flags & FLAG_RELIABLE: await self.process_reliable(packet) else: if packet.type == TYPE_DATA: data = self.payload_encoder.decode(packet) await self.unreliable_packets.put(data) elif packet.type == TYPE_DISCONNECT: logger.info("Connection closed by other end point (forcefully)") await self.cleanup() async def process_reliable(self, packet): substream = packet.substream_id for packet in self.sliding_windows[substream].update(packet): if packet.type == TYPE_DATA: self.fragment_buffers[substream] += self.payload_encoder.decode(packet) if packet.fragment_id == 0: await self.packets[substream].put(self.fragment_buffers[substream]) self.fragment_buffers[substream] = b"" elif packet.type == TYPE_DISCONNECT: logger.info("Connection closed by other end point") await self.cleanup() def is_new_aggregate_ack(self, packet): if self.settings["prudp.transport"] == self.settings.TRANSPORT_UDP: if self.version == 0: return False return packet.substream_id == 1 return True def verify_aggregate_ack(self, packet): if packet.type != TYPE_DATA: raise ValueError("Aggregate ack must be a DATA packet") if len(packet.payload) % 2: raise ValueError("Aggregate ack payload size must be a multiple of 2") if packet.substream_id not in [0, 1]: raise ValueError("Aggregate ack packet has invalid stream id: %i" %packet.substream_id) if self.is_new_aggregate_ack(packet): if len(packet.payload) != 4 + packet.payload[1] * 2: raise ValueError("Aggregate ack payload has incorrect size") elif len(packet.payload) < 4: raise ValueError("Aggregate ack payload is too small") def handle_aggregate_ack(self, packet): self.verify_aggregate_ack(packet) if self.is_new_aggregate_ack(packet): substream = packet.payload[0] base_id = struct.unpack_from(" self.max_substream_id or \ packet.minor_version > self.minor_ver or \ packet.supported_functions & ~self.supported_functions != 0: raise ValueError("Received CONNECT packet with invalid negotiation parameters") key = (addr, packet.source_port, packet.source_type) client = self.clients.get(key) if client is None: client = PRUDPClient(self.settings, self.transport, packet.version) client.bind(self.addr, self.port, self.type) client.connect(addr, packet.source_port, packet.source_type) client.configure(packet.max_substream_id, packet.supported_functions, packet.minor_version) client.remote(packet.connection_signature, packet.session_id) response = self.process_login_request(packet.payload, client) if key not in self.clients: self.clients[key] = client self.group.start_soon(self.start_client, client) ack = PRUDPPacket(TYPE_CONNECT, FLAG_ACK | FLAG_HAS_SIZE) ack.version = packet.version ack.source_type = self.type ack.source_port = self.port ack.dest_type = packet.source_type ack.dest_port = packet.source_port ack.connection_signature = bytes(len(connection_signature)) ack.max_substream_id = packet.max_substream_id ack.supported_functions = packet.supported_functions ack.minor_version = packet.minor_version ack.session_id = client.local_session_id ack.packet_id = 1 ack.payload = response ack.signature = self.packet_encoder.calc_packet_signature(ack, b"", packet.connection_signature) await self.transport.send(ack, addr) def process_login_request(self, data, client): if self.key is None: return b"" stream = streams_nex.StreamIn(data, self.settings) ticket_data = stream.buffer() request_data = stream.buffer() ticket = kerberos.ServerTicket.decrypt(ticket_data, self.key, self.settings) if ticket.timestamp.timestamp() < time.time() - 120: raise ValueError("Ticket has expired") kerb = kerberos.KerberosEncryption(ticket.session_key) decrypted = kerb.decrypt(request_data) if len(decrypted) != self.settings["nex.pid_size"] + 8: raise ValueError("Invalid ticket size") stream = streams_nex.StreamIn(decrypted, self.settings) if stream.pid() != ticket.source: raise ValueError("Invalid pid in kerberos ticket") client.login(ticket.source, stream.u32(), ticket.session_key) check_value = stream.u32() return struct.pack("= 40000: for field in ['update_time']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.unique_id = stream.u64() self.rank = stream.u32() self.category = stream.u32() self.score = stream.u32() self.groups = stream.list(stream.u8) self.param = stream.u64() self.common_data = stream.buffer() if stream.settings["nex.version"] >= 40000: self.update_time = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.u64(self.unique_id) stream.u32(self.rank) stream.u32(self.category) stream.u32(self.score) stream.list(self.groups, stream.u8) stream.u64(self.param) stream.buffer(self.common_data) if stream.settings["nex.version"] >= 40000: stream.datetime(self.update_time) class RankingResult(common.Structure): def __init__(self): super().__init__() self.data = None self.total = None self.since_time = None def check_required(self, settings, version): for field in ['data', 'total', 'since_time']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data = stream.list(RankingRankData) self.total = stream.u32() self.since_time = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.data, stream.add) stream.u32(self.total) stream.datetime(self.since_time) class RankingCachedResult(RankingResult): def __init__(self): super().__init__() self.created_time = None self.expired_time = None self.max_length = None def check_required(self, settings, version): for field in ['created_time', 'expired_time', 'max_length']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.created_time = stream.datetime() self.expired_time = stream.datetime() self.max_length = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.datetime(self.created_time) stream.datetime(self.expired_time) stream.u8(self.max_length) common.DataHolder.register(RankingCachedResult, "RankingCachedResult") class RankingStats(common.Structure): def __init__(self): super().__init__() self.stats = None def check_required(self, settings, version): for field in ['stats']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.stats = stream.list(stream.double) def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.stats, stream.double) class RankingScoreData(common.Structure): def __init__(self): super().__init__() self.category = None self.score = None self.order = None self.update_mode = None self.groups = None self.param = None def check_required(self, settings, version): for field in ['category', 'score', 'order', 'update_mode', 'groups', 'param']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.category = stream.u32() self.score = stream.u32() self.order = stream.u8() self.update_mode = stream.u8() self.groups = stream.list(stream.u8) self.param = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.category) stream.u32(self.score) stream.u8(self.order) stream.u8(self.update_mode) stream.list(self.groups, stream.u8) stream.u64(self.param) class RankingChangeAttributesParam(common.Structure): def __init__(self): super().__init__() self.flags = None self.groups = None self.param = None def check_required(self, settings, version): for field in ['flags', 'groups', 'param']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.flags = stream.u8() self.groups = stream.list(stream.u8) self.param = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.flags) stream.list(self.groups, stream.u8) stream.u64(self.param) class RankingProtocol: METHOD_UPLOAD_SCORE = 1 METHOD_DELETE_SCORE = 2 METHOD_DELETE_ALL_SCORES = 3 METHOD_UPLOAD_COMMON_DATA = 4 METHOD_DELETE_COMMON_DATA = 5 METHOD_GET_COMMON_DATA = 6 METHOD_CHANGE_ATTRIBUTES = 7 METHOD_CHANGE_ALL_ATTRIBUTES = 8 METHOD_GET_RANKING = 9 METHOD_GET_APPROX_ORDER = 10 METHOD_GET_STATS = 11 METHOD_GET_RANKING_BY_PID_LIST = 12 METHOD_GET_RANKING_BY_UNIQUE_ID_LIST = 13 METHOD_GET_CACHED_TOPX_RANKING = 14 METHOD_GET_CACHED_TOPX_RANKINGS = 15 PROTOCOL_ID = 0x70 class RankingClient(RankingProtocol): def __init__(self, client): self.settings = client.settings self.client = client async def upload_score(self, score_data, unique_id): logger.info("RankingClient.upload_score()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(score_data) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPLOAD_SCORE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClient.upload_score -> done") async def delete_score(self, category, unique_id): logger.info("RankingClient.delete_score()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(category) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_SCORE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClient.delete_score -> done") async def delete_all_scores(self, unique_id): logger.info("RankingClient.delete_all_scores()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_ALL_SCORES, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClient.delete_all_scores -> done") async def upload_common_data(self, common_data, unique_id): logger.info("RankingClient.upload_common_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.buffer(common_data) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPLOAD_COMMON_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClient.upload_common_data -> done") async def delete_common_data(self, unique_id): logger.info("RankingClient.delete_common_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_COMMON_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClient.delete_common_data -> done") async def get_common_data(self, unique_id): logger.info("RankingClient.get_common_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_COMMON_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) data = stream.buffer() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClient.get_common_data -> done") return data async def change_attributes(self, category, param, unique_id): logger.info("RankingClient.change_attributes()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(category) stream.add(param) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CHANGE_ATTRIBUTES, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClient.change_attributes -> done") async def change_all_attributes(self, param, unique_id): logger.info("RankingClient.change_all_attributes()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CHANGE_ALL_ATTRIBUTES, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClient.change_all_attributes -> done") async def get_ranking(self, mode, category, order, unique_id, pid): logger.info("RankingClient.get_ranking()") #--- request --- stream = streams.StreamOut(self.settings) stream.u8(mode) stream.u32(category) stream.add(order) stream.u64(unique_id) stream.pid(pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RANKING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.extract(RankingResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClient.get_ranking -> done") return result async def get_approx_order(self, category, order, score, unique_id, pid): logger.info("RankingClient.get_approx_order()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(category) stream.add(order) stream.u32(score) stream.u64(unique_id) stream.pid(pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_APPROX_ORDER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) order = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClient.get_approx_order -> done") return order async def get_stats(self, category, order, flags): logger.info("RankingClient.get_stats()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(category) stream.add(order) stream.u32(flags) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) stats = stream.extract(RankingStats) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClient.get_stats -> done") return stats async def get_ranking_by_pid_list(self, pids, mode, category, order, unique_id): logger.info("RankingClient.get_ranking_by_pid_list()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) stream.u8(mode) stream.u32(category) stream.add(order) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RANKING_BY_PID_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.extract(RankingResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClient.get_ranking_by_pid_list -> done") return result async def get_ranking_by_unique_id_list(self, ids, mode, category, order, unique_id): logger.info("RankingClient.get_ranking_by_unique_id_list()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(ids, stream.u64) stream.u8(mode) stream.u32(category) stream.add(order) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RANKING_BY_UNIQUE_ID_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.extract(RankingResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClient.get_ranking_by_unique_id_list -> done") return result async def get_cached_topx_ranking(self, category, order): logger.info("RankingClient.get_cached_topx_ranking()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(category) stream.add(order) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_CACHED_TOPX_RANKING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.extract(RankingCachedResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClient.get_cached_topx_ranking -> done") return result async def get_cached_topx_rankings(self, categories, order): logger.info("RankingClient.get_cached_topx_rankings()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(categories, stream.u32) stream.list(order, stream.add) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_CACHED_TOPX_RANKINGS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) results = stream.list(RankingCachedResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClient.get_cached_topx_rankings -> done") return results class RankingServer(RankingProtocol): def __init__(self): self.methods = { self.METHOD_UPLOAD_SCORE: self.handle_upload_score, self.METHOD_DELETE_SCORE: self.handle_delete_score, self.METHOD_DELETE_ALL_SCORES: self.handle_delete_all_scores, self.METHOD_UPLOAD_COMMON_DATA: self.handle_upload_common_data, self.METHOD_DELETE_COMMON_DATA: self.handle_delete_common_data, self.METHOD_GET_COMMON_DATA: self.handle_get_common_data, self.METHOD_CHANGE_ATTRIBUTES: self.handle_change_attributes, self.METHOD_CHANGE_ALL_ATTRIBUTES: self.handle_change_all_attributes, self.METHOD_GET_RANKING: self.handle_get_ranking, self.METHOD_GET_APPROX_ORDER: self.handle_get_approx_order, self.METHOD_GET_STATS: self.handle_get_stats, self.METHOD_GET_RANKING_BY_PID_LIST: self.handle_get_ranking_by_pid_list, self.METHOD_GET_RANKING_BY_UNIQUE_ID_LIST: self.handle_get_ranking_by_unique_id_list, self.METHOD_GET_CACHED_TOPX_RANKING: self.handle_get_cached_topx_ranking, self.METHOD_GET_CACHED_TOPX_RANKINGS: self.handle_get_cached_topx_rankings, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on RankingServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_upload_score(self, client, input, output): logger.info("RankingServer.upload_score()") #--- request --- score_data = input.extract(RankingScoreData) unique_id = input.u64() await self.upload_score(client, score_data, unique_id) async def handle_delete_score(self, client, input, output): logger.info("RankingServer.delete_score()") #--- request --- category = input.u32() unique_id = input.u64() await self.delete_score(client, category, unique_id) async def handle_delete_all_scores(self, client, input, output): logger.info("RankingServer.delete_all_scores()") #--- request --- unique_id = input.u64() await self.delete_all_scores(client, unique_id) async def handle_upload_common_data(self, client, input, output): logger.info("RankingServer.upload_common_data()") #--- request --- common_data = input.buffer() unique_id = input.u64() await self.upload_common_data(client, common_data, unique_id) async def handle_delete_common_data(self, client, input, output): logger.info("RankingServer.delete_common_data()") #--- request --- unique_id = input.u64() await self.delete_common_data(client, unique_id) async def handle_get_common_data(self, client, input, output): logger.info("RankingServer.get_common_data()") #--- request --- unique_id = input.u64() response = await self.get_common_data(client, unique_id) #--- response --- if not isinstance(response, bytes): raise RuntimeError("Expected bytes, got %s" %response.__class__.__name__) output.buffer(response) async def handle_change_attributes(self, client, input, output): logger.info("RankingServer.change_attributes()") #--- request --- category = input.u32() param = input.extract(RankingChangeAttributesParam) unique_id = input.u64() await self.change_attributes(client, category, param, unique_id) async def handle_change_all_attributes(self, client, input, output): logger.info("RankingServer.change_all_attributes()") #--- request --- param = input.extract(RankingChangeAttributesParam) unique_id = input.u64() await self.change_all_attributes(client, param, unique_id) async def handle_get_ranking(self, client, input, output): logger.info("RankingServer.get_ranking()") #--- request --- mode = input.u8() category = input.u32() order = input.extract(RankingOrderParam) unique_id = input.u64() pid = input.pid() response = await self.get_ranking(client, mode, category, order, unique_id, pid) #--- response --- if not isinstance(response, RankingResult): raise RuntimeError("Expected RankingResult, got %s" %response.__class__.__name__) output.add(response) async def handle_get_approx_order(self, client, input, output): logger.info("RankingServer.get_approx_order()") #--- request --- category = input.u32() order = input.extract(RankingOrderParam) score = input.u32() unique_id = input.u64() pid = input.pid() response = await self.get_approx_order(client, category, order, score, unique_id, pid) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u32(response) async def handle_get_stats(self, client, input, output): logger.info("RankingServer.get_stats()") #--- request --- category = input.u32() order = input.extract(RankingOrderParam) flags = input.u32() response = await self.get_stats(client, category, order, flags) #--- response --- if not isinstance(response, RankingStats): raise RuntimeError("Expected RankingStats, got %s" %response.__class__.__name__) output.add(response) async def handle_get_ranking_by_pid_list(self, client, input, output): logger.info("RankingServer.get_ranking_by_pid_list()") #--- request --- pids = input.list(input.pid) mode = input.u8() category = input.u32() order = input.extract(RankingOrderParam) unique_id = input.u64() response = await self.get_ranking_by_pid_list(client, pids, mode, category, order, unique_id) #--- response --- if not isinstance(response, RankingResult): raise RuntimeError("Expected RankingResult, got %s" %response.__class__.__name__) output.add(response) async def handle_get_ranking_by_unique_id_list(self, client, input, output): logger.info("RankingServer.get_ranking_by_unique_id_list()") #--- request --- ids = input.list(input.u64) mode = input.u8() category = input.u32() order = input.extract(RankingOrderParam) unique_id = input.u64() response = await self.get_ranking_by_unique_id_list(client, ids, mode, category, order, unique_id) #--- response --- if not isinstance(response, RankingResult): raise RuntimeError("Expected RankingResult, got %s" %response.__class__.__name__) output.add(response) async def handle_get_cached_topx_ranking(self, client, input, output): logger.info("RankingServer.get_cached_topx_ranking()") #--- request --- category = input.u32() order = input.extract(RankingOrderParam) response = await self.get_cached_topx_ranking(client, category, order) #--- response --- if not isinstance(response, RankingCachedResult): raise RuntimeError("Expected RankingCachedResult, got %s" %response.__class__.__name__) output.add(response) async def handle_get_cached_topx_rankings(self, client, input, output): logger.info("RankingServer.get_cached_topx_rankings()") #--- request --- categories = input.list(input.u32) order = input.list(RankingOrderParam) response = await self.get_cached_topx_rankings(client, categories, order) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def upload_score(self, *args): logger.warning("RankingServer.upload_score not implemented") raise common.RMCError("Core::NotImplemented") async def delete_score(self, *args): logger.warning("RankingServer.delete_score not implemented") raise common.RMCError("Core::NotImplemented") async def delete_all_scores(self, *args): logger.warning("RankingServer.delete_all_scores not implemented") raise common.RMCError("Core::NotImplemented") async def upload_common_data(self, *args): logger.warning("RankingServer.upload_common_data not implemented") raise common.RMCError("Core::NotImplemented") async def delete_common_data(self, *args): logger.warning("RankingServer.delete_common_data not implemented") raise common.RMCError("Core::NotImplemented") async def get_common_data(self, *args): logger.warning("RankingServer.get_common_data not implemented") raise common.RMCError("Core::NotImplemented") async def change_attributes(self, *args): logger.warning("RankingServer.change_attributes not implemented") raise common.RMCError("Core::NotImplemented") async def change_all_attributes(self, *args): logger.warning("RankingServer.change_all_attributes not implemented") raise common.RMCError("Core::NotImplemented") async def get_ranking(self, *args): logger.warning("RankingServer.get_ranking not implemented") raise common.RMCError("Core::NotImplemented") async def get_approx_order(self, *args): logger.warning("RankingServer.get_approx_order not implemented") raise common.RMCError("Core::NotImplemented") async def get_stats(self, *args): logger.warning("RankingServer.get_stats not implemented") raise common.RMCError("Core::NotImplemented") async def get_ranking_by_pid_list(self, *args): logger.warning("RankingServer.get_ranking_by_pid_list not implemented") raise common.RMCError("Core::NotImplemented") async def get_ranking_by_unique_id_list(self, *args): logger.warning("RankingServer.get_ranking_by_unique_id_list not implemented") raise common.RMCError("Core::NotImplemented") async def get_cached_topx_ranking(self, *args): logger.warning("RankingServer.get_cached_topx_ranking not implemented") raise common.RMCError("Core::NotImplemented") async def get_cached_topx_rankings(self, *args): logger.warning("RankingServer.get_cached_topx_rankings not implemented") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/ranking2.py ================================================ # This file was generated automatically by generate_protocols.py from nintendo.nex import notification, rmc, common, streams import logging logger = logging.getLogger(__name__) class RankingMode: GLOBAL_AROUND_SELF = 1 GLOBAL = 2 FRIENDS = 3 class Ranking2CategorySetting(common.Structure): def __init__(self): super().__init__() self.min_score = None self.max_score = None self.lowest_rank = None self.reset_month = None self.reset_day = None self.reset_hour = None self.reset_mode = None self.max_seasons_to_go_back = None self.score_order = None def check_required(self, settings, version): for field in ['min_score', 'max_score', 'lowest_rank', 'reset_month', 'reset_day', 'reset_hour', 'reset_mode', 'max_seasons_to_go_back', 'score_order']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.min_score = stream.u32() self.max_score = stream.u32() self.lowest_rank = stream.u32() self.reset_month = stream.u16() self.reset_day = stream.u8() self.reset_hour = stream.u8() self.reset_mode = stream.u8() self.max_seasons_to_go_back = stream.u8() self.score_order = stream.bool() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.min_score) stream.u32(self.max_score) stream.u32(self.lowest_rank) stream.u16(self.reset_month) stream.u8(self.reset_day) stream.u8(self.reset_hour) stream.u8(self.reset_mode) stream.u8(self.max_seasons_to_go_back) stream.bool(self.score_order) class Ranking2ChartInfo(common.Structure): def __init__(self): super().__init__() self.create_time = None self.index = None self.category = None self.season = None self.bins_size = None self.sampling_rate = None self.score_order = None self.estimate_length = None self.estimate_highest_score = None self.estimate_lowest_score = None self.estimate_median_score = None self.estimate_average_score = None self.highest_bins_score = None self.lowest_bins_score = None self.bins_width = None self.attribute1 = None self.attribute2 = None self.quantities = None def check_required(self, settings, version): for field in ['create_time', 'index', 'category', 'season', 'bins_size', 'sampling_rate', 'score_order', 'estimate_length', 'estimate_highest_score', 'estimate_lowest_score', 'estimate_median_score', 'estimate_average_score', 'highest_bins_score', 'lowest_bins_score', 'bins_width', 'attribute1', 'attribute2', 'quantities']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.create_time = stream.datetime() self.index = stream.u32() self.category = stream.u32() self.season = stream.s32() self.bins_size = stream.u8() self.sampling_rate = stream.u8() self.score_order = stream.bool() self.estimate_length = stream.u32() self.estimate_highest_score = stream.u32() self.estimate_lowest_score = stream.u32() self.estimate_median_score = stream.u32() self.estimate_average_score = stream.double() self.highest_bins_score = stream.u32() self.lowest_bins_score = stream.u32() self.bins_width = stream.u32() self.attribute1 = stream.u32() self.attribute2 = stream.u32() self.quantities = stream.list(stream.u32) def save(self, stream, version): self.check_required(stream.settings, version) stream.datetime(self.create_time) stream.u32(self.index) stream.u32(self.category) stream.s32(self.season) stream.u8(self.bins_size) stream.u8(self.sampling_rate) stream.bool(self.score_order) stream.u32(self.estimate_length) stream.u32(self.estimate_highest_score) stream.u32(self.estimate_lowest_score) stream.u32(self.estimate_median_score) stream.double(self.estimate_average_score) stream.u32(self.highest_bins_score) stream.u32(self.lowest_bins_score) stream.u32(self.bins_width) stream.u32(self.attribute1) stream.u32(self.attribute2) stream.list(self.quantities, stream.u32) class Ranking2ChartInfoInput(common.Structure): def __init__(self): super().__init__() self.chart_index = None self.seasons_to_go_back = None def check_required(self, settings, version): for field in ['chart_index', 'seasons_to_go_back']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.chart_index = stream.u32() self.seasons_to_go_back = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.chart_index) stream.u8(self.seasons_to_go_back) class Ranking2CommonData(common.Structure): def __init__(self): super().__init__() self.username = None self.mii = None self.binary_data = None def check_required(self, settings, version): for field in ['username', 'mii', 'binary_data']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.username = stream.string() self.mii = stream.qbuffer() self.binary_data = stream.qbuffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.username) stream.qbuffer(self.mii) stream.qbuffer(self.binary_data) class Ranking2EstimateScoreRankInput(common.Structure): def __init__(self): super().__init__() self.category = None self.seasons_to_go_back = None self.score = None def check_required(self, settings, version): for field in ['category', 'seasons_to_go_back', 'score']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.category = stream.u32() self.seasons_to_go_back = stream.u8() self.score = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.category) stream.u8(self.seasons_to_go_back) stream.u32(self.score) class Ranking2EstimateScoreRankOutput(common.Structure): def __init__(self): super().__init__() self.rank = None self.length = None self.score = None self.category = None self.season = None self.sampling_rate = None def check_required(self, settings, version): for field in ['rank', 'length', 'score', 'category', 'season', 'sampling_rate']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.rank = stream.u32() self.length = stream.u32() self.score = stream.u32() self.category = stream.u32() self.season = stream.s32() self.sampling_rate = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.rank) stream.u32(self.length) stream.u32(self.score) stream.u32(self.category) stream.s32(self.season) stream.u8(self.sampling_rate) class Ranking2GetByListParam(common.Structure): def __init__(self): super().__init__() self.category = None self.offset = None self.length = None self.sort_flags = None self.option_flags = None self.seasons_to_go_back = None def check_required(self, settings, version): for field in ['category', 'offset', 'length', 'sort_flags', 'option_flags', 'seasons_to_go_back']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.category = stream.u32() self.offset = stream.u32() self.length = stream.u32() self.sort_flags = stream.u32() self.option_flags = stream.u32() self.seasons_to_go_back = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.category) stream.u32(self.offset) stream.u32(self.length) stream.u32(self.sort_flags) stream.u32(self.option_flags) stream.u8(self.seasons_to_go_back) class Ranking2GetParam(common.Structure): def __init__(self): super().__init__() self.unique_id = 0 self.pid = 0 self.category = None self.offset = 0 self.count = 10 self.sort_flags = 0 self.option_flags = 0 self.mode = 2 self.seasons_to_go_back = 0 def check_required(self, settings, version): for field in ['category']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.unique_id = stream.u64() self.pid = stream.pid() self.category = stream.u32() self.offset = stream.u32() self.count = stream.u32() self.sort_flags = stream.u32() self.option_flags = stream.u32() self.mode = stream.u8() self.seasons_to_go_back = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.unique_id) stream.pid(self.pid) stream.u32(self.category) stream.u32(self.offset) stream.u32(self.count) stream.u32(self.sort_flags) stream.u32(self.option_flags) stream.u8(self.mode) stream.u8(self.seasons_to_go_back) class Ranking2Info(common.Structure): def __init__(self): super().__init__() self.data = None self.lowest_rank = None self.num_entries = None self.season = None def check_required(self, settings, version): for field in ['data', 'lowest_rank', 'num_entries', 'season']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data = stream.list(Ranking2RankData) self.lowest_rank = stream.u32() self.num_entries = stream.u32() self.season = stream.s32() def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.data, stream.add) stream.u32(self.lowest_rank) stream.u32(self.num_entries) stream.s32(self.season) class Ranking2RankData(common.Structure): def __init__(self): super().__init__() self.misc = None self.unique_id = None self.pid = None self.rank = None self.score = None self.common_data = Ranking2CommonData() def check_required(self, settings, version): for field in ['misc', 'unique_id', 'pid', 'rank', 'score']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.misc = stream.u64() self.unique_id = stream.u64() self.pid = stream.pid() self.rank = stream.u32() self.score = stream.u32() self.common_data = stream.extract(Ranking2CommonData) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.misc) stream.u64(self.unique_id) stream.pid(self.pid) stream.u32(self.rank) stream.u32(self.score) stream.add(self.common_data) class Ranking2ScoreData(common.Structure): def __init__(self): super().__init__() self.misc = None self.category = None self.score = None def check_required(self, settings, version): for field in ['misc', 'category', 'score']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.misc = stream.u64() self.category = stream.u32() self.score = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.misc) stream.u32(self.category) stream.u32(self.score) class Ranking2Protocol: METHOD_PUT_SCORE = 1 METHOD_GET_COMMON_DATA = 2 METHOD_PUT_COMMON_DATA = 3 METHOD_DELETE_COMMON_DATA = 4 METHOD_GET_RANKING = 5 METHOD_GET_RANKING_BY_PRINCIPAL_ID = 6 METHOD_GET_CATEGORY_SETTING = 7 METHOD_GET_RANKING_CHART = 8 METHOD_GET_RANKING_CHARTS = 9 METHOD_GET_ESTIMATE_SCORE_RANK = 10 PROTOCOL_ID = 0x7A class Ranking2Client(Ranking2Protocol): def __init__(self, client): self.settings = client.settings self.client = client async def put_score(self, socres, unique_id): logger.info("Ranking2Client.put_score()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(socres, stream.add) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PUT_SCORE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("Ranking2Client.put_score -> done") async def get_common_data(self, option_flags, pid, unique_id): logger.info("Ranking2Client.get_common_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(option_flags) stream.pid(pid) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_COMMON_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) common_data = stream.extract(Ranking2CommonData) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("Ranking2Client.get_common_data -> done") return common_data async def put_common_data(self, data, unique_id): logger.info("Ranking2Client.put_common_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(data) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PUT_COMMON_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("Ranking2Client.put_common_data -> done") async def delete_common_data(self, unique_id): logger.info("Ranking2Client.delete_common_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_COMMON_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("Ranking2Client.delete_common_data -> done") async def get_ranking(self, param): logger.info("Ranking2Client.get_ranking()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RANKING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(Ranking2Info) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("Ranking2Client.get_ranking -> done") return info async def get_ranking_by_principal_id(self, param, pids): logger.info("Ranking2Client.get_ranking_by_principal_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) stream.list(pids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RANKING_BY_PRINCIPAL_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(Ranking2Info) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("Ranking2Client.get_ranking_by_principal_id -> done") return info async def get_category_setting(self, category): logger.info("Ranking2Client.get_category_setting()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(category) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_CATEGORY_SETTING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) setting = stream.extract(Ranking2CategorySetting) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("Ranking2Client.get_category_setting -> done") return setting async def get_ranking_chart(self, input): logger.info("Ranking2Client.get_ranking_chart()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(input) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RANKING_CHART, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(Ranking2ChartInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("Ranking2Client.get_ranking_chart -> done") return info async def get_ranking_charts(self, inputs): logger.info("Ranking2Client.get_ranking_charts()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(inputs, stream.add) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RANKING_CHARTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) infos = stream.list(Ranking2ChartInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("Ranking2Client.get_ranking_charts -> done") return infos async def get_estimate_score_rank(self, input): logger.info("Ranking2Client.get_estimate_score_rank()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(input) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_ESTIMATE_SCORE_RANK, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) output = stream.extract(Ranking2EstimateScoreRankOutput) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("Ranking2Client.get_estimate_score_rank -> done") return output class Ranking2Server(Ranking2Protocol): def __init__(self): self.methods = { self.METHOD_PUT_SCORE: self.handle_put_score, self.METHOD_GET_COMMON_DATA: self.handle_get_common_data, self.METHOD_PUT_COMMON_DATA: self.handle_put_common_data, self.METHOD_DELETE_COMMON_DATA: self.handle_delete_common_data, self.METHOD_GET_RANKING: self.handle_get_ranking, self.METHOD_GET_RANKING_BY_PRINCIPAL_ID: self.handle_get_ranking_by_principal_id, self.METHOD_GET_CATEGORY_SETTING: self.handle_get_category_setting, self.METHOD_GET_RANKING_CHART: self.handle_get_ranking_chart, self.METHOD_GET_RANKING_CHARTS: self.handle_get_ranking_charts, self.METHOD_GET_ESTIMATE_SCORE_RANK: self.handle_get_estimate_score_rank, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on Ranking2Server: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_put_score(self, client, input, output): logger.info("Ranking2Server.put_score()") #--- request --- socres = input.list(Ranking2ScoreData) unique_id = input.u64() await self.put_score(client, socres, unique_id) async def handle_get_common_data(self, client, input, output): logger.info("Ranking2Server.get_common_data()") #--- request --- option_flags = input.u32() pid = input.pid() unique_id = input.u64() response = await self.get_common_data(client, option_flags, pid, unique_id) #--- response --- if not isinstance(response, Ranking2CommonData): raise RuntimeError("Expected Ranking2CommonData, got %s" %response.__class__.__name__) output.add(response) async def handle_put_common_data(self, client, input, output): logger.info("Ranking2Server.put_common_data()") #--- request --- data = input.extract(Ranking2CommonData) unique_id = input.u64() await self.put_common_data(client, data, unique_id) async def handle_delete_common_data(self, client, input, output): logger.info("Ranking2Server.delete_common_data()") #--- request --- unique_id = input.u64() await self.delete_common_data(client, unique_id) async def handle_get_ranking(self, client, input, output): logger.info("Ranking2Server.get_ranking()") #--- request --- param = input.extract(Ranking2GetParam) response = await self.get_ranking(client, param) #--- response --- if not isinstance(response, Ranking2Info): raise RuntimeError("Expected Ranking2Info, got %s" %response.__class__.__name__) output.add(response) async def handle_get_ranking_by_principal_id(self, client, input, output): logger.info("Ranking2Server.get_ranking_by_principal_id()") #--- request --- param = input.extract(Ranking2GetByListParam) pids = input.list(input.pid) response = await self.get_ranking_by_principal_id(client, param, pids) #--- response --- if not isinstance(response, Ranking2Info): raise RuntimeError("Expected Ranking2Info, got %s" %response.__class__.__name__) output.add(response) async def handle_get_category_setting(self, client, input, output): logger.info("Ranking2Server.get_category_setting()") #--- request --- category = input.u32() response = await self.get_category_setting(client, category) #--- response --- if not isinstance(response, Ranking2CategorySetting): raise RuntimeError("Expected Ranking2CategorySetting, got %s" %response.__class__.__name__) output.add(response) async def handle_get_ranking_chart(self, client, input, output): logger.info("Ranking2Server.get_ranking_chart()") #--- request --- input = input.extract(Ranking2ChartInfoInput) response = await self.get_ranking_chart(client, input) #--- response --- if not isinstance(response, Ranking2ChartInfo): raise RuntimeError("Expected Ranking2ChartInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_ranking_charts(self, client, input, output): logger.info("Ranking2Server.get_ranking_charts()") #--- request --- inputs = input.list(Ranking2ChartInfoInput) response = await self.get_ranking_charts(client, inputs) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_estimate_score_rank(self, client, input, output): logger.info("Ranking2Server.get_estimate_score_rank()") #--- request --- input = input.extract(Ranking2EstimateScoreRankInput) response = await self.get_estimate_score_rank(client, input) #--- response --- if not isinstance(response, Ranking2EstimateScoreRankOutput): raise RuntimeError("Expected Ranking2EstimateScoreRankOutput, got %s" %response.__class__.__name__) output.add(response) async def put_score(self, *args): logger.warning("Ranking2Server.put_score not implemented") raise common.RMCError("Core::NotImplemented") async def get_common_data(self, *args): logger.warning("Ranking2Server.get_common_data not implemented") raise common.RMCError("Core::NotImplemented") async def put_common_data(self, *args): logger.warning("Ranking2Server.put_common_data not implemented") raise common.RMCError("Core::NotImplemented") async def delete_common_data(self, *args): logger.warning("Ranking2Server.delete_common_data not implemented") raise common.RMCError("Core::NotImplemented") async def get_ranking(self, *args): logger.warning("Ranking2Server.get_ranking not implemented") raise common.RMCError("Core::NotImplemented") async def get_ranking_by_principal_id(self, *args): logger.warning("Ranking2Server.get_ranking_by_principal_id not implemented") raise common.RMCError("Core::NotImplemented") async def get_category_setting(self, *args): logger.warning("Ranking2Server.get_category_setting not implemented") raise common.RMCError("Core::NotImplemented") async def get_ranking_chart(self, *args): logger.warning("Ranking2Server.get_ranking_chart not implemented") raise common.RMCError("Core::NotImplemented") async def get_ranking_charts(self, *args): logger.warning("Ranking2Server.get_ranking_charts not implemented") raise common.RMCError("Core::NotImplemented") async def get_estimate_score_rank(self, *args): logger.warning("Ranking2Server.get_estimate_score_rank not implemented") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/ranking2_eagle.py ================================================ # This file was generated automatically by generate_protocols.py from nintendo.nex import notification, rmc, common, streams import logging logger = logging.getLogger(__name__) class RankingMode: GLOBAL_AROUND_SELF = 1 GLOBAL = 2 FRIENDS = 3 class Ranking2CategorySetting(common.Structure): def __init__(self): super().__init__() self.min_score = None self.max_score = None self.lowest_rank = None self.reset_month = None self.reset_day = None self.reset_hour = None self.reset_mode = None self.max_seasons_to_go_back = None self.score_order = None def check_required(self, settings, version): for field in ['min_score', 'max_score', 'lowest_rank', 'reset_month', 'reset_day', 'reset_hour', 'reset_mode', 'max_seasons_to_go_back', 'score_order']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.min_score = stream.u32() self.max_score = stream.u32() self.lowest_rank = stream.u32() self.reset_month = stream.u16() self.reset_day = stream.u8() self.reset_hour = stream.u8() self.reset_mode = stream.u8() self.max_seasons_to_go_back = stream.u8() self.score_order = stream.bool() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.min_score) stream.u32(self.max_score) stream.u32(self.lowest_rank) stream.u16(self.reset_month) stream.u8(self.reset_day) stream.u8(self.reset_hour) stream.u8(self.reset_mode) stream.u8(self.max_seasons_to_go_back) stream.bool(self.score_order) class Ranking2ChartInfo(common.Structure): def __init__(self): super().__init__() self.create_time = None self.index = None self.category = None self.season = None self.bins_size = None self.sampling_rate = None self.score_order = None self.estimate_length = None self.estimate_highest_score = None self.estimate_lowest_score = None self.estimate_median_score = None self.estimate_average_score = None self.highest_bins_score = None self.lowest_bins_score = None self.bins_width = None self.attribute1 = None self.attribute2 = None self.quantities = None def check_required(self, settings, version): for field in ['create_time', 'index', 'category', 'season', 'bins_size', 'sampling_rate', 'score_order', 'estimate_length', 'estimate_highest_score', 'estimate_lowest_score', 'estimate_median_score', 'estimate_average_score', 'highest_bins_score', 'lowest_bins_score', 'bins_width', 'attribute1', 'attribute2', 'quantities']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.create_time = stream.datetime() self.index = stream.u32() self.category = stream.u32() self.season = stream.s32() self.bins_size = stream.u8() self.sampling_rate = stream.u8() self.score_order = stream.bool() self.estimate_length = stream.u32() self.estimate_highest_score = stream.u32() self.estimate_lowest_score = stream.u32() self.estimate_median_score = stream.u32() self.estimate_average_score = stream.double() self.highest_bins_score = stream.u32() self.lowest_bins_score = stream.u32() self.bins_width = stream.u32() self.attribute1 = stream.u32() self.attribute2 = stream.u32() self.quantities = stream.list(stream.u32) def save(self, stream, version): self.check_required(stream.settings, version) stream.datetime(self.create_time) stream.u32(self.index) stream.u32(self.category) stream.s32(self.season) stream.u8(self.bins_size) stream.u8(self.sampling_rate) stream.bool(self.score_order) stream.u32(self.estimate_length) stream.u32(self.estimate_highest_score) stream.u32(self.estimate_lowest_score) stream.u32(self.estimate_median_score) stream.double(self.estimate_average_score) stream.u32(self.highest_bins_score) stream.u32(self.lowest_bins_score) stream.u32(self.bins_width) stream.u32(self.attribute1) stream.u32(self.attribute2) stream.list(self.quantities, stream.u32) class Ranking2ChartInfoInput(common.Structure): def __init__(self): super().__init__() self.chart_index = None self.seasons_to_go_back = None def check_required(self, settings, version): for field in ['chart_index', 'seasons_to_go_back']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.chart_index = stream.u32() self.seasons_to_go_back = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.chart_index) stream.u8(self.seasons_to_go_back) class Ranking2CommonData(common.Structure): def __init__(self): super().__init__() self.username = None self.mii = None self.binary_data = None def check_required(self, settings, version): for field in ['username', 'mii', 'binary_data']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.username = stream.string() self.mii = stream.qbuffer() self.binary_data = stream.qbuffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.username) stream.qbuffer(self.mii) stream.qbuffer(self.binary_data) class Ranking2EstimateScoreRankInput(common.Structure): def __init__(self): super().__init__() self.category = None self.seasons_to_go_back = None self.score = None def check_required(self, settings, version): for field in ['category', 'seasons_to_go_back', 'score']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.category = stream.u32() self.seasons_to_go_back = stream.u8() self.score = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.category) stream.u8(self.seasons_to_go_back) stream.u32(self.score) class Ranking2EstimateScoreRankOutput(common.Structure): def __init__(self): super().__init__() self.rank = None self.length = None self.score = None self.category = None self.season = None self.sampling_rate = None def check_required(self, settings, version): for field in ['rank', 'length', 'score', 'category', 'season', 'sampling_rate']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.rank = stream.u32() self.length = stream.u32() self.score = stream.u32() self.category = stream.u32() self.season = stream.s32() self.sampling_rate = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.rank) stream.u32(self.length) stream.u32(self.score) stream.u32(self.category) stream.s32(self.season) stream.u8(self.sampling_rate) class Ranking2GetByListParam(common.Structure): def __init__(self): super().__init__() self.category = None self.offset = None self.length = None self.sort_flags = None self.option_flags = None self.seasons_to_go_back = None def check_required(self, settings, version): for field in ['category', 'offset', 'length', 'sort_flags', 'option_flags', 'seasons_to_go_back']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.category = stream.u32() self.offset = stream.u32() self.length = stream.u32() self.sort_flags = stream.u32() self.option_flags = stream.u32() self.seasons_to_go_back = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.category) stream.u32(self.offset) stream.u32(self.length) stream.u32(self.sort_flags) stream.u32(self.option_flags) stream.u8(self.seasons_to_go_back) class Ranking2GetParam(common.Structure): def __init__(self): super().__init__() self.unique_id = 0 self.pid = 0 self.category = None self.offset = 0 self.count = 10 self.sort_flags = 0 self.option_flags = 0 self.mode = 2 self.seasons_to_go_back = 0 def check_required(self, settings, version): for field in ['category']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.unique_id = stream.u64() self.pid = stream.pid() self.category = stream.u32() self.offset = stream.u32() self.count = stream.u32() self.sort_flags = stream.u32() self.option_flags = stream.u32() self.mode = stream.u8() self.seasons_to_go_back = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.unique_id) stream.pid(self.pid) stream.u32(self.category) stream.u32(self.offset) stream.u32(self.count) stream.u32(self.sort_flags) stream.u32(self.option_flags) stream.u8(self.mode) stream.u8(self.seasons_to_go_back) class Ranking2Info(common.Structure): def __init__(self): super().__init__() self.data = None self.lowest_rank = None self.num_entries = None self.season = None def check_required(self, settings, version): for field in ['data', 'lowest_rank', 'num_entries', 'season']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data = stream.list(Ranking2RankData) self.lowest_rank = stream.u32() self.num_entries = stream.u32() self.season = stream.s32() def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.data, stream.add) stream.u32(self.lowest_rank) stream.u32(self.num_entries) stream.s32(self.season) class Ranking2RankData(common.Structure): def __init__(self): super().__init__() self.misc = None self.unique_id = None self.pid = None self.rank = None self.score = None self.common_data = Ranking2CommonData() def check_required(self, settings, version): for field in ['misc', 'unique_id', 'pid', 'rank', 'score']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.misc = stream.u64() self.unique_id = stream.u64() self.pid = stream.pid() self.rank = stream.u32() self.score = stream.u32() self.common_data = stream.extract(Ranking2CommonData) def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.misc) stream.u64(self.unique_id) stream.pid(self.pid) stream.u32(self.rank) stream.u32(self.score) stream.add(self.common_data) class Ranking2ScoreData(common.Structure): def __init__(self): super().__init__() self.misc = None self.category = None self.score = None def check_required(self, settings, version): for field in ['misc', 'category', 'score']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.misc = stream.u64() self.category = stream.u32() self.score = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.misc) stream.u32(self.category) stream.u32(self.score) class Ranking2EstimateMyScoreRankInput(common.Structure): def __init__(self): super().__init__() self.category = None self.seasons_to_go_back = None def check_required(self, settings, version): for field in ['category', 'seasons_to_go_back']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.category = stream.u32() self.seasons_to_go_back = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.category) stream.u8(self.seasons_to_go_back) class Ranking2Protocol: METHOD_PUT_SCORE = 1 METHOD_GET_COMMON_DATA = 2 METHOD_PUT_COMMON_DATA = 3 METHOD_DELETE_COMMON_DATA = 4 METHOD_GET_RANKING = 5 METHOD_GET_RANKING_BY_PRINCIPAL_ID = 6 METHOD_GET_CATEGORY_SETTING = 7 METHOD_GET_RANKING_CHART = 8 METHOD_GET_RANKING_CHARTS = 9 METHOD_GET_ESTIMATE_SCORE_RANK = 10 METHOD_GET_ESTIMATE_MY_SCORE_RANK = 11 PROTOCOL_ID = 0x7A class Ranking2Client(Ranking2Protocol): def __init__(self, client): self.settings = client.settings self.client = client async def put_score(self, socres, unique_id): logger.info("Ranking2Client.put_score()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(socres, stream.add) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PUT_SCORE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("Ranking2Client.put_score -> done") async def get_common_data(self, option_flags, pid, unique_id): logger.info("Ranking2Client.get_common_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(option_flags) stream.pid(pid) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_COMMON_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) common_data = stream.extract(Ranking2CommonData) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("Ranking2Client.get_common_data -> done") return common_data async def put_common_data(self, data, unique_id): logger.info("Ranking2Client.put_common_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(data) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_PUT_COMMON_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("Ranking2Client.put_common_data -> done") async def delete_common_data(self, unique_id): logger.info("Ranking2Client.delete_common_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_COMMON_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("Ranking2Client.delete_common_data -> done") async def get_ranking(self, param): logger.info("Ranking2Client.get_ranking()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RANKING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(Ranking2Info) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("Ranking2Client.get_ranking -> done") return info async def get_ranking_by_principal_id(self, param, pids): logger.info("Ranking2Client.get_ranking_by_principal_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) stream.list(pids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RANKING_BY_PRINCIPAL_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(Ranking2Info) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("Ranking2Client.get_ranking_by_principal_id -> done") return info async def get_category_setting(self, category): logger.info("Ranking2Client.get_category_setting()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(category) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_CATEGORY_SETTING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) setting = stream.extract(Ranking2CategorySetting) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("Ranking2Client.get_category_setting -> done") return setting async def get_ranking_chart(self, input): logger.info("Ranking2Client.get_ranking_chart()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(input) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RANKING_CHART, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(Ranking2ChartInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("Ranking2Client.get_ranking_chart -> done") return info async def get_ranking_charts(self, inputs): logger.info("Ranking2Client.get_ranking_charts()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(inputs, stream.add) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RANKING_CHARTS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) infos = stream.list(Ranking2ChartInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("Ranking2Client.get_ranking_charts -> done") return infos async def get_estimate_score_rank(self, input): logger.info("Ranking2Client.get_estimate_score_rank()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(input) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_ESTIMATE_SCORE_RANK, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) output = stream.extract(Ranking2EstimateScoreRankOutput) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("Ranking2Client.get_estimate_score_rank -> done") return output async def get_estimate_my_score_rank(self, input): logger.info("Ranking2Client.get_estimate_my_score_rank()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(input) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_ESTIMATE_MY_SCORE_RANK, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) output = stream.extract(Ranking2EstimateScoreRankOutput) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("Ranking2Client.get_estimate_my_score_rank -> done") return output class Ranking2Server(Ranking2Protocol): def __init__(self): self.methods = { self.METHOD_PUT_SCORE: self.handle_put_score, self.METHOD_GET_COMMON_DATA: self.handle_get_common_data, self.METHOD_PUT_COMMON_DATA: self.handle_put_common_data, self.METHOD_DELETE_COMMON_DATA: self.handle_delete_common_data, self.METHOD_GET_RANKING: self.handle_get_ranking, self.METHOD_GET_RANKING_BY_PRINCIPAL_ID: self.handle_get_ranking_by_principal_id, self.METHOD_GET_CATEGORY_SETTING: self.handle_get_category_setting, self.METHOD_GET_RANKING_CHART: self.handle_get_ranking_chart, self.METHOD_GET_RANKING_CHARTS: self.handle_get_ranking_charts, self.METHOD_GET_ESTIMATE_SCORE_RANK: self.handle_get_estimate_score_rank, self.METHOD_GET_ESTIMATE_MY_SCORE_RANK: self.handle_get_estimate_my_score_rank, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on Ranking2Server: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_put_score(self, client, input, output): logger.info("Ranking2Server.put_score()") #--- request --- socres = input.list(Ranking2ScoreData) unique_id = input.u64() await self.put_score(client, socres, unique_id) async def handle_get_common_data(self, client, input, output): logger.info("Ranking2Server.get_common_data()") #--- request --- option_flags = input.u32() pid = input.pid() unique_id = input.u64() response = await self.get_common_data(client, option_flags, pid, unique_id) #--- response --- if not isinstance(response, Ranking2CommonData): raise RuntimeError("Expected Ranking2CommonData, got %s" %response.__class__.__name__) output.add(response) async def handle_put_common_data(self, client, input, output): logger.info("Ranking2Server.put_common_data()") #--- request --- data = input.extract(Ranking2CommonData) unique_id = input.u64() await self.put_common_data(client, data, unique_id) async def handle_delete_common_data(self, client, input, output): logger.info("Ranking2Server.delete_common_data()") #--- request --- unique_id = input.u64() await self.delete_common_data(client, unique_id) async def handle_get_ranking(self, client, input, output): logger.info("Ranking2Server.get_ranking()") #--- request --- param = input.extract(Ranking2GetParam) response = await self.get_ranking(client, param) #--- response --- if not isinstance(response, Ranking2Info): raise RuntimeError("Expected Ranking2Info, got %s" %response.__class__.__name__) output.add(response) async def handle_get_ranking_by_principal_id(self, client, input, output): logger.info("Ranking2Server.get_ranking_by_principal_id()") #--- request --- param = input.extract(Ranking2GetByListParam) pids = input.list(input.pid) response = await self.get_ranking_by_principal_id(client, param, pids) #--- response --- if not isinstance(response, Ranking2Info): raise RuntimeError("Expected Ranking2Info, got %s" %response.__class__.__name__) output.add(response) async def handle_get_category_setting(self, client, input, output): logger.info("Ranking2Server.get_category_setting()") #--- request --- category = input.u32() response = await self.get_category_setting(client, category) #--- response --- if not isinstance(response, Ranking2CategorySetting): raise RuntimeError("Expected Ranking2CategorySetting, got %s" %response.__class__.__name__) output.add(response) async def handle_get_ranking_chart(self, client, input, output): logger.info("Ranking2Server.get_ranking_chart()") #--- request --- input = input.extract(Ranking2ChartInfoInput) response = await self.get_ranking_chart(client, input) #--- response --- if not isinstance(response, Ranking2ChartInfo): raise RuntimeError("Expected Ranking2ChartInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_ranking_charts(self, client, input, output): logger.info("Ranking2Server.get_ranking_charts()") #--- request --- inputs = input.list(Ranking2ChartInfoInput) response = await self.get_ranking_charts(client, inputs) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_estimate_score_rank(self, client, input, output): logger.info("Ranking2Server.get_estimate_score_rank()") #--- request --- input = input.extract(Ranking2EstimateScoreRankInput) response = await self.get_estimate_score_rank(client, input) #--- response --- if not isinstance(response, Ranking2EstimateScoreRankOutput): raise RuntimeError("Expected Ranking2EstimateScoreRankOutput, got %s" %response.__class__.__name__) output.add(response) async def handle_get_estimate_my_score_rank(self, client, input, output): logger.info("Ranking2Server.get_estimate_my_score_rank()") #--- request --- input = input.extract(Ranking2EstimateMyScoreRankInput) response = await self.get_estimate_my_score_rank(client, input) #--- response --- if not isinstance(response, Ranking2EstimateScoreRankOutput): raise RuntimeError("Expected Ranking2EstimateScoreRankOutput, got %s" %response.__class__.__name__) output.add(response) async def put_score(self, *args): logger.warning("Ranking2Server.put_score not implemented") raise common.RMCError("Core::NotImplemented") async def get_common_data(self, *args): logger.warning("Ranking2Server.get_common_data not implemented") raise common.RMCError("Core::NotImplemented") async def put_common_data(self, *args): logger.warning("Ranking2Server.put_common_data not implemented") raise common.RMCError("Core::NotImplemented") async def delete_common_data(self, *args): logger.warning("Ranking2Server.delete_common_data not implemented") raise common.RMCError("Core::NotImplemented") async def get_ranking(self, *args): logger.warning("Ranking2Server.get_ranking not implemented") raise common.RMCError("Core::NotImplemented") async def get_ranking_by_principal_id(self, *args): logger.warning("Ranking2Server.get_ranking_by_principal_id not implemented") raise common.RMCError("Core::NotImplemented") async def get_category_setting(self, *args): logger.warning("Ranking2Server.get_category_setting not implemented") raise common.RMCError("Core::NotImplemented") async def get_ranking_chart(self, *args): logger.warning("Ranking2Server.get_ranking_chart not implemented") raise common.RMCError("Core::NotImplemented") async def get_ranking_charts(self, *args): logger.warning("Ranking2Server.get_ranking_charts not implemented") raise common.RMCError("Core::NotImplemented") async def get_estimate_score_rank(self, *args): logger.warning("Ranking2Server.get_estimate_score_rank not implemented") raise common.RMCError("Core::NotImplemented") async def get_estimate_my_score_rank(self, *args): logger.warning("Ranking2Server.get_estimate_my_score_rank not implemented") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/ranking_mk8.py ================================================ # This file was generated automatically by generate_protocols.py from nintendo.nex import notification, rmc, common, streams import logging logger = logging.getLogger(__name__) class RankingOrderCalc: STANDARD = 0 ORDINAL = 1 class RankingMode: GLOBAL = 0 GLOBAL_AROUND_SELF = 1 SELF = 4 class RankingStatFlags: RANKING_COUNT = 1 TOTAL_SCORE = 2 LOWEST_SCORE = 4 HIGHEST_SCORE = 8 AVERAGE_SCORE = 16 ALL = 31 class RankingOrderParam(common.Structure): def __init__(self): super().__init__() self.order_calc = 0 self.group_index = 255 self.group_num = 0 self.time_scope = 2 self.offset = 0 self.count = 10 def check_required(self, settings, version): pass def load(self, stream, version): self.order_calc = stream.u8() self.group_index = stream.u8() self.group_num = stream.u8() self.time_scope = stream.u8() self.offset = stream.u32() self.count = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.order_calc) stream.u8(self.group_index) stream.u8(self.group_num) stream.u8(self.time_scope) stream.u32(self.offset) stream.u8(self.count) class RankingRankData(common.Structure): def __init__(self): super().__init__() self.pid = None self.unique_id = None self.rank = None self.category = None self.score = None self.groups = None self.param = None self.common_data = None self.update_time = None def check_required(self, settings, version): for field in ['pid', 'unique_id', 'rank', 'category', 'score', 'groups', 'param', 'common_data']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) if settings["nex.version"] >= 40000: for field in ['update_time']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.unique_id = stream.u64() self.rank = stream.u32() self.category = stream.u32() self.score = stream.u32() self.groups = stream.list(stream.u8) self.param = stream.u64() self.common_data = stream.buffer() if stream.settings["nex.version"] >= 40000: self.update_time = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.u64(self.unique_id) stream.u32(self.rank) stream.u32(self.category) stream.u32(self.score) stream.list(self.groups, stream.u8) stream.u64(self.param) stream.buffer(self.common_data) if stream.settings["nex.version"] >= 40000: stream.datetime(self.update_time) class RankingResult(common.Structure): def __init__(self): super().__init__() self.data = None self.total = None self.since_time = None def check_required(self, settings, version): for field in ['data', 'total', 'since_time']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data = stream.list(RankingRankData) self.total = stream.u32() self.since_time = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.data, stream.add) stream.u32(self.total) stream.datetime(self.since_time) class RankingCachedResult(RankingResult): def __init__(self): super().__init__() self.created_time = None self.expired_time = None self.max_length = None def check_required(self, settings, version): for field in ['created_time', 'expired_time', 'max_length']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.created_time = stream.datetime() self.expired_time = stream.datetime() self.max_length = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.datetime(self.created_time) stream.datetime(self.expired_time) stream.u8(self.max_length) common.DataHolder.register(RankingCachedResult, "RankingCachedResult") class RankingStats(common.Structure): def __init__(self): super().__init__() self.stats = None def check_required(self, settings, version): for field in ['stats']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.stats = stream.list(stream.double) def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.stats, stream.double) class RankingScoreData(common.Structure): def __init__(self): super().__init__() self.category = None self.score = None self.order = None self.update_mode = None self.groups = None self.param = None def check_required(self, settings, version): for field in ['category', 'score', 'order', 'update_mode', 'groups', 'param']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.category = stream.u32() self.score = stream.u32() self.order = stream.u8() self.update_mode = stream.u8() self.groups = stream.list(stream.u8) self.param = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.category) stream.u32(self.score) stream.u8(self.order) stream.u8(self.update_mode) stream.list(self.groups, stream.u8) stream.u64(self.param) class RankingChangeAttributesParam(common.Structure): def __init__(self): super().__init__() self.flags = None self.groups = None self.param = None def check_required(self, settings, version): for field in ['flags', 'groups', 'param']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.flags = stream.u8() self.groups = stream.list(stream.u8) self.param = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.flags) stream.list(self.groups, stream.u8) stream.u64(self.param) class CompetitionRankingInfo(common.Structure): def __init__(self): super().__init__() self.id = None self.num_participants = None self.team_scores = None def check_required(self, settings, version): for field in ['id', 'num_participants', 'team_scores']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.id = stream.u32() self.num_participants = stream.u32() self.team_scores = stream.list(stream.u32) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.id) stream.u32(self.num_participants) stream.list(self.team_scores, stream.u32) class CompetitionRankingInfoGetParam(common.Structure): def __init__(self): super().__init__() self.rank_order = None self.range = common.ResultRange() def check_required(self, settings, version): for field in ['rank_order']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.rank_order = stream.u8() self.range = stream.extract(common.ResultRange) def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.rank_order) stream.add(self.range) class CompetitionRankingUploadScoreParam(common.Structure): def __init__(self): super().__init__() self.id = None self.season_id = None self.unk3 = None self.score = None self.team_id = None self.team_score = None self.is_first_upload = None self.metadata = None def check_required(self, settings, version): for field in ['id', 'season_id', 'unk3', 'score', 'team_id', 'team_score', 'is_first_upload', 'metadata']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.id = stream.u32() self.season_id = stream.u32() self.unk3 = stream.u32() self.score = stream.u32() self.team_id = stream.u8() self.team_score = stream.u32() self.is_first_upload = stream.bool() self.metadata = stream.qbuffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.id) stream.u32(self.season_id) stream.u32(self.unk3) stream.u32(self.score) stream.u8(self.team_id) stream.u32(self.team_score) stream.bool(self.is_first_upload) stream.qbuffer(self.metadata) class RankingProtocolMK8: METHOD_UPLOAD_SCORE = 1 METHOD_DELETE_SCORE = 2 METHOD_DELETE_ALL_SCORES = 3 METHOD_UPLOAD_COMMON_DATA = 4 METHOD_DELETE_COMMON_DATA = 5 METHOD_GET_COMMON_DATA = 6 METHOD_CHANGE_ATTRIBUTES = 7 METHOD_CHANGE_ALL_ATTRIBUTES = 8 METHOD_GET_RANKING = 9 METHOD_GET_APPROX_ORDER = 10 METHOD_GET_STATS = 11 METHOD_GET_RANKING_BY_PID_LIST = 12 METHOD_GET_RANKING_BY_UNIQUE_ID_LIST = 13 METHOD_GET_COMPETITION_RANKING_SCORE = 14 METHOD_UPLOAD_COMPETITION_RANKING_SCORE = 15 METHOD_GET_COMPETITION_INFO = 16 PROTOCOL_ID = 0x70 class RankingClientMK8(RankingProtocolMK8): def __init__(self, client): self.settings = client.settings self.client = client async def upload_score(self, score_data, unique_id): logger.info("RankingClientMK8.upload_score()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(score_data) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPLOAD_SCORE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8.upload_score -> done") async def delete_score(self, category, unique_id): logger.info("RankingClientMK8.delete_score()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(category) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_SCORE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8.delete_score -> done") async def delete_all_scores(self, unique_id): logger.info("RankingClientMK8.delete_all_scores()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_ALL_SCORES, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8.delete_all_scores -> done") async def upload_common_data(self, common_data, unique_id): logger.info("RankingClientMK8.upload_common_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.buffer(common_data) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPLOAD_COMMON_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8.upload_common_data -> done") async def delete_common_data(self, unique_id): logger.info("RankingClientMK8.delete_common_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_COMMON_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8.delete_common_data -> done") async def get_common_data(self, unique_id): logger.info("RankingClientMK8.get_common_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_COMMON_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) data = stream.buffer() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8.get_common_data -> done") return data async def change_attributes(self, category, param, unique_id): logger.info("RankingClientMK8.change_attributes()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(category) stream.add(param) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CHANGE_ATTRIBUTES, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8.change_attributes -> done") async def change_all_attributes(self, param, unique_id): logger.info("RankingClientMK8.change_all_attributes()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CHANGE_ALL_ATTRIBUTES, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8.change_all_attributes -> done") async def get_ranking(self, mode, category, order, unique_id, pid): logger.info("RankingClientMK8.get_ranking()") #--- request --- stream = streams.StreamOut(self.settings) stream.u8(mode) stream.u32(category) stream.add(order) stream.u64(unique_id) stream.pid(pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RANKING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.extract(RankingResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8.get_ranking -> done") return result async def get_approx_order(self, category, order, score, unique_id, pid): logger.info("RankingClientMK8.get_approx_order()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(category) stream.add(order) stream.u32(score) stream.u64(unique_id) stream.pid(pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_APPROX_ORDER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) order = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8.get_approx_order -> done") return order async def get_stats(self, category, order, flags): logger.info("RankingClientMK8.get_stats()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(category) stream.add(order) stream.u32(flags) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) stats = stream.extract(RankingStats) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8.get_stats -> done") return stats async def get_ranking_by_pid_list(self, pids, mode, category, order, unique_id): logger.info("RankingClientMK8.get_ranking_by_pid_list()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) stream.u8(mode) stream.u32(category) stream.add(order) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RANKING_BY_PID_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.extract(RankingResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8.get_ranking_by_pid_list -> done") return result async def get_ranking_by_unique_id_list(self, ids, mode, category, order, unique_id): logger.info("RankingClientMK8.get_ranking_by_unique_id_list()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(ids, stream.u64) stream.u8(mode) stream.u32(category) stream.add(order) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RANKING_BY_UNIQUE_ID_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.extract(RankingResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8.get_ranking_by_unique_id_list -> done") return result async def upload_competition_ranking_score(self, param): logger.info("RankingClientMK8.upload_competition_ranking_score()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPLOAD_COMPETITION_RANKING_SCORE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8.upload_competition_ranking_score -> done") return result async def get_competition_info(self, param): logger.info("RankingClientMK8.get_competition_info()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_COMPETITION_INFO, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.list(CompetitionRankingInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8.get_competition_info -> done") return info class RankingServerMK8(RankingProtocolMK8): def __init__(self): self.methods = { self.METHOD_UPLOAD_SCORE: self.handle_upload_score, self.METHOD_DELETE_SCORE: self.handle_delete_score, self.METHOD_DELETE_ALL_SCORES: self.handle_delete_all_scores, self.METHOD_UPLOAD_COMMON_DATA: self.handle_upload_common_data, self.METHOD_DELETE_COMMON_DATA: self.handle_delete_common_data, self.METHOD_GET_COMMON_DATA: self.handle_get_common_data, self.METHOD_CHANGE_ATTRIBUTES: self.handle_change_attributes, self.METHOD_CHANGE_ALL_ATTRIBUTES: self.handle_change_all_attributes, self.METHOD_GET_RANKING: self.handle_get_ranking, self.METHOD_GET_APPROX_ORDER: self.handle_get_approx_order, self.METHOD_GET_STATS: self.handle_get_stats, self.METHOD_GET_RANKING_BY_PID_LIST: self.handle_get_ranking_by_pid_list, self.METHOD_GET_RANKING_BY_UNIQUE_ID_LIST: self.handle_get_ranking_by_unique_id_list, self.METHOD_GET_COMPETITION_RANKING_SCORE: self.handle_get_competition_ranking_score, self.METHOD_UPLOAD_COMPETITION_RANKING_SCORE: self.handle_upload_competition_ranking_score, self.METHOD_GET_COMPETITION_INFO: self.handle_get_competition_info, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on RankingServerMK8: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_upload_score(self, client, input, output): logger.info("RankingServerMK8.upload_score()") #--- request --- score_data = input.extract(RankingScoreData) unique_id = input.u64() await self.upload_score(client, score_data, unique_id) async def handle_delete_score(self, client, input, output): logger.info("RankingServerMK8.delete_score()") #--- request --- category = input.u32() unique_id = input.u64() await self.delete_score(client, category, unique_id) async def handle_delete_all_scores(self, client, input, output): logger.info("RankingServerMK8.delete_all_scores()") #--- request --- unique_id = input.u64() await self.delete_all_scores(client, unique_id) async def handle_upload_common_data(self, client, input, output): logger.info("RankingServerMK8.upload_common_data()") #--- request --- common_data = input.buffer() unique_id = input.u64() await self.upload_common_data(client, common_data, unique_id) async def handle_delete_common_data(self, client, input, output): logger.info("RankingServerMK8.delete_common_data()") #--- request --- unique_id = input.u64() await self.delete_common_data(client, unique_id) async def handle_get_common_data(self, client, input, output): logger.info("RankingServerMK8.get_common_data()") #--- request --- unique_id = input.u64() response = await self.get_common_data(client, unique_id) #--- response --- if not isinstance(response, bytes): raise RuntimeError("Expected bytes, got %s" %response.__class__.__name__) output.buffer(response) async def handle_change_attributes(self, client, input, output): logger.info("RankingServerMK8.change_attributes()") #--- request --- category = input.u32() param = input.extract(RankingChangeAttributesParam) unique_id = input.u64() await self.change_attributes(client, category, param, unique_id) async def handle_change_all_attributes(self, client, input, output): logger.info("RankingServerMK8.change_all_attributes()") #--- request --- param = input.extract(RankingChangeAttributesParam) unique_id = input.u64() await self.change_all_attributes(client, param, unique_id) async def handle_get_ranking(self, client, input, output): logger.info("RankingServerMK8.get_ranking()") #--- request --- mode = input.u8() category = input.u32() order = input.extract(RankingOrderParam) unique_id = input.u64() pid = input.pid() response = await self.get_ranking(client, mode, category, order, unique_id, pid) #--- response --- if not isinstance(response, RankingResult): raise RuntimeError("Expected RankingResult, got %s" %response.__class__.__name__) output.add(response) async def handle_get_approx_order(self, client, input, output): logger.info("RankingServerMK8.get_approx_order()") #--- request --- category = input.u32() order = input.extract(RankingOrderParam) score = input.u32() unique_id = input.u64() pid = input.pid() response = await self.get_approx_order(client, category, order, score, unique_id, pid) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u32(response) async def handle_get_stats(self, client, input, output): logger.info("RankingServerMK8.get_stats()") #--- request --- category = input.u32() order = input.extract(RankingOrderParam) flags = input.u32() response = await self.get_stats(client, category, order, flags) #--- response --- if not isinstance(response, RankingStats): raise RuntimeError("Expected RankingStats, got %s" %response.__class__.__name__) output.add(response) async def handle_get_ranking_by_pid_list(self, client, input, output): logger.info("RankingServerMK8.get_ranking_by_pid_list()") #--- request --- pids = input.list(input.pid) mode = input.u8() category = input.u32() order = input.extract(RankingOrderParam) unique_id = input.u64() response = await self.get_ranking_by_pid_list(client, pids, mode, category, order, unique_id) #--- response --- if not isinstance(response, RankingResult): raise RuntimeError("Expected RankingResult, got %s" %response.__class__.__name__) output.add(response) async def handle_get_ranking_by_unique_id_list(self, client, input, output): logger.info("RankingServerMK8.get_ranking_by_unique_id_list()") #--- request --- ids = input.list(input.u64) mode = input.u8() category = input.u32() order = input.extract(RankingOrderParam) unique_id = input.u64() response = await self.get_ranking_by_unique_id_list(client, ids, mode, category, order, unique_id) #--- response --- if not isinstance(response, RankingResult): raise RuntimeError("Expected RankingResult, got %s" %response.__class__.__name__) output.add(response) async def handle_get_competition_ranking_score(self, client, input, output): logger.warning("RankingServerMK8.get_competition_ranking_score is not supported") raise common.RMCError("Core::NotImplemented") async def handle_upload_competition_ranking_score(self, client, input, output): logger.info("RankingServerMK8.upload_competition_ranking_score()") #--- request --- param = input.extract(CompetitionRankingUploadScoreParam) response = await self.upload_competition_ranking_score(client, param) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_competition_info(self, client, input, output): logger.info("RankingServerMK8.get_competition_info()") #--- request --- param = input.extract(CompetitionRankingInfoGetParam) response = await self.get_competition_info(client, param) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def upload_score(self, *args): logger.warning("RankingServerMK8.upload_score not implemented") raise common.RMCError("Core::NotImplemented") async def delete_score(self, *args): logger.warning("RankingServerMK8.delete_score not implemented") raise common.RMCError("Core::NotImplemented") async def delete_all_scores(self, *args): logger.warning("RankingServerMK8.delete_all_scores not implemented") raise common.RMCError("Core::NotImplemented") async def upload_common_data(self, *args): logger.warning("RankingServerMK8.upload_common_data not implemented") raise common.RMCError("Core::NotImplemented") async def delete_common_data(self, *args): logger.warning("RankingServerMK8.delete_common_data not implemented") raise common.RMCError("Core::NotImplemented") async def get_common_data(self, *args): logger.warning("RankingServerMK8.get_common_data not implemented") raise common.RMCError("Core::NotImplemented") async def change_attributes(self, *args): logger.warning("RankingServerMK8.change_attributes not implemented") raise common.RMCError("Core::NotImplemented") async def change_all_attributes(self, *args): logger.warning("RankingServerMK8.change_all_attributes not implemented") raise common.RMCError("Core::NotImplemented") async def get_ranking(self, *args): logger.warning("RankingServerMK8.get_ranking not implemented") raise common.RMCError("Core::NotImplemented") async def get_approx_order(self, *args): logger.warning("RankingServerMK8.get_approx_order not implemented") raise common.RMCError("Core::NotImplemented") async def get_stats(self, *args): logger.warning("RankingServerMK8.get_stats not implemented") raise common.RMCError("Core::NotImplemented") async def get_ranking_by_pid_list(self, *args): logger.warning("RankingServerMK8.get_ranking_by_pid_list not implemented") raise common.RMCError("Core::NotImplemented") async def get_ranking_by_unique_id_list(self, *args): logger.warning("RankingServerMK8.get_ranking_by_unique_id_list not implemented") raise common.RMCError("Core::NotImplemented") async def upload_competition_ranking_score(self, *args): logger.warning("RankingServerMK8.upload_competition_ranking_score not implemented") raise common.RMCError("Core::NotImplemented") async def get_competition_info(self, *args): logger.warning("RankingServerMK8.get_competition_info not implemented") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/ranking_mk8d.py ================================================ # This file was generated automatically by generate_protocols.py from nintendo.nex import notification, rmc, common, streams import logging logger = logging.getLogger(__name__) class RankingOrderCalc: STANDARD = 0 ORDINAL = 1 class RankingMode: GLOBAL = 0 GLOBAL_AROUND_SELF = 1 SELF = 4 class RankingStatFlags: RANKING_COUNT = 1 TOTAL_SCORE = 2 LOWEST_SCORE = 4 HIGHEST_SCORE = 8 AVERAGE_SCORE = 16 ALL = 31 class RankingOrderParam(common.Structure): def __init__(self): super().__init__() self.order_calc = 0 self.group_index = 255 self.group_num = 0 self.time_scope = 2 self.offset = 0 self.count = 10 def check_required(self, settings, version): pass def load(self, stream, version): self.order_calc = stream.u8() self.group_index = stream.u8() self.group_num = stream.u8() self.time_scope = stream.u8() self.offset = stream.u32() self.count = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.order_calc) stream.u8(self.group_index) stream.u8(self.group_num) stream.u8(self.time_scope) stream.u32(self.offset) stream.u8(self.count) class RankingRankData(common.Structure): def __init__(self): super().__init__() self.pid = None self.unique_id = None self.rank = None self.category = None self.score = None self.groups = None self.param = None self.common_data = None self.update_time = None def check_required(self, settings, version): for field in ['pid', 'unique_id', 'rank', 'category', 'score', 'groups', 'param', 'common_data']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) if settings["nex.version"] >= 40000: for field in ['update_time']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.pid = stream.pid() self.unique_id = stream.u64() self.rank = stream.u32() self.category = stream.u32() self.score = stream.u32() self.groups = stream.list(stream.u8) self.param = stream.u64() self.common_data = stream.buffer() if stream.settings["nex.version"] >= 40000: self.update_time = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.pid(self.pid) stream.u64(self.unique_id) stream.u32(self.rank) stream.u32(self.category) stream.u32(self.score) stream.list(self.groups, stream.u8) stream.u64(self.param) stream.buffer(self.common_data) if stream.settings["nex.version"] >= 40000: stream.datetime(self.update_time) class RankingResult(common.Structure): def __init__(self): super().__init__() self.data = None self.total = None self.since_time = None def check_required(self, settings, version): for field in ['data', 'total', 'since_time']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data = stream.list(RankingRankData) self.total = stream.u32() self.since_time = stream.datetime() def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.data, stream.add) stream.u32(self.total) stream.datetime(self.since_time) class RankingCachedResult(RankingResult): def __init__(self): super().__init__() self.created_time = None self.expired_time = None self.max_length = None def check_required(self, settings, version): for field in ['created_time', 'expired_time', 'max_length']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.created_time = stream.datetime() self.expired_time = stream.datetime() self.max_length = stream.u8() def save(self, stream, version): self.check_required(stream.settings, version) stream.datetime(self.created_time) stream.datetime(self.expired_time) stream.u8(self.max_length) common.DataHolder.register(RankingCachedResult, "RankingCachedResult") class RankingStats(common.Structure): def __init__(self): super().__init__() self.stats = None def check_required(self, settings, version): for field in ['stats']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.stats = stream.list(stream.double) def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.stats, stream.double) class RankingScoreData(common.Structure): def __init__(self): super().__init__() self.category = None self.score = None self.order = None self.update_mode = None self.groups = None self.param = None def check_required(self, settings, version): for field in ['category', 'score', 'order', 'update_mode', 'groups', 'param']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.category = stream.u32() self.score = stream.u32() self.order = stream.u8() self.update_mode = stream.u8() self.groups = stream.list(stream.u8) self.param = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.category) stream.u32(self.score) stream.u8(self.order) stream.u8(self.update_mode) stream.list(self.groups, stream.u8) stream.u64(self.param) class RankingChangeAttributesParam(common.Structure): def __init__(self): super().__init__() self.flags = None self.groups = None self.param = None def check_required(self, settings, version): for field in ['flags', 'groups', 'param']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.flags = stream.u8() self.groups = stream.list(stream.u8) self.param = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.flags) stream.list(self.groups, stream.u8) stream.u64(self.param) class CommonDataList(common.Structure): def __init__(self): super().__init__() self.data = None def check_required(self, settings, version): for field in ['data']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data = stream.list(stream.qbuffer) def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.data, stream.qbuffer) class CompetitionRankingGetScoreParam(common.Structure): def __init__(self): super().__init__() self.id = None self.range = common.ResultRange() def check_required(self, settings, version): for field in ['id']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.id = stream.u32() self.range = stream.extract(common.ResultRange) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.id) stream.add(self.range) class CompetitionRankingInfo(common.Structure): def __init__(self): super().__init__() self.id = None self.num_participants = None self.team_scores = None def check_required(self, settings, version): for field in ['id', 'num_participants', 'team_scores']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.id = stream.u32() self.num_participants = stream.u32() self.team_scores = stream.list(stream.u32) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.id) stream.u32(self.num_participants) stream.list(self.team_scores, stream.u32) class CompetitionRankingInfoGetParam(common.Structure): def __init__(self): super().__init__() self.rank_order = None self.range = common.ResultRange() def check_required(self, settings, version): for field in ['rank_order']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.rank_order = stream.u8() self.range = stream.extract(common.ResultRange) def save(self, stream, version): self.check_required(stream.settings, version) stream.u8(self.rank_order) stream.add(self.range) class CompetitionRankingScoreData(common.Structure): def __init__(self): super().__init__() self.rank = None self.pid = None self.score = None self.last_update = None self.team_id = 255 self.metadata = None def check_required(self, settings, version): for field in ['rank', 'pid', 'score', 'last_update', 'metadata']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.rank = stream.u32() self.pid = stream.pid() self.score = stream.u32() self.last_update = stream.datetime() self.team_id = stream.u8() self.metadata = stream.qbuffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.rank) stream.pid(self.pid) stream.u32(self.score) stream.datetime(self.last_update) stream.u8(self.team_id) stream.qbuffer(self.metadata) class CompetitionRankingScoreInfo(common.Structure): def __init__(self): super().__init__() self.season_id = None self.scores = None self.num_participants = None self.team_scores = None def check_required(self, settings, version): for field in ['season_id', 'scores', 'num_participants', 'team_scores']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.season_id = stream.u32() self.scores = stream.list(CompetitionRankingScoreData) self.num_participants = stream.u32() self.team_scores = stream.list(stream.u32) def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.season_id) stream.list(self.scores, stream.add) stream.u32(self.num_participants) stream.list(self.team_scores, stream.u32) class CompetitionRankingUploadScoreParam(common.Structure): def __init__(self): super().__init__() self.id = None self.season_id = None self.unk3 = None self.score = None self.team_id = None self.team_score = None self.is_first_upload = None self.metadata = None def check_required(self, settings, version): for field in ['id', 'season_id', 'unk3', 'score', 'team_id', 'team_score', 'is_first_upload', 'metadata']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.id = stream.u32() self.season_id = stream.u32() self.unk3 = stream.u32() self.score = stream.u32() self.team_id = stream.u8() self.team_score = stream.u32() self.is_first_upload = stream.bool() self.metadata = stream.qbuffer() def save(self, stream, version): self.check_required(stream.settings, version) stream.u32(self.id) stream.u32(self.season_id) stream.u32(self.unk3) stream.u32(self.score) stream.u8(self.team_id) stream.u32(self.team_score) stream.bool(self.is_first_upload) stream.qbuffer(self.metadata) class ScorePack(common.Structure): def __init__(self): super().__init__() self.data = None def check_required(self, settings, version): for field in ['data']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.data = stream.list(stream.qbuffer) def save(self, stream, version): self.check_required(stream.settings, version) stream.list(self.data, stream.qbuffer) class RankingProtocolMK8D: METHOD_UPLOAD_SCORE = 1 METHOD_DELETE_SCORE = 2 METHOD_DELETE_ALL_SCORES = 3 METHOD_UPLOAD_COMMON_DATA = 4 METHOD_DELETE_COMMON_DATA = 5 METHOD_GET_COMMON_DATA = 6 METHOD_CHANGE_ATTRIBUTES = 7 METHOD_CHANGE_ALL_ATTRIBUTES = 8 METHOD_GET_RANKING = 9 METHOD_GET_APPROX_ORDER = 10 METHOD_GET_STATS = 11 METHOD_GET_RANKING_BY_PID_LIST = 12 METHOD_GET_RANKING_BY_UNIQUE_ID_LIST = 13 METHOD_GET_CACHED_TOPX_RANKING = 14 METHOD_GET_CACHED_TOPX_RANKINGS = 15 METHOD_GET_COMPETITION_RANKING_SCORE = 16 METHOD_UPLOAD_COMPETITION_RANKING_SCORE = 17 METHOD_GET_COMPETITION_INFO = 18 METHOD_UPLOAD_SCORE_PACK = 19 METHOD_GET_SCORE_PACK = 20 METHOD_EXECUTE_DELETE_SCORE_JOB = 21 METHOD_GET_COMMMON_DATA_BY_PID_LIST = 22 PROTOCOL_ID = 0x70 class RankingClientMK8D(RankingProtocolMK8D): def __init__(self, client): self.settings = client.settings self.client = client async def upload_score(self, score_data, unique_id): logger.info("RankingClientMK8D.upload_score()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(score_data) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPLOAD_SCORE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8D.upload_score -> done") async def delete_score(self, category, unique_id): logger.info("RankingClientMK8D.delete_score()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(category) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_SCORE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8D.delete_score -> done") async def delete_all_scores(self, unique_id): logger.info("RankingClientMK8D.delete_all_scores()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_ALL_SCORES, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8D.delete_all_scores -> done") async def upload_common_data(self, common_data, unique_id): logger.info("RankingClientMK8D.upload_common_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.buffer(common_data) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPLOAD_COMMON_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8D.upload_common_data -> done") async def delete_common_data(self, unique_id): logger.info("RankingClientMK8D.delete_common_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_DELETE_COMMON_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8D.delete_common_data -> done") async def get_common_data(self, unique_id): logger.info("RankingClientMK8D.get_common_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_COMMON_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) data = stream.buffer() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8D.get_common_data -> done") return data async def change_attributes(self, category, param, unique_id): logger.info("RankingClientMK8D.change_attributes()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(category) stream.add(param) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CHANGE_ATTRIBUTES, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8D.change_attributes -> done") async def change_all_attributes(self, param, unique_id): logger.info("RankingClientMK8D.change_all_attributes()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_CHANGE_ALL_ATTRIBUTES, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8D.change_all_attributes -> done") async def get_ranking(self, mode, category, order, unique_id, pid): logger.info("RankingClientMK8D.get_ranking()") #--- request --- stream = streams.StreamOut(self.settings) stream.u8(mode) stream.u32(category) stream.add(order) stream.u64(unique_id) stream.pid(pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RANKING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.extract(RankingResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8D.get_ranking -> done") return result async def get_approx_order(self, category, order, score, unique_id, pid): logger.info("RankingClientMK8D.get_approx_order()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(category) stream.add(order) stream.u32(score) stream.u64(unique_id) stream.pid(pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_APPROX_ORDER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) order = stream.u32() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8D.get_approx_order -> done") return order async def get_stats(self, category, order, flags): logger.info("RankingClientMK8D.get_stats()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(category) stream.add(order) stream.u32(flags) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STATS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) stats = stream.extract(RankingStats) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8D.get_stats -> done") return stats async def get_ranking_by_pid_list(self, pids, mode, category, order, unique_id): logger.info("RankingClientMK8D.get_ranking_by_pid_list()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) stream.u8(mode) stream.u32(category) stream.add(order) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RANKING_BY_PID_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.extract(RankingResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8D.get_ranking_by_pid_list -> done") return result async def get_ranking_by_unique_id_list(self, ids, mode, category, order, unique_id): logger.info("RankingClientMK8D.get_ranking_by_unique_id_list()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(ids, stream.u64) stream.u8(mode) stream.u32(category) stream.add(order) stream.u64(unique_id) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_RANKING_BY_UNIQUE_ID_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.extract(RankingResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8D.get_ranking_by_unique_id_list -> done") return result async def get_cached_topx_ranking(self, category, order): logger.info("RankingClientMK8D.get_cached_topx_ranking()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(category) stream.add(order) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_CACHED_TOPX_RANKING, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.extract(RankingCachedResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8D.get_cached_topx_ranking -> done") return result async def get_cached_topx_rankings(self, categories, order): logger.info("RankingClientMK8D.get_cached_topx_rankings()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(categories, stream.u32) stream.list(order, stream.add) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_CACHED_TOPX_RANKINGS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) results = stream.list(RankingCachedResult) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8D.get_cached_topx_rankings -> done") return results async def get_competition_ranking_score(self, param): logger.info("RankingClientMK8D.get_competition_ranking_score()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_COMPETITION_RANKING_SCORE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.list(CompetitionRankingScoreInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8D.get_competition_ranking_score -> done") return info async def upload_competition_ranking_score(self, param): logger.info("RankingClientMK8D.upload_competition_ranking_score()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPLOAD_COMPETITION_RANKING_SCORE, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.bool() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8D.upload_competition_ranking_score -> done") return result async def get_competition_info(self, param): logger.info("RankingClientMK8D.get_competition_info()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(param) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_COMPETITION_INFO, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.list(CompetitionRankingInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8D.get_competition_info -> done") return info async def upload_score_pack(self, score_data, metadata): logger.info("RankingClientMK8D.upload_score_pack()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(score_data) stream.qbuffer(metadata) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPLOAD_SCORE_PACK, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8D.upload_score_pack -> done") async def get_score_pack(self, pids, category): logger.info("RankingClientMK8D.get_score_pack()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) stream.u32(category) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_SCORE_PACK, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) result = stream.extract(ScorePack) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8D.get_score_pack -> done") return result async def get_commmon_data_by_pid_list(self, pids): logger.info("RankingClientMK8D.get_commmon_data_by_pid_list()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(pids, stream.pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_COMMMON_DATA_BY_PID_LIST, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) list = stream.extract(CommonDataList) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RankingClientMK8D.get_commmon_data_by_pid_list -> done") return list class RankingServerMK8D(RankingProtocolMK8D): def __init__(self): self.methods = { self.METHOD_UPLOAD_SCORE: self.handle_upload_score, self.METHOD_DELETE_SCORE: self.handle_delete_score, self.METHOD_DELETE_ALL_SCORES: self.handle_delete_all_scores, self.METHOD_UPLOAD_COMMON_DATA: self.handle_upload_common_data, self.METHOD_DELETE_COMMON_DATA: self.handle_delete_common_data, self.METHOD_GET_COMMON_DATA: self.handle_get_common_data, self.METHOD_CHANGE_ATTRIBUTES: self.handle_change_attributes, self.METHOD_CHANGE_ALL_ATTRIBUTES: self.handle_change_all_attributes, self.METHOD_GET_RANKING: self.handle_get_ranking, self.METHOD_GET_APPROX_ORDER: self.handle_get_approx_order, self.METHOD_GET_STATS: self.handle_get_stats, self.METHOD_GET_RANKING_BY_PID_LIST: self.handle_get_ranking_by_pid_list, self.METHOD_GET_RANKING_BY_UNIQUE_ID_LIST: self.handle_get_ranking_by_unique_id_list, self.METHOD_GET_CACHED_TOPX_RANKING: self.handle_get_cached_topx_ranking, self.METHOD_GET_CACHED_TOPX_RANKINGS: self.handle_get_cached_topx_rankings, self.METHOD_GET_COMPETITION_RANKING_SCORE: self.handle_get_competition_ranking_score, self.METHOD_UPLOAD_COMPETITION_RANKING_SCORE: self.handle_upload_competition_ranking_score, self.METHOD_GET_COMPETITION_INFO: self.handle_get_competition_info, self.METHOD_UPLOAD_SCORE_PACK: self.handle_upload_score_pack, self.METHOD_GET_SCORE_PACK: self.handle_get_score_pack, self.METHOD_EXECUTE_DELETE_SCORE_JOB: self.handle_execute_delete_score_job, self.METHOD_GET_COMMMON_DATA_BY_PID_LIST: self.handle_get_commmon_data_by_pid_list, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on RankingServerMK8D: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_upload_score(self, client, input, output): logger.info("RankingServerMK8D.upload_score()") #--- request --- score_data = input.extract(RankingScoreData) unique_id = input.u64() await self.upload_score(client, score_data, unique_id) async def handle_delete_score(self, client, input, output): logger.info("RankingServerMK8D.delete_score()") #--- request --- category = input.u32() unique_id = input.u64() await self.delete_score(client, category, unique_id) async def handle_delete_all_scores(self, client, input, output): logger.info("RankingServerMK8D.delete_all_scores()") #--- request --- unique_id = input.u64() await self.delete_all_scores(client, unique_id) async def handle_upload_common_data(self, client, input, output): logger.info("RankingServerMK8D.upload_common_data()") #--- request --- common_data = input.buffer() unique_id = input.u64() await self.upload_common_data(client, common_data, unique_id) async def handle_delete_common_data(self, client, input, output): logger.info("RankingServerMK8D.delete_common_data()") #--- request --- unique_id = input.u64() await self.delete_common_data(client, unique_id) async def handle_get_common_data(self, client, input, output): logger.info("RankingServerMK8D.get_common_data()") #--- request --- unique_id = input.u64() response = await self.get_common_data(client, unique_id) #--- response --- if not isinstance(response, bytes): raise RuntimeError("Expected bytes, got %s" %response.__class__.__name__) output.buffer(response) async def handle_change_attributes(self, client, input, output): logger.info("RankingServerMK8D.change_attributes()") #--- request --- category = input.u32() param = input.extract(RankingChangeAttributesParam) unique_id = input.u64() await self.change_attributes(client, category, param, unique_id) async def handle_change_all_attributes(self, client, input, output): logger.info("RankingServerMK8D.change_all_attributes()") #--- request --- param = input.extract(RankingChangeAttributesParam) unique_id = input.u64() await self.change_all_attributes(client, param, unique_id) async def handle_get_ranking(self, client, input, output): logger.info("RankingServerMK8D.get_ranking()") #--- request --- mode = input.u8() category = input.u32() order = input.extract(RankingOrderParam) unique_id = input.u64() pid = input.pid() response = await self.get_ranking(client, mode, category, order, unique_id, pid) #--- response --- if not isinstance(response, RankingResult): raise RuntimeError("Expected RankingResult, got %s" %response.__class__.__name__) output.add(response) async def handle_get_approx_order(self, client, input, output): logger.info("RankingServerMK8D.get_approx_order()") #--- request --- category = input.u32() order = input.extract(RankingOrderParam) score = input.u32() unique_id = input.u64() pid = input.pid() response = await self.get_approx_order(client, category, order, score, unique_id, pid) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u32(response) async def handle_get_stats(self, client, input, output): logger.info("RankingServerMK8D.get_stats()") #--- request --- category = input.u32() order = input.extract(RankingOrderParam) flags = input.u32() response = await self.get_stats(client, category, order, flags) #--- response --- if not isinstance(response, RankingStats): raise RuntimeError("Expected RankingStats, got %s" %response.__class__.__name__) output.add(response) async def handle_get_ranking_by_pid_list(self, client, input, output): logger.info("RankingServerMK8D.get_ranking_by_pid_list()") #--- request --- pids = input.list(input.pid) mode = input.u8() category = input.u32() order = input.extract(RankingOrderParam) unique_id = input.u64() response = await self.get_ranking_by_pid_list(client, pids, mode, category, order, unique_id) #--- response --- if not isinstance(response, RankingResult): raise RuntimeError("Expected RankingResult, got %s" %response.__class__.__name__) output.add(response) async def handle_get_ranking_by_unique_id_list(self, client, input, output): logger.info("RankingServerMK8D.get_ranking_by_unique_id_list()") #--- request --- ids = input.list(input.u64) mode = input.u8() category = input.u32() order = input.extract(RankingOrderParam) unique_id = input.u64() response = await self.get_ranking_by_unique_id_list(client, ids, mode, category, order, unique_id) #--- response --- if not isinstance(response, RankingResult): raise RuntimeError("Expected RankingResult, got %s" %response.__class__.__name__) output.add(response) async def handle_get_cached_topx_ranking(self, client, input, output): logger.info("RankingServerMK8D.get_cached_topx_ranking()") #--- request --- category = input.u32() order = input.extract(RankingOrderParam) response = await self.get_cached_topx_ranking(client, category, order) #--- response --- if not isinstance(response, RankingCachedResult): raise RuntimeError("Expected RankingCachedResult, got %s" %response.__class__.__name__) output.add(response) async def handle_get_cached_topx_rankings(self, client, input, output): logger.info("RankingServerMK8D.get_cached_topx_rankings()") #--- request --- categories = input.list(input.u32) order = input.list(RankingOrderParam) response = await self.get_cached_topx_rankings(client, categories, order) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_competition_ranking_score(self, client, input, output): logger.info("RankingServerMK8D.get_competition_ranking_score()") #--- request --- param = input.extract(CompetitionRankingGetScoreParam) response = await self.get_competition_ranking_score(client, param) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_upload_competition_ranking_score(self, client, input, output): logger.info("RankingServerMK8D.upload_competition_ranking_score()") #--- request --- param = input.extract(CompetitionRankingUploadScoreParam) response = await self.upload_competition_ranking_score(client, param) #--- response --- if not isinstance(response, bool): raise RuntimeError("Expected bool, got %s" %response.__class__.__name__) output.bool(response) async def handle_get_competition_info(self, client, input, output): logger.info("RankingServerMK8D.get_competition_info()") #--- request --- param = input.extract(CompetitionRankingInfoGetParam) response = await self.get_competition_info(client, param) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_upload_score_pack(self, client, input, output): logger.info("RankingServerMK8D.upload_score_pack()") #--- request --- score_data = input.extract(RankingScoreData) metadata = input.qbuffer() await self.upload_score_pack(client, score_data, metadata) async def handle_get_score_pack(self, client, input, output): logger.info("RankingServerMK8D.get_score_pack()") #--- request --- pids = input.list(input.pid) category = input.u32() response = await self.get_score_pack(client, pids, category) #--- response --- if not isinstance(response, ScorePack): raise RuntimeError("Expected ScorePack, got %s" %response.__class__.__name__) output.add(response) async def handle_execute_delete_score_job(self, client, input, output): logger.warning("RankingServerMK8D.execute_delete_score_job is not supported") raise common.RMCError("Core::NotImplemented") async def handle_get_commmon_data_by_pid_list(self, client, input, output): logger.info("RankingServerMK8D.get_commmon_data_by_pid_list()") #--- request --- pids = input.list(input.pid) response = await self.get_commmon_data_by_pid_list(client, pids) #--- response --- if not isinstance(response, CommonDataList): raise RuntimeError("Expected CommonDataList, got %s" %response.__class__.__name__) output.add(response) async def upload_score(self, *args): logger.warning("RankingServerMK8D.upload_score not implemented") raise common.RMCError("Core::NotImplemented") async def delete_score(self, *args): logger.warning("RankingServerMK8D.delete_score not implemented") raise common.RMCError("Core::NotImplemented") async def delete_all_scores(self, *args): logger.warning("RankingServerMK8D.delete_all_scores not implemented") raise common.RMCError("Core::NotImplemented") async def upload_common_data(self, *args): logger.warning("RankingServerMK8D.upload_common_data not implemented") raise common.RMCError("Core::NotImplemented") async def delete_common_data(self, *args): logger.warning("RankingServerMK8D.delete_common_data not implemented") raise common.RMCError("Core::NotImplemented") async def get_common_data(self, *args): logger.warning("RankingServerMK8D.get_common_data not implemented") raise common.RMCError("Core::NotImplemented") async def change_attributes(self, *args): logger.warning("RankingServerMK8D.change_attributes not implemented") raise common.RMCError("Core::NotImplemented") async def change_all_attributes(self, *args): logger.warning("RankingServerMK8D.change_all_attributes not implemented") raise common.RMCError("Core::NotImplemented") async def get_ranking(self, *args): logger.warning("RankingServerMK8D.get_ranking not implemented") raise common.RMCError("Core::NotImplemented") async def get_approx_order(self, *args): logger.warning("RankingServerMK8D.get_approx_order not implemented") raise common.RMCError("Core::NotImplemented") async def get_stats(self, *args): logger.warning("RankingServerMK8D.get_stats not implemented") raise common.RMCError("Core::NotImplemented") async def get_ranking_by_pid_list(self, *args): logger.warning("RankingServerMK8D.get_ranking_by_pid_list not implemented") raise common.RMCError("Core::NotImplemented") async def get_ranking_by_unique_id_list(self, *args): logger.warning("RankingServerMK8D.get_ranking_by_unique_id_list not implemented") raise common.RMCError("Core::NotImplemented") async def get_cached_topx_ranking(self, *args): logger.warning("RankingServerMK8D.get_cached_topx_ranking not implemented") raise common.RMCError("Core::NotImplemented") async def get_cached_topx_rankings(self, *args): logger.warning("RankingServerMK8D.get_cached_topx_rankings not implemented") raise common.RMCError("Core::NotImplemented") async def get_competition_ranking_score(self, *args): logger.warning("RankingServerMK8D.get_competition_ranking_score not implemented") raise common.RMCError("Core::NotImplemented") async def upload_competition_ranking_score(self, *args): logger.warning("RankingServerMK8D.upload_competition_ranking_score not implemented") raise common.RMCError("Core::NotImplemented") async def get_competition_info(self, *args): logger.warning("RankingServerMK8D.get_competition_info not implemented") raise common.RMCError("Core::NotImplemented") async def upload_score_pack(self, *args): logger.warning("RankingServerMK8D.upload_score_pack not implemented") raise common.RMCError("Core::NotImplemented") async def get_score_pack(self, *args): logger.warning("RankingServerMK8D.get_score_pack not implemented") raise common.RMCError("Core::NotImplemented") async def get_commmon_data_by_pid_list(self, *args): logger.warning("RankingServerMK8D.get_commmon_data_by_pid_list not implemented") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/remotelog.py ================================================ # This file was generated automatically by generate_protocols.py from nintendo.nex import notification, rmc, common, streams import logging logger = logging.getLogger(__name__) class RemoteLogDeviceProtocol: METHOD_LOG = 1 PROTOCOL_ID = 0x1 class RemoteLogDeviceClient(RemoteLogDeviceProtocol): def __init__(self, client): self.settings = client.settings self.client = client async def log(self, message): logger.info("RemoteLogDeviceClient.log()") #--- request --- stream = streams.StreamOut(self.settings) stream.string(message) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_LOG, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("RemoteLogDeviceClient.log -> done") class RemoteLogDeviceServer(RemoteLogDeviceProtocol): def __init__(self): self.methods = { self.METHOD_LOG: self.handle_log, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on RemoteLogDeviceServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_log(self, client, input, output): logger.info("RemoteLogDeviceServer.log()") #--- request --- message = input.string() await self.log(client, message) async def log(self, *args): logger.warning("RemoteLogDeviceServer.log not implemented") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/rmc.py ================================================ from nintendo.nex import prudp, common, streams from anynet import util import contextlib import struct import anyio import logging logger = logging.getLogger(__name__) class RMCResponse: pass class RMCMessage: REQUEST = 0 RESPONSE = 1 def __init__(self, settings): self.settings = settings self.mode = RMCMessage.REQUEST self.protocol = None self.method = None self.call_id = 0 self.error = -1 self.body = b"" @staticmethod def prepare(settings, mode, protocol, method, call_id, body): inst = RMCMessage(settings) inst.mode = mode inst.protocol = protocol inst.method = method inst.call_id = call_id inst.body = body return inst @staticmethod def request(settings, protocol, method, call_id, body): return RMCMessage.prepare( settings, RMCMessage.REQUEST, protocol, method, call_id, body ) @staticmethod def response(settings, protocol, method, call_id, body): return RMCMessage.prepare( settings, RMCMessage.RESPONSE, protocol, method, call_id, body ) @staticmethod def error(settings, protocol, method, call_id, error): inst = RMCMessage(settings) inst.mode = RMCMessage.RESPONSE inst.protocol = protocol inst.method = method inst.call_id = call_id inst.error = error return inst @staticmethod def parse(settings, data): inst = RMCMessage(settings) inst.decode(data) return inst def encode(self): stream = streams.StreamOut(self.settings) flag = 0x80 if self.mode == self.REQUEST else 0 if self.protocol < 0x80: stream.u8(self.protocol | flag) else: stream.u8(0x7F | flag) stream.u16(self.protocol) if self.mode == self.REQUEST: stream.u32(self.call_id) stream.u32(self.method) stream.write(self.body) else: if self.error != -1 and self.error & 0x80000000: stream.bool(False) stream.u32(self.error) stream.u32(self.call_id) else: stream.bool(True) stream.u32(self.call_id) stream.u32(self.method | 0x8000) stream.write(self.body) return struct.pack("I", stream.size()) + stream.get() def decode(self, data): stream = streams.StreamIn(data, self.settings) length = stream.u32() if length != stream.size() - 4: raise ValueError("RMC message has unexpected size") protocol = stream.u8() self.protocol = protocol & ~0x80 if self.protocol == 0x7F: self.protocol = stream.u16() if protocol & 0x80: self.mode = self.REQUEST self.call_id = stream.u32() self.method = stream.u32() self.body = stream.readall() else: self.mode = self.RESPONSE if stream.bool(): self.call_id = stream.u32() self.method = stream.u32() & ~0x8000 self.body = stream.readall() else: self.error = stream.u32() self.call_id = stream.u32() if not stream.eof(): raise ValueError("RMC error message is bigger than expected") class RMCClient: def __init__(self, settings, client): self.settings = settings.copy() self.client = client self.call_id = 1 if self.client.minor_version() >= 3: self.settings["nex.struct_header"] = True self.servers = {} self.requests = {} self.responses = {} self.closed = False async def __aenter__(self): return self async def __aexit__(self, typ, val, tb): await self.cleanup() def register_server(self, server): if server.PROTOCOL_ID in self.servers: raise ValueError("Server with protocol id %i already exists" %server.PROTOCOL_ID) self.servers[server.PROTOCOL_ID] = server async def cleanup(self): if not self.closed: self.closed = True for event in self.requests.values(): event.set() for server in self.servers.values(): await server.logout(self) async def close(self): if not self.closed: await self.cleanup() await self.client.close() async def disconnect(self): if not self.closed: await self.cleanup() await self.client.disconnect() async def start(self, servers): for server in servers: self.register_server(server) while not self.closed: try: data = await self.client.recv() except anyio.EndOfStream: logger.info("Connection was closed") await self.cleanup() return message = RMCMessage.parse(self.settings, data) if message.mode == RMCMessage.REQUEST: logger.debug( "Received RMC request: protocol=%i method=%i call=%i", message.protocol, message.method, message.call_id ) await self.handle_request(message) else: logger.debug( "Received RMC response: protocol=%i method=%s call=%i", message.protocol, message.method, message.call_id ) if message.call_id in self.requests: self.responses[message.call_id] = message event = self.requests.pop(message.call_id) event.set() else: logger.warning("RMC response has invalid call id") async def handle_request(self, request): input = streams.StreamIn(request.body, self.settings) output = streams.StreamOut(self.settings) result = common.Result() if request.protocol in self.servers: try: await self.servers[request.protocol].handle(self, request.method, input, output) except common.RMCError as e: logger.warning("RMC failed: %s" %e) result = e.result() except Exception as e: logger.exception("Exception occurred while handling a method call") if isinstance(e, TypeError): result = common.Result.error("PythonCore::TypeError") elif isinstance(e, IndexError): result = common.Result.error("PythonCore::IndexError") elif isinstance(e, MemoryError): result = common.Result.error("PythonCore::MemoryError") elif isinstance(e, KeyError): result = common.Result.error("PythonCore::KeyError") else: result = common.Result.error("PythonCore::Exception") except anyio.ExceptionGroup as e: logger.exception("Multiple exceptions occurred while handling a method call") filtered = [] for exc in e.exceptions: if not isinstance(exc, Exception): raise result = common.Result.error("PythonCore::Exception") if getattr(self.servers[request.protocol], "NORESPONSE", False): return else: logger.warning("Received RMC request with unimplemented protocol id: %i", request.protocol) result = common.Result.error("Core::NotImplemented") if result.is_success(): response = RMCMessage.response( self.settings, request.protocol, request.method, request.call_id, output.get() ) else: response = RMCMessage.error( self.settings, request.protocol, request.method, request.call_id, result.code() ) await self.client.send(response.encode()) async def request(self, protocol, method, body, noresponse=False): if self.closed: raise RuntimeError("RMC connection is closed") call_id = self.call_id self.call_id = (self.call_id + 1) & 0xFFFFFFFF if not noresponse: event = anyio.Event() self.requests[call_id] = event message = RMCMessage.request(self.settings, protocol, method, call_id, body) await self.client.send(message.encode()) if not noresponse: await event.wait() if self.closed: raise RuntimeError("RMC connection is closed") message = self.responses.pop(call_id) if message.error != -1: raise common.RMCError(message.error) return message.body def pid(self): return self.client.pid() def local_address(self): return self.client.local_address() def remote_address(self): return self.client.remote_address() def local_sid(self): return self.client.local_sid() def remote_sid(self): return self.client.remote_sid() @contextlib.asynccontextmanager async def connect(settings, host, port, vport=1, context=None, credentials=None, servers=[]): logger.debug("Connecting RMC client to %s:%i:%i", host, port, vport) async with prudp.connect(settings, host, port, vport, 10, context, credentials) as client: client = RMCClient(settings, client) async with client: async with util.create_task_group() as group: group.start_soon(client.start, servers) yield client logger.debug("RMC client is closed") @contextlib.asynccontextmanager async def serve(settings, servers, host="", port=0, vport=1, context=None, key=None): async def handle(client): host, port = client.remote_address() logger.debug("New RMC connection: %s:%i", host, port) client = RMCClient(settings, client) async with client: await client.start(servers) logger.info("Starting RMC server at %s:%i:%i", host, port, vport) async with prudp.serve(handle, settings, host, port, vport, 10, context, key): yield logger.info("RMC server is closed") @contextlib.asynccontextmanager async def serve_on_transport(settings, servers, transport, port, key=None): async def handle(client): host, port = client.remote_address() logger.debug("New RMC connection: %s:%i", host, port) client = RMCClient(settings, client) async with client: await client.start(servers) logger.info("Starting RMC server at PRUDP port %i", port) async with transport.serve(handle, port, 10, key): yield logger.info("RMC server is closed") serve_prudp = serve_on_transport ================================================ FILE: nintendo/nex/screening.py ================================================ # This file was generated automatically by generate_protocols.py from nintendo.nex import notification, rmc, common, streams import logging logger = logging.getLogger(__name__) class ScreeningProtocol: METHOD_REPORT_DATA_STORE_CONTENT = 1 METHOD_REPORT_USER = 2 PROTOCOL_ID = 0x7C class ScreeningClient(ScreeningProtocol): def __init__(self, client): self.settings = client.settings self.client = client class ScreeningServer(ScreeningProtocol): def __init__(self): self.methods = { self.METHOD_REPORT_DATA_STORE_CONTENT: self.handle_report_data_store_content, self.METHOD_REPORT_USER: self.handle_report_user, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on ScreeningServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_report_data_store_content(self, client, input, output): logger.warning("ScreeningServer.report_data_store_content is not supported") raise common.RMCError("Core::NotImplemented") async def handle_report_user(self, client, input, output): logger.warning("ScreeningServer.report_user is not supported") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/secure.py ================================================ # This file was generated automatically by generate_protocols.py from nintendo.nex import notification, rmc, common, streams import logging logger = logging.getLogger(__name__) class ConnectionData(common.Structure): def __init__(self): super().__init__() self.station = None self.connection_id = None def check_required(self, settings, version): for field in ['station', 'connection_id']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.station = stream.stationurl() self.connection_id = stream.u32() def save(self, stream, version): self.check_required(stream.settings, version) stream.stationurl(self.station) stream.u32(self.connection_id) class NintendoLoginData(common.Structure): def __init__(self): super().__init__() self.token = None def check_required(self, settings, version): for field in ['token']: if getattr(self, field) is None: raise ValueError("No value assigned to required field: %s" %field) def load(self, stream, version): self.token = stream.string() def save(self, stream, version): self.check_required(stream.settings, version) stream.string(self.token) class SecureConnectionProtocol: METHOD_REGISTER = 1 METHOD_REQUEST_CONNECTION_DATA = 2 METHOD_REQUEST_URLS = 3 METHOD_REGISTER_EX = 4 METHOD_TEST_CONNECTIVITY = 5 METHOD_UPDATE_URLS = 6 METHOD_REPLACE_URL = 7 METHOD_SEND_REPORT = 8 PROTOCOL_ID = 0xB class SecureConnectionClient(SecureConnectionProtocol): def __init__(self, client): self.settings = client.settings self.client = client async def register(self, urls): logger.info("SecureConnectionClient.register()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(urls, stream.stationurl) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REGISTER, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.result() obj.connection_id = stream.u32() obj.public_station = stream.stationurl() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("SecureConnectionClient.register -> done") return obj async def request_connection_data(self, cid, pid): logger.info("SecureConnectionClient.request_connection_data()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(cid) stream.pid(pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REQUEST_CONNECTION_DATA, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.connection_data = stream.list(ConnectionData) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("SecureConnectionClient.request_connection_data -> done") return obj async def request_urls(self, cid, pid): logger.info("SecureConnectionClient.request_urls()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(cid) stream.pid(pid) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REQUEST_URLS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.bool() obj.urls = stream.list(stream.stationurl) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("SecureConnectionClient.request_urls -> done") return obj async def register_ex(self, urls, login_data): logger.info("SecureConnectionClient.register_ex()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(urls, stream.stationurl) stream.anydata(login_data) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REGISTER_EX, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) obj = rmc.RMCResponse() obj.result = stream.result() obj.connection_id = stream.u32() obj.public_station = stream.stationurl() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("SecureConnectionClient.register_ex -> done") return obj async def test_connectivity(self): logger.info("SecureConnectionClient.test_connectivity()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_TEST_CONNECTIVITY, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("SecureConnectionClient.test_connectivity -> done") async def update_urls(self, urls): logger.info("SecureConnectionClient.update_urls()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(urls, stream.stationurl) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_UPDATE_URLS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("SecureConnectionClient.update_urls -> done") async def replace_url(self, url, new): logger.info("SecureConnectionClient.replace_url()") #--- request --- stream = streams.StreamOut(self.settings) stream.stationurl(url) stream.stationurl(new) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_REPLACE_URL, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("SecureConnectionClient.replace_url -> done") async def send_report(self, report_id, data): logger.info("SecureConnectionClient.send_report()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(report_id) stream.qbuffer(data) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_SEND_REPORT, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("SecureConnectionClient.send_report -> done") class SecureConnectionServer(SecureConnectionProtocol): def __init__(self): self.methods = { self.METHOD_REGISTER: self.handle_register, self.METHOD_REQUEST_CONNECTION_DATA: self.handle_request_connection_data, self.METHOD_REQUEST_URLS: self.handle_request_urls, self.METHOD_REGISTER_EX: self.handle_register_ex, self.METHOD_TEST_CONNECTIVITY: self.handle_test_connectivity, self.METHOD_UPDATE_URLS: self.handle_update_urls, self.METHOD_REPLACE_URL: self.handle_replace_url, self.METHOD_SEND_REPORT: self.handle_send_report, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on SecureConnectionServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_register(self, client, input, output): logger.info("SecureConnectionServer.register()") #--- request --- urls = input.list(input.stationurl) response = await self.register(client, urls) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'connection_id', 'public_station']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.result(response.result) output.u32(response.connection_id) output.stationurl(response.public_station) async def handle_request_connection_data(self, client, input, output): logger.info("SecureConnectionServer.request_connection_data()") #--- request --- cid = input.u32() pid = input.pid() response = await self.request_connection_data(client, cid, pid) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'connection_data']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.list(response.connection_data, output.add) async def handle_request_urls(self, client, input, output): logger.info("SecureConnectionServer.request_urls()") #--- request --- cid = input.u32() pid = input.pid() response = await self.request_urls(client, cid, pid) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'urls']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.bool(response.result) output.list(response.urls, output.stationurl) async def handle_register_ex(self, client, input, output): logger.info("SecureConnectionServer.register_ex()") #--- request --- urls = input.list(input.stationurl) login_data = input.anydata() response = await self.register_ex(client, urls, login_data) #--- response --- if not isinstance(response, rmc.RMCResponse): raise RuntimeError("Expected RMCResponse, got %s" %response.__class__.__name__) for field in ['result', 'connection_id', 'public_station']: if not hasattr(response, field): raise RuntimeError("Missing field in RMCResponse: %s" %field) output.result(response.result) output.u32(response.connection_id) output.stationurl(response.public_station) async def handle_test_connectivity(self, client, input, output): logger.info("SecureConnectionServer.test_connectivity()") #--- request --- await self.test_connectivity(client) async def handle_update_urls(self, client, input, output): logger.info("SecureConnectionServer.update_urls()") #--- request --- urls = input.list(input.stationurl) await self.update_urls(client, urls) async def handle_replace_url(self, client, input, output): logger.info("SecureConnectionServer.replace_url()") #--- request --- url = input.stationurl() new = input.stationurl() await self.replace_url(client, url, new) async def handle_send_report(self, client, input, output): logger.info("SecureConnectionServer.send_report()") #--- request --- report_id = input.u32() data = input.qbuffer() await self.send_report(client, report_id, data) async def register(self, *args): logger.warning("SecureConnectionServer.register not implemented") raise common.RMCError("Core::NotImplemented") async def request_connection_data(self, *args): logger.warning("SecureConnectionServer.request_connection_data not implemented") raise common.RMCError("Core::NotImplemented") async def request_urls(self, *args): logger.warning("SecureConnectionServer.request_urls not implemented") raise common.RMCError("Core::NotImplemented") async def register_ex(self, *args): logger.warning("SecureConnectionServer.register_ex not implemented") raise common.RMCError("Core::NotImplemented") async def test_connectivity(self, *args): logger.warning("SecureConnectionServer.test_connectivity not implemented") raise common.RMCError("Core::NotImplemented") async def update_urls(self, *args): logger.warning("SecureConnectionServer.update_urls not implemented") raise common.RMCError("Core::NotImplemented") async def replace_url(self, *args): logger.warning("SecureConnectionServer.replace_url not implemented") raise common.RMCError("Core::NotImplemented") async def send_report(self, *args): logger.warning("SecureConnectionServer.send_report not implemented") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/settings.py ================================================ from nintendo import resources class Settings: TRANSPORT_UDP = 0 TRANSPORT_TCP = 1 TRANSPORT_WEBSOCKET = 2 COMPRESSION_NONE = 0 COMPRESSION_ZLIB = 1 ENCRYPTION_NONE = 0 ENCRYPTION_RC4 = 1 field_types = { "nex.version": int, "nex.client_version": int, "nex.struct_header": int, "nex.pid_size": int, "prudp.access_key": str, "prudp.version": int, "prudp.minor_version": int, "prudp.supported_functions": int, "prudp.transport": int, "prudp.compression": int, "prudp.encryption": int, "prudp.resend_timeout": float, "prudp.resend_limit": int, "prudp.ping_timeout": float, "prudp.fragment_size": int, "prudp.max_substream_id": int, "prudp_v0.signature_version": int, "prudp_v0.flags_version": int, "prudp_v0.checksum_version": int, "kerberos.key_size": int, "kerberos.key_derivation": int, "kerberos.ticket_version": int } def __init__(self, filename=None): self.settings = {} self.reset() if filename: self.load(filename) def __getitem__(self, name): return self.settings[name] def __setitem__(self, name, value): if name not in self.field_types: raise KeyError("Unknown setting: %s" %name) self.settings[name] = self.field_types[name](value) def configure(self, access_key, nex_version, client_version=None): self["prudp.access_key"] = access_key self["nex.version"] = nex_version if nex_version >= 40400: if client_version is None: raise ValueError("NEX 4.4.0 or later requires client version") self["nex.client_version"] = client_version def reset(self): self.load("default") def copy(self): copy = Settings() copy.settings = self.settings.copy() return copy def load(self, name): with resources.open("files/config/%s.cfg" %name) as f: linenum = 1 for line in f: line = line.strip() if line: if "=" in line: field, value = line.split("=", 1) self[field.strip()] = value.strip() else: raise ValueError("Syntax error at line %i" %linenum) linenum += 1 def default(): return Settings() def load(name): return Settings(name) ================================================ FILE: nintendo/nex/streams.py ================================================ from nintendo.nex import common from anynet import streams class StreamOut(streams.StreamOut): def __init__(self, settings): super().__init__("<") self.settings = settings def pid(self, value): if self.settings["nex.pid_size"] == 8: self.u64(value) else: self.u32(value) def result(self, result): self.u32(result.code()) def list(self, list, func): self.u32(len(list)) self.repeat(list, func) def map(self, map, keyfunc, valuefunc): self.u32(len(map)) for key, value in map.items(): keyfunc(key) valuefunc(value) def string(self, string): if string is None: self.u16(0) else: data = (string + "\0").encode("utf8") self.u16(len(data)) self.write(data) def stationurl(self, url): self.string(str(url)) def datetime(self, datetime): self.u64(datetime.value()) def buffer(self, data): self.u32(len(data)) self.write(data) def qbuffer(self, data): self.u16(len(data)) self.write(data) def add(self, inst): inst.encode(self) def anydata(self, inst): holder = common.DataHolder() holder.data = inst self.add(holder) def variant(self, value): # We have to check for bool before int, # because bool is a subclass of int if value is None: self.u8(0) elif isinstance(value, bool): self.u8(3) self.bool(value) elif isinstance(value, int): if value < 0: self.u8(1) self.s64(value) else: self.u8(6) self.u64(value) elif isinstance(value, float): self.u8(2) self.double(value) elif isinstance(value, str): self.u8(4) self.string(value) elif isinstance(value, common.DateTime): self.u8(5) self.datetime(value) else: raise TypeError("Type is not compatible with 'variant'") class StreamIn(streams.StreamIn): def __init__(self, data, settings): super().__init__(data, "<") self.settings = settings def pid(self): if self.settings["nex.pid_size"] == 8: return self.u64() return self.u32() def result(self): return common.Result(self.u32()) def list(self, func): return self.repeat(func, self.u32()) def map(self, keyfunc, valuefunc): map = {} for i in range(self.u32()): key = self.callback(keyfunc) value = self.callback(valuefunc) map[key] = value return map def repeat(self, func, count): return [self.callback(func) for i in range(count)] def callback(self, func): if isinstance(func, type) and issubclass(func, common.Structure): return self.extract(func) return func() def string(self): length = self.u16() if length: return self.read(length).decode("utf8")[:-1] #Remove null-terminator def stationurl(self): return common.StationURL.parse(self.string()) def datetime(self): return common.DateTime(self.u64()) def buffer(self): return self.read(self.u32()) def qbuffer(self): return self.read(self.u16()) def substream(self): return StreamIn(self.buffer(), self.settings) def extract(self, cls): inst = cls() inst.decode(self) return inst def anydata(self): return self.extract(common.DataHolder).data def variant(self): type = self.u8() if type == 0: return None elif type == 1: return self.s64() elif type == 2: return self.double() elif type == 3: return self.bool() elif type == 4: return self.string() elif type == 5: return self.datetime() elif type == 6: return self.u64() raise ValueError("Variant has invalid type id") ================================================ FILE: nintendo/nex/subscriber.py ================================================ # This file was generated automatically by generate_protocols.py from nintendo.nex import notification, rmc, common, streams import logging logger = logging.getLogger(__name__) class SubscriberProtocol: METHOD_HELLO = 1 METHOD_POST_CONTENT = 2 METHOD_GET_CONTENT = 3 METHOD_FOLLOW = 4 METHOD_UNFOLLOW_ALL_AND_FOLLOW = 5 METHOD_UNFOLLOW = 6 METHOD_GET_FOLLOWING = 7 METHOD_GET_FOLLOWER = 8 METHOD_GET_NUM_FOLLOWERS = 9 METHOD_GET_TIMELINE = 10 METHOD_DELETE_CONTENT = 11 METHOD_GET_CONTENT_MULTI = 12 METHOD_UPDATE_USER_STATUS = 13 METHOD_GET_FRIEND_USER_STATUSES = 14 METHOD_GET_USER_STATUSES = 15 PROTOCOL_ID = 0x79 class SubscriberClient(SubscriberProtocol): def __init__(self, client): self.settings = client.settings self.client = client class SubscriberServer(SubscriberProtocol): def __init__(self): self.methods = { self.METHOD_HELLO: self.handle_hello, self.METHOD_POST_CONTENT: self.handle_post_content, self.METHOD_GET_CONTENT: self.handle_get_content, self.METHOD_FOLLOW: self.handle_follow, self.METHOD_UNFOLLOW_ALL_AND_FOLLOW: self.handle_unfollow_all_and_follow, self.METHOD_UNFOLLOW: self.handle_unfollow, self.METHOD_GET_FOLLOWING: self.handle_get_following, self.METHOD_GET_FOLLOWER: self.handle_get_follower, self.METHOD_GET_NUM_FOLLOWERS: self.handle_get_num_followers, self.METHOD_GET_TIMELINE: self.handle_get_timeline, self.METHOD_DELETE_CONTENT: self.handle_delete_content, self.METHOD_GET_CONTENT_MULTI: self.handle_get_content_multi, self.METHOD_UPDATE_USER_STATUS: self.handle_update_user_status, self.METHOD_GET_FRIEND_USER_STATUSES: self.handle_get_friend_user_statuses, self.METHOD_GET_USER_STATUSES: self.handle_get_user_statuses, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on SubscriberServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_hello(self, client, input, output): logger.warning("SubscriberServer.hello is not supported") raise common.RMCError("Core::NotImplemented") async def handle_post_content(self, client, input, output): logger.warning("SubscriberServer.post_content is not supported") raise common.RMCError("Core::NotImplemented") async def handle_get_content(self, client, input, output): logger.warning("SubscriberServer.get_content is not supported") raise common.RMCError("Core::NotImplemented") async def handle_follow(self, client, input, output): logger.warning("SubscriberServer.follow is not supported") raise common.RMCError("Core::NotImplemented") async def handle_unfollow_all_and_follow(self, client, input, output): logger.warning("SubscriberServer.unfollow_all_and_follow is not supported") raise common.RMCError("Core::NotImplemented") async def handle_unfollow(self, client, input, output): logger.warning("SubscriberServer.unfollow is not supported") raise common.RMCError("Core::NotImplemented") async def handle_get_following(self, client, input, output): logger.warning("SubscriberServer.get_following is not supported") raise common.RMCError("Core::NotImplemented") async def handle_get_follower(self, client, input, output): logger.warning("SubscriberServer.get_follower is not supported") raise common.RMCError("Core::NotImplemented") async def handle_get_num_followers(self, client, input, output): logger.warning("SubscriberServer.get_num_followers is not supported") raise common.RMCError("Core::NotImplemented") async def handle_get_timeline(self, client, input, output): logger.warning("SubscriberServer.get_timeline is not supported") raise common.RMCError("Core::NotImplemented") async def handle_delete_content(self, client, input, output): logger.warning("SubscriberServer.delete_content is not supported") raise common.RMCError("Core::NotImplemented") async def handle_get_content_multi(self, client, input, output): logger.warning("SubscriberServer.get_content_multi is not supported") raise common.RMCError("Core::NotImplemented") async def handle_update_user_status(self, client, input, output): logger.warning("SubscriberServer.update_user_status is not supported") raise common.RMCError("Core::NotImplemented") async def handle_get_friend_user_statuses(self, client, input, output): logger.warning("SubscriberServer.get_friend_user_statuses is not supported") raise common.RMCError("Core::NotImplemented") async def handle_get_user_statuses(self, client, input, output): logger.warning("SubscriberServer.get_user_statuses is not supported") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nex/utility.py ================================================ # This file was generated automatically by generate_protocols.py from nintendo.nex import notification, rmc, common, streams import logging logger = logging.getLogger(__name__) class UniqueIdInfo(common.Structure): def __init__(self): super().__init__() self.unique_id = 0 self.password = 0 def check_required(self, settings, version): pass def load(self, stream, version): self.unique_id = stream.u64() self.password = stream.u64() def save(self, stream, version): self.check_required(stream.settings, version) stream.u64(self.unique_id) stream.u64(self.password) class UtilityProtocol: METHOD_ACQUIRE_NEX_UNIQUE_ID = 1 METHOD_ACQUIRE_NEX_UNIQUE_ID_WITH_PASSWORD = 2 METHOD_ASSOCIATE_NEX_UNIQUE_ID_WITH_MY_PRINCIPAL_ID = 3 METHOD_ASSOCIATE_NEX_UNIQUE_IDS_WITH_MY_PRINCIPAL_ID = 4 METHOD_GET_ASSOCIATED_NEX_UNIQUE_ID_WITH_MY_PRINCIPAL_ID = 5 METHOD_GET_ASSOCIATED_NEX_UNIQUE_IDS_WITH_MY_PRINCIPAL_ID = 6 METHOD_GET_INTEGER_SETTINGS = 7 METHOD_GET_STRING_SETTINGS = 8 PROTOCOL_ID = 0x6E class UtilityClient(UtilityProtocol): def __init__(self, client): self.settings = client.settings self.client = client async def acquire_nex_unique_id(self): logger.info("UtilityClient.acquire_nex_unique_id()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_ACQUIRE_NEX_UNIQUE_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) unique_id = stream.u64() if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("UtilityClient.acquire_nex_unique_id -> done") return unique_id async def acquire_nex_unique_id_with_password(self): logger.info("UtilityClient.acquire_nex_unique_id_with_password()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_ACQUIRE_NEX_UNIQUE_ID_WITH_PASSWORD, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(UniqueIdInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("UtilityClient.acquire_nex_unique_id_with_password -> done") return info async def associate_nex_unique_id_with_my_principal_id(self, info): logger.info("UtilityClient.associate_nex_unique_id_with_my_principal_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.add(info) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_ASSOCIATE_NEX_UNIQUE_ID_WITH_MY_PRINCIPAL_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("UtilityClient.associate_nex_unique_id_with_my_principal_id -> done") async def associate_nex_unique_ids_with_my_principal_id(self, infos): logger.info("UtilityClient.associate_nex_unique_ids_with_my_principal_id()") #--- request --- stream = streams.StreamOut(self.settings) stream.list(infos, stream.add) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_ASSOCIATE_NEX_UNIQUE_IDS_WITH_MY_PRINCIPAL_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("UtilityClient.associate_nex_unique_ids_with_my_principal_id -> done") async def get_associated_nex_unique_id_with_my_principal_id(self): logger.info("UtilityClient.get_associated_nex_unique_id_with_my_principal_id()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_ASSOCIATED_NEX_UNIQUE_ID_WITH_MY_PRINCIPAL_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) info = stream.extract(UniqueIdInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("UtilityClient.get_associated_nex_unique_id_with_my_principal_id -> done") return info async def get_associated_nex_unique_ids_with_my_principal_id(self): logger.info("UtilityClient.get_associated_nex_unique_ids_with_my_principal_id()") #--- request --- stream = streams.StreamOut(self.settings) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_ASSOCIATED_NEX_UNIQUE_IDS_WITH_MY_PRINCIPAL_ID, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) infos = stream.list(UniqueIdInfo) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("UtilityClient.get_associated_nex_unique_ids_with_my_principal_id -> done") return infos async def get_integer_settings(self, index): logger.info("UtilityClient.get_integer_settings()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(index) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_INTEGER_SETTINGS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) settings = stream.map(stream.u16, stream.s32) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("UtilityClient.get_integer_settings -> done") return settings async def get_string_settings(self, index): logger.info("UtilityClient.get_string_settings()") #--- request --- stream = streams.StreamOut(self.settings) stream.u32(index) data = await self.client.request(self.PROTOCOL_ID, self.METHOD_GET_STRING_SETTINGS, stream.get()) #--- response --- stream = streams.StreamIn(data, self.settings) settings = stream.map(stream.u16, stream.string) if not stream.eof(): raise ValueError("Response is bigger than expected (got %i bytes, but only %i were read)" %(stream.size(), stream.tell())) logger.info("UtilityClient.get_string_settings -> done") return settings class UtilityServer(UtilityProtocol): def __init__(self): self.methods = { self.METHOD_ACQUIRE_NEX_UNIQUE_ID: self.handle_acquire_nex_unique_id, self.METHOD_ACQUIRE_NEX_UNIQUE_ID_WITH_PASSWORD: self.handle_acquire_nex_unique_id_with_password, self.METHOD_ASSOCIATE_NEX_UNIQUE_ID_WITH_MY_PRINCIPAL_ID: self.handle_associate_nex_unique_id_with_my_principal_id, self.METHOD_ASSOCIATE_NEX_UNIQUE_IDS_WITH_MY_PRINCIPAL_ID: self.handle_associate_nex_unique_ids_with_my_principal_id, self.METHOD_GET_ASSOCIATED_NEX_UNIQUE_ID_WITH_MY_PRINCIPAL_ID: self.handle_get_associated_nex_unique_id_with_my_principal_id, self.METHOD_GET_ASSOCIATED_NEX_UNIQUE_IDS_WITH_MY_PRINCIPAL_ID: self.handle_get_associated_nex_unique_ids_with_my_principal_id, self.METHOD_GET_INTEGER_SETTINGS: self.handle_get_integer_settings, self.METHOD_GET_STRING_SETTINGS: self.handle_get_string_settings, } async def logout(self, client): pass async def handle(self, client, method_id, input, output): if method_id in self.methods: await self.methods[method_id](client, input, output) else: logger.warning("Unknown method called on UtilityServer: %i", method_id) raise common.RMCError("Core::NotImplemented") async def handle_acquire_nex_unique_id(self, client, input, output): logger.info("UtilityServer.acquire_nex_unique_id()") #--- request --- response = await self.acquire_nex_unique_id(client) #--- response --- if not isinstance(response, int): raise RuntimeError("Expected int, got %s" %response.__class__.__name__) output.u64(response) async def handle_acquire_nex_unique_id_with_password(self, client, input, output): logger.info("UtilityServer.acquire_nex_unique_id_with_password()") #--- request --- response = await self.acquire_nex_unique_id_with_password(client) #--- response --- if not isinstance(response, UniqueIdInfo): raise RuntimeError("Expected UniqueIdInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_associate_nex_unique_id_with_my_principal_id(self, client, input, output): logger.info("UtilityServer.associate_nex_unique_id_with_my_principal_id()") #--- request --- info = input.extract(UniqueIdInfo) await self.associate_nex_unique_id_with_my_principal_id(client, info) async def handle_associate_nex_unique_ids_with_my_principal_id(self, client, input, output): logger.info("UtilityServer.associate_nex_unique_ids_with_my_principal_id()") #--- request --- infos = input.list(UniqueIdInfo) await self.associate_nex_unique_ids_with_my_principal_id(client, infos) async def handle_get_associated_nex_unique_id_with_my_principal_id(self, client, input, output): logger.info("UtilityServer.get_associated_nex_unique_id_with_my_principal_id()") #--- request --- response = await self.get_associated_nex_unique_id_with_my_principal_id(client) #--- response --- if not isinstance(response, UniqueIdInfo): raise RuntimeError("Expected UniqueIdInfo, got %s" %response.__class__.__name__) output.add(response) async def handle_get_associated_nex_unique_ids_with_my_principal_id(self, client, input, output): logger.info("UtilityServer.get_associated_nex_unique_ids_with_my_principal_id()") #--- request --- response = await self.get_associated_nex_unique_ids_with_my_principal_id(client) #--- response --- if not isinstance(response, list): raise RuntimeError("Expected list, got %s" %response.__class__.__name__) output.list(response, output.add) async def handle_get_integer_settings(self, client, input, output): logger.info("UtilityServer.get_integer_settings()") #--- request --- index = input.u32() response = await self.get_integer_settings(client, index) #--- response --- if not isinstance(response, dict): raise RuntimeError("Expected dict, got %s" %response.__class__.__name__) output.map(response, output.u16, output.s32) async def handle_get_string_settings(self, client, input, output): logger.info("UtilityServer.get_string_settings()") #--- request --- index = input.u32() response = await self.get_string_settings(client, index) #--- response --- if not isinstance(response, dict): raise RuntimeError("Expected dict, got %s" %response.__class__.__name__) output.map(response, output.u16, output.string) async def acquire_nex_unique_id(self, *args): logger.warning("UtilityServer.acquire_nex_unique_id not implemented") raise common.RMCError("Core::NotImplemented") async def acquire_nex_unique_id_with_password(self, *args): logger.warning("UtilityServer.acquire_nex_unique_id_with_password not implemented") raise common.RMCError("Core::NotImplemented") async def associate_nex_unique_id_with_my_principal_id(self, *args): logger.warning("UtilityServer.associate_nex_unique_id_with_my_principal_id not implemented") raise common.RMCError("Core::NotImplemented") async def associate_nex_unique_ids_with_my_principal_id(self, *args): logger.warning("UtilityServer.associate_nex_unique_ids_with_my_principal_id not implemented") raise common.RMCError("Core::NotImplemented") async def get_associated_nex_unique_id_with_my_principal_id(self, *args): logger.warning("UtilityServer.get_associated_nex_unique_id_with_my_principal_id not implemented") raise common.RMCError("Core::NotImplemented") async def get_associated_nex_unique_ids_with_my_principal_id(self, *args): logger.warning("UtilityServer.get_associated_nex_unique_ids_with_my_principal_id not implemented") raise common.RMCError("Core::NotImplemented") async def get_integer_settings(self, *args): logger.warning("UtilityServer.get_integer_settings not implemented") raise common.RMCError("Core::NotImplemented") async def get_string_settings(self, *args): logger.warning("UtilityServer.get_string_settings not implemented") raise common.RMCError("Core::NotImplemented") ================================================ FILE: nintendo/nnas.py ================================================ from anynet import http, tls from nintendo import resources import datetime import hashlib import struct import base64 import logging logger = logging.getLogger(__name__) def calc_password_hash(pid, password): data = struct.pack("> 8) & 0xFFFFF) if self.title_version is not None: req.headers["X-Nintendo-Application-Version"] = "%04X" %self.title_version if cert is not None: req.headers["X-Nintendo-Device-Cert"] = cert if auth is not None: req.headers["Authorization"] = "Bearer " + auth async def request(self, req): response = await http.request(self.url, req, self.context) if response.error(): logger.error("Account request returned status code %i\n%s", response.status_code, response.text) raise NNASError(response.status_code, response.xml) return response.xml async def login(self, username, password, password_type=None): req = http.HTTPRequest.post("/v1/api/oauth20/access_token/generate") self.prepare(req, cert=self.device_cert) req.form = { "grant_type": "password", "user_id": username, "password": password, } if password_type is not None: req.form["password_type"] = password_type response = await self.request(req) return OAuth20.parse(response) async def get_nex_token(self, access_token, game_server_id): req = http.HTTPRequest.get("/v1/api/provider/nex_token/@me") req.params = { "game_server_id": "%08X" %game_server_id } self.prepare(req, access_token) response = await self.request(req) return NexToken.parse(response) async def get_service_token(self, access_token, client_id): req = http.HTTPRequest.get("/v1/api/provider/service_token/@me") req.params = { "client_id": client_id } self.prepare(req, access_token) response = await self.request(req) return response["token"].text async def get_profile(self, access_token): req = http.HTTPRequest.get("/v1/api/people/@me/profile") self.prepare(req, access_token) response = await self.request(req) return Profile.parse(response) #The following functions can be used without logging in async def get_miis(self, pids): req = http.HTTPRequest.get("/v1/api/miis") req.params = { "pids": ",".join([str(pid) for pid in pids]) } self.prepare(req) response = await self.request(req) return [Mii.parse(mii) for mii in response] async def get_pids(self, nnids): req = http.HTTPRequest.get("/v1/api/admin/mapped_ids") req.params = { "input_type": "user_id", "output_type": "pid", "input": ",".join(nnids) } self.prepare(req) response = await self.request(req) return {id["in_id"].text: int(id["out_id"].text) for id in response if id["out_id"].text} async def get_nnids(self, pids): req = http.HTTPRequest.get("/v1/api/admin/mapped_ids") req.params = { "input_type": "pid", "output_type": "user_id", "input": ",".join([str(pid) for pid in pids]) } self.prepare(req) response = await self.request(req) return {int(id["in_id"].text): id["out_id"].text for id in response if id["out_id"].text} async def get_mii(self, pid): return (await self.get_miis([pid]))[0] async def get_pid(self, nnid): return (await self.get_pids([nnid]))[nnid] async def get_nnid(self, pid): return (await self.get_nnids([pid]))[pid] ================================================ FILE: nintendo/resources.py ================================================ from anynet import tls import importlib.resources def get(path): return importlib.resources.files("nintendo").joinpath(path) def open(path, mode="r", *, encoding="utf-8"): return get(path).open(mode, encoding=encoding) def read_bytes(path): return get(path).read_bytes() def certificate(name): data = read_bytes("files/cert/%s" %name) return tls.TLSCertificate.parse(data, tls.TYPE_DER) def private_key(name): data = read_bytes("files/cert/%s" %name) return tls.TLSPrivateKey.parse(data, tls.TYPE_DER) ================================================ FILE: nintendo/switch/__init__.py ================================================ from Crypto.Cipher import AES from Crypto.PublicKey import RSA from anynet import tls import hashlib import struct def load_keys(filename): with open(filename) as f: lines = f.readlines() keys = {} for line in lines: line = line.strip() if line: name, key = line.split("=") keys[name.strip()] = bytes.fromhex(key) return keys table = [ 0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401, 0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400 ] def crc16(data): hash = 0x55AA for byte in data: r = table[hash & 0xF] hash = (hash >> 4) ^ r ^ table[byte & 0xF] r = table[hash & 0xF] hash = (hash >> 4) ^ r ^ table[byte >> 4] return hash class ProdInfo: def __init__(self, keys, filename): self.keys = keys with open(filename, "rb") as f: self.data = f.read() def check(self, offset, size): end = offset + size - 2 expected = struct.unpack_from(" 0x800: raise ValueError("TLS certificate is too big") data = self.data[0xAE0 : 0xAE0 + length] hash = hashlib.sha256(data).digest() if hash != self.data[0x12E0 : 0x1300]: raise ValueError("SHA256 check failed") return tls.TLSCertificate.parse(data, tls.TYPE_DER) def get_tls_key(self): self.check(0x3AE0, 0x140) initial = self.data[0x3AE0 : 0x3AF0] cipher = self.data[0x3AF0 : 0x3BF0] kek = self.keys["ssl_rsa_kek_personalized"] if "ssl_rsa_kek_personalized" in self.keys else self.keys["ssl_rsa_kek"] aes = AES.new(kek, AES.MODE_CTR, nonce=b"", initial_value=initial) d = int.from_bytes(aes.decrypt(cipher), "big") pubkey = self.get_tls_cert().public_key() rsa = RSA.construct((pubkey.n, pubkey.e, d)) der = rsa.export_key("DER") return tls.TLSPrivateKey.parse(der, tls.TYPE_DER) ================================================ FILE: nintendo/switch/aauth.py ================================================ from Crypto.Util.Padding import pad from Crypto.Cipher import AES, PKCS1_OAEP from Crypto.PublicKey import RSA from Crypto.Hash import SHA256 from Crypto.Random import get_random_bytes from anynet import tls, http from nintendo import resources import struct import base64 import logging logger = logging.getLogger(__name__) RSA_MODULUS = int( "2903599220185509629948246004681271806662185201109683699434876284" "9306378942456577312580648895443616535088601867223713942187399041" "4854872772034425863387471719375473684104853507768450203982749294" "8967945831738920699512732919046223059402955082098739033920491649" "6879108565068863591362496844602988110766097564477545097467537357" "3183749964356608012071405755940871989007021731074728723470759285" "8155278592486462922448753256166071381157786436864032235809243318" "2591089355065715995209202752330511548478896205428626608544326862" "4782505679727111312756904637828438785474471375120478991907979820" "98870089661523253199182993983393803812441" ) RSA_EXPONENT = 65537 USER_AGENT = { 900: "libcurl (nnAccount; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 9.3.0.0; Add-on 9.3.0.0)", 901: "libcurl (nnAccount; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 9.3.0.0; Add-on 9.3.0.0)", 910: "libcurl (nnAccount; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 9.3.0.0; Add-on 9.3.0.0)", 920: "libcurl (nnAccount; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 9.3.0.0; Add-on 9.3.0.0)", 1000: "libcurl (nnAccount; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 10.4.0.0; Add-on 10.4.0.0)", 1001: "libcurl (nnAccount; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 10.4.0.0; Add-on 10.4.0.0)", 1002: "libcurl (nnAccount; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 10.4.0.0; Add-on 10.4.0.0)", 1003: "libcurl (nnAccount; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 10.4.0.0; Add-on 10.4.0.0)", 1004: "libcurl (nnAccount; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 10.4.0.0; Add-on 10.4.0.0)", 1010: "libcurl (nnAccount; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 10.4.0.0; Add-on 10.4.0.0)", 1011: "libcurl (nnAccount; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 10.4.0.0; Add-on 10.4.0.0)", 1020: "libcurl (nnAccount; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 10.4.0.0; Add-on 10.4.0.0)", 1100: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 11.4.0.0; Add-on 11.4.0.0)", 1101: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 11.4.0.0; Add-on 11.4.0.0)", 1200: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 12.3.0.0; Add-on 12.3.0.0)", 1201: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 12.3.0.0; Add-on 12.3.0.0)", 1202: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 12.3.0.0; Add-on 12.3.0.0)", 1203: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 12.3.0.0; Add-on 12.3.0.0)", 1210: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 12.3.0.0; Add-on 12.3.0.0)", 1300: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 13.3.0.0; Add-on 13.3.0.0)", 1310: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 13.4.0.0; Add-on 13.4.0.0)", 1320: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 13.4.0.0; Add-on 13.4.0.0)", 1321: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 13.4.0.0; Add-on 13.4.0.0)", 1400: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 14.3.0.0; Add-on 14.3.0.0)", 1410: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 14.3.0.0; Add-on 14.3.0.0)", 1411: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 14.3.0.0; Add-on 14.3.0.0)", 1412: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 14.3.0.0; Add-on 14.3.0.0)", 1500: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 15.3.0.0; Add-on 15.3.0.0)", 1501: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 15.3.0.0; Add-on 15.3.0.0)", 1600: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 16.2.0.0; Add-on 16.2.0.0)", 1601: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 16.2.0.0; Add-on 16.2.0.0)", 1602: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 16.2.0.0; Add-on 16.2.0.0)", 1603: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 16.2.0.0; Add-on 16.2.0.0)", 1610: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 16.2.0.0; Add-on 16.2.0.0)", 1700: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 17.5.0.0; Add-on 17.5.0.0)", 1701: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 17.5.0.0; Add-on 17.5.0.0)", 1800: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 18.3.0.0; Add-on 18.3.0.0)", 1801: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 18.3.0.0; Add-on 18.3.0.0)", 1810: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 18.3.0.0; Add-on 18.3.0.0)", 1900: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 19.3.0.0; Add-on 19.3.0.0)", 1901: "libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 19.3.0.0; Add-on 19.3.0.0)", 2000: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 20.5.4.0)", 2001: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 20.5.4.0)", 2010: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 20.5.4.0)", 2011: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 20.5.4.0)", 2015: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 20.5.4.0)", 2020: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 20.5.4.0)", 2030: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 20.5.4.0)", 2040: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 20.5.4.0)", 2050: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 20.5.4.0)", 2100: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 21.4.0.0)", 2101: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 21.4.0.0)", 2110: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 21.4.0.0)", 2120: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 21.4.0.0)", 2200: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 22.2.0.0)", 2210: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 22.2.0.0)", } API_VERSION = { 900: 3, 901: 3, 910: 3, 920: 3, 1000: 3, 1001: 3, 1002: 3, 1003: 3, 1004: 3, 1010: 3, 1011: 3, 1020: 3, 1100: 3, 1101: 3, 1200: 3, 1201: 3, 1202: 3, 1203: 3, 1210: 3, 1300: 3, 1310: 3, 1320: 3, 1321: 3, 1400: 3, 1410: 3, 1411: 3, 1412: 3, 1500: 4, 1501: 4, 1600: 4, 1601: 4, 1602: 4, 1603: 4, 1610: 4, 1700: 4, 1701: 4, 1800: 4, 1801: 4, 1810: 4, 1900: 5, 1901: 5, 2000: 5, 2001: 5, 2010: 5, 2011: 5, 2015: 5, 2020: 5, 2030: 5, 2040: 5, 2050: 5, 2100: 5, 2101: 5, 2110: 5, 2120: 5, 2200: 5, 2210: 5, } LATEST_VERSION = 2210 class AAuthError(Exception): DEVICE_TOKEN_EXPIRED = 103 ROMID_BANNED = 105 UNAUTHORIZED_APPLICATION = 106 SERVICE_CLOSED = 109 APPLICATION_UPDATE_REQUIRED = 111 INTERNAL_SERVER_ERROR = 112 GENERIC = 118 REGION_MISMATCH = 121 def __init__(self, response): self.response = response self.code = int(response.json["errors"][0]["code"]) self.message = response.json["errors"][0]["message"] def __str__(self): return self.message class AAuthClient: def __init__(self): self.request_callback = http.request self.context = tls.TLSContext() self.context_overridden = False self.host_overridden = False self.power_state = "FA" self.set_system_version(LATEST_VERSION) def set_request_callback(self, callback): self.request_callback = callback def set_context(self, context): self.context = context self.context_overridden = True def set_certificate(self, cert, key): self.context.set_certificate(cert, key) def set_host(self, host): self.host = host self.host_overridden = True def set_power_state(self, state): self.power_state = state def set_system_version(self, version): if version not in USER_AGENT: raise ValueError("Unknown system version") self.system_version = version self.user_agent = USER_AGENT[version] self.api_version = API_VERSION[version] if version >= 2000: caname = "Nintendo_Root_CA_G4.der" host = "aauth.hac.lp1.ndas.srv.nintendo.net" else: caname = "Nintendo_CA_G3.der" host = "aauth-lp1.ndas.srv.nintendo.net" if not self.context_overridden: ca = resources.certificate(caname) self.context.set_authority(ca) if not self.host_overridden: self.host = host async def request(self, req, use_power_state): if self.system_version < 1800: req.headers["Host"] = self.host req.headers["User-Agent"] = self.user_agent req.headers["Accept"] = "*/*" if use_power_state: req.headers["X-Nintendo-PowerState"] = self.power_state req.headers["Content-Length"] = 0 req.headers["Content-Type"] = "application/x-www-form-urlencoded" elif self.system_version < 2000: req.headers["Host"] = self.host req.headers["Accept"] = "*/*" req.headers["Content-Type"] = "application/x-www-form-urlencoded" if use_power_state: req.headers["X-Nintendo-PowerState"] = self.power_state req.headers["Content-Length"] = 0 else: req.headers["Host"] = self.host req.headers["Accept"] = "*/*" req.headers["User-Agent"] = self.user_agent req.headers["Content-Type"] = "application/x-www-form-urlencoded" if use_power_state: req.headers["X-Nintendo-PowerState"] = self.power_state req.headers["Content-Length"] = 0 response = await self.request_callback(self.host, req, self.context) if response.json and "errors" in response.json: logger.error("AAuth server returned errors:") for error in response.json["errors"]: logger.error(" (%s) %s", error["code"], error["message"]) raise AAuthError(response) response.raise_if_error() return response def verify_ticket(self, ticket, title_id): # Verify ticket, in case someone accidentally # provides the wrong ticket if len(ticket) != 0x2C0: raise ValueError("Ticket has unexpected size") if struct.unpack_from("Q", ticket, 0x2A0)[0] != title_id: raise ValueError("Ticket has different title id") if struct.unpack_from(">Q", ticket, 0x2A8)[0] != ticket[0x285]: raise ValueError("Ticket has inconsistent master key revision") def verify_token(self, token): # Just a basic check, to make sure that people do not # accidentally pass a ticket instead of a JWT if not isinstance(token, str) or token.count(".") != 2: raise ValueError("Cert must contain a valid JWT") async def get_time(self): req = http.HTTPRequest.get("/v1/time") req.headers["Host"] = self.host req.headers["Accept"] = "*/*" response = await http.request(self.host, req, self.context) response.raise_if_error() time = int(response.headers["X-NINTENDO-UNIXTIME"]) ip = response.headers["X-NINTENDO-GLOBAL-IP"] return time, ip async def challenge(self, device_token): param_name = "&device_auth_token" if self.system_version < 1800 else "device_auth_token" req = http.HTTPRequest.post("/v%i/challenge" %self.api_version) req.rawform = { param_name: device_token } response = await self.request(req, False) return response.json # Warning: do not use auth_nocert on a production server. # It will immediately ban your Switch. async def auth_nocert(self, title_id, title_version, device_token): auth_type = "media_type" if self.api_version < 5 else "auth_type" req = http.HTTPRequest.post("/v%i/application_auth_token" %self.api_version) req.form = { "application_id": "%016x" %title_id, "application_version": "%08x" %title_version, "device_auth_token": device_token, auth_type: "NO_CERT" } response = await self.request(req, True) return response.json async def auth_system(self, title_id, title_version, device_token): auth_type = "media_type" if self.api_version < 5 else "auth_type" req = http.HTTPRequest.post("/v%i/application_auth_token" %self.api_version) req.form = { "application_id": "%016x" %title_id, "application_version": "%08x" %title_version, "device_auth_token": device_token, auth_type: "SYSTEM" } response = await self.request(req, True) return response.json async def auth_digital(self, title_id, title_version, device_token, cert): auth_type = "media_type" if self.api_version < 5 else "auth_type" req = http.HTTPRequest.post("/v%i/application_auth_token" %self.api_version) req.form = { "application_id": "%016x" %title_id, "application_version": "%08x" %title_version, "device_auth_token": device_token, auth_type: "DIGITAL" } if self.api_version == 3: self.verify_ticket(cert, title_id) plain_key = get_random_bytes(16) aes = AES.new(plain_key, AES.MODE_CBC, iv=bytes(16)) encrypted_ticket = aes.encrypt(pad(cert, 16)) rsa_key = RSA.construct((RSA_MODULUS, RSA_EXPONENT)) rsa = PKCS1_OAEP.new(rsa_key, SHA256) encrypted_key = rsa.encrypt(plain_key) req.form["cert"] = base64.b64encode(encrypted_ticket, b"-_").decode().rstrip("=") req.form["cert_key"] = base64.b64encode(encrypted_key, b"-_").decode().rstrip("=") elif self.api_version >= 4: self.verify_token(cert) req.form["cert"] = cert response = await self.request(req, True) return response.json async def auth_gamecard(self, title_id, title_version, device_token, cert, gvt, challenge=None, challenge_src=None): auth_type = "media_type" if self.api_version < 5 else "auth_type" req = http.HTTPRequest.post("/v%i/application_auth_token" %self.api_version) req.form = { "application_id": "%016x" %title_id, "application_version": "%08x" %title_version, "device_auth_token": device_token, auth_type: "GAMECARD", "gvt": base64.b64encode(gvt, b"-_").decode().rstrip("="), "cert": base64.b64encode(cert, b"-_").decode().rstrip("=") } if self.api_version >= 5: req.form["challenge"] = challenge req.form["challenge_src"] = challenge_src response = await self.request(req, True) return response.json ================================================ FILE: nintendo/switch/atumn.py ================================================ from anynet import tls, http from nintendo import resources from nintendo.switch import common import logging logger = logging.getLogger(__name__) USER_AGENT = "NintendoSDK Firmware/%s (platform:NX; did:%016x; eid:lp1)" LATEST_VERSION = 2210 class AtumnClient: def __init__(self, device_id): self.device_id = device_id self.request_callback = http.request ca = resources.certificate("Nintendo_Class_2_CA_G3.der") self.context = tls.TLSContext() self.context.set_authority(ca) self.host = "atumn.hac.lp1.d4c.nintendo.net" self.user_agent = USER_AGENT %(common.FIRMWARE_VERSIONS[LATEST_VERSION], self.device_id) def set_request_callback(self, callback): self.request_callback = callback def set_context(self, context): self.context = context def set_certificate(self, cert, key): self.context.set_certificate(cert, key) def set_host(self, host): self.host = host def set_system_version(self, version): if version not in common.FIRMWARE_VERSIONS: raise ValueError("Unknown system version: %i" %version) self.user_agent = USER_AGENT %(common.FIRMWARE_VERSIONS[version], self.device_id) async def request(self, req): req.headers["Host"] = self.host req.headers["Accept"] = "*/*" req.headers["User-Agent"] = self.user_agent response = await self.request_callback(self.host, req, self.context) response.raise_if_error() return response async def download_content_metadata(self, title_id, title_version, *, system_update=False): content_type = "s" if system_update else "a" req = http.HTTPRequest.head("/t/%c/%016x/%i" %(content_type, title_id, title_version)) req.params = { "device_id": "%016x" %self.device_id } response = await self.request(req) content_id = response.headers["X-Nintendo-Content-ID"] req = http.HTTPRequest.get("/c/%s/%s" %(content_type, content_id)) response = await self.request(req) return response.body async def download_content(self, content_id): req = http.HTTPRequest.get("/c/c/%s" %content_id) response = await self.request(req) return response.body ================================================ FILE: nintendo/switch/baas.py ================================================ from anynet import tls, http import json import logging logger = logging.getLogger(__name__) MODULE_ACCOUNT = "nnAccount" MODULE_FRIENDS = "nnFriends" USER_AGENT = { 900: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 9.3.0.0; Add-on 9.3.0.0)", 901: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 9.3.0.0; Add-on 9.3.0.0)", 910: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 9.3.0.0; Add-on 9.3.0.0)", 920: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 9.3.0.0; Add-on 9.3.0.0)", 1000: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 10.4.0.0; Add-on 10.4.0.0)", 1001: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 10.4.0.0; Add-on 10.4.0.0)", 1002: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 10.4.0.0; Add-on 10.4.0.0)", 1003: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 10.4.0.0; Add-on 10.4.0.0)", 1004: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 10.4.0.0; Add-on 10.4.0.0)", 1010: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 10.4.0.0; Add-on 10.4.0.0)", 1011: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 10.4.0.0; Add-on 10.4.0.0)", 1020: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 10.4.0.0; Add-on 10.4.0.0)", 1100: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 11.4.0.0; Add-on 11.4.0.0)", 1101: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 11.4.0.0; Add-on 11.4.0.0)", 1200: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 12.3.0.0; Add-on 12.3.0.0)", 1201: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 12.3.0.0; Add-on 12.3.0.0)", 1202: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 12.3.0.0; Add-on 12.3.0.0)", 1203: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 12.3.0.0; Add-on 12.3.0.0)", 1210: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 12.3.0.0; Add-on 12.3.0.0)", 1300: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 13.3.0.0; Add-on 13.3.0.0)", 1310: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 13.4.0.0; Add-on 13.4.0.0)", 1320: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 13.4.0.0; Add-on 13.4.0.0)", 1321: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 13.4.0.0; Add-on 13.4.0.0)", 1400: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 14.3.0.0; Add-on 14.3.0.0)", 1410: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 14.3.0.0; Add-on 14.3.0.0)", 1411: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 14.3.0.0; Add-on 14.3.0.0)", 1412: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 14.3.0.0; Add-on 14.3.0.0)", 1500: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 15.3.0.0; Add-on 15.3.0.0)", 1501: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 15.3.0.0; Add-on 15.3.0.0)", 1600: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 16.2.0.0; Add-on 16.2.0.0)", 1601: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 16.2.0.0; Add-on 16.2.0.0)", 1602: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 16.2.0.0; Add-on 16.2.0.0)", 1603: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 16.2.0.0; Add-on 16.2.0.0)", 1610: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 16.2.0.0; Add-on 16.2.0.0)", 1700: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 17.5.0.0; Add-on 17.5.0.0)", 1701: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 17.5.0.0; Add-on 17.5.0.0)", 1800: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 18.3.0.0; Add-on 18.3.0.0)", 1801: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 18.3.0.0; Add-on 18.3.0.0)", 1810: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 18.3.0.0; Add-on 18.3.0.0)", 1900: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 19.3.0.0; Add-on 19.3.0.0)", 1901: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 19.3.0.0; Add-on 19.3.0.0)", 2000: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 20.5.4.0; Add-on 20.5.4.0)", 2001: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 20.5.4.0; Add-on 20.5.4.0)", 2010: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 20.5.4.0; Add-on 20.5.4.0)", 2011: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 20.5.4.0; Add-on 20.5.4.0)", 2015: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 20.5.4.0; Add-on 20.5.4.0)", 2020: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 20.5.4.0; Add-on 20.5.4.0)", 2030: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 20.5.4.0; Add-on 20.5.4.0)", 2040: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 20.5.4.0; Add-on 20.5.4.0)", 2050: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 20.5.4.0; Add-on 20.5.4.0)", 2100: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 21.4.0.0; Add-on 21.4.0.0)", 2101: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 21.4.0.0; Add-on 21.4.0.0)", 2110: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 21.4.0.0; Add-on 21.4.0.0)", 2120: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 21.4.0.0; Add-on 21.4.0.0)", 2220: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 22.2.0.0; Add-on 22.2.0.0)", 2210: "libcurl (%s; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 22.2.0.0; Add-on 22.2.0.0)", } LATEST_VERSION = 2210 class PresenceState: INACTIVE = "INACTIVE" ONLINE = "ONLINE" PLAYING = "PLAYING" class BAASError(Exception): def __init__(self, response): self.response = response self.type = response.json["type"] self.name = response.json["errorCode"] self.title = response.json["title"] self.detail = response.json["detail"] self.status = response.json["status"] self.instance = response.json["instance"] def __str__(self): return self.title class BAASClient: def __init__(self): self.request_callback = http.request self.context = tls.TLSContext() self.host = None self.power_state = "FA" self.system_version = LATEST_VERSION self.user_agent = USER_AGENT[LATEST_VERSION] def set_request_callback(self, callback): self.request_callback = callback def set_context(self, context): self.context = context def set_certificate(self, cert, key): self.context.set_certificate(cert, key) def set_host(self, host): self.host = host def set_power_state(self, state): self.power_state = state def set_system_version(self, version): if version not in USER_AGENT: raise ValueError("Unknown system version") self.system_version = version self.user_agent = USER_AGENT[version] def get_host(self, module): if self.host: return self.host if module == MODULE_ACCOUNT and self.system_version >= 2100: return "m-lp1.baas.nintendo.com" return "e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com" async def request(self, req, token, module, *, use_power_state=False): # This is somewhat complicated because we want to # put the headers in the correct order content_type = "application/x-www-form-urlencoded" if req.json is not None: content_type = "application/json-patch+json" if req.method == "PATCH" else "application/json" req.headers["Host"] = self.host if module == MODULE_ACCOUNT and self.system_version >= 2100: req.headers["Accept"] = "*/*" req.headers["User-Agent"] = self.user_agent %module if req.method != "GET": req.headers["Content-Type"] = content_type if token: req.headers["Authorization"] = "Bearer " + token if use_power_state: req.headers["X-Nintendo-PowerState"] = self.power_state if req.method != "GET": req.headers["Content-Length"] = 0 else: req.headers["User-Agent"] = self.user_agent %module req.headers["Accept"] = "*/*" if module == MODULE_FRIENDS and req.json is not None: req.headers["Content-Type"] = content_type if token: req.headers["Authorization"] = "Bearer " + token if use_power_state: req.headers["X-Nintendo-PowerState"] = self.power_state if req.method != "GET": if req.json is None: req.headers["Content-Length"] = 0 req.headers["Content-Type"] = content_type else: if module != MODULE_FRIENDS: req.headers["Content-Type"] = content_type req.headers["Content-Length"] = 0 response = await self.request_callback(self.host, req, self.context) if response.json and "errorCode" in response.json: logger.warning("BAAS server returned an error: %s" %response.json) raise BAASError(response) response.raise_if_error() return response async def authenticate(self, device_token, penne_id=None): req = http.HTTPRequest.post("/1.0.0/application/token") req.form = { "grantType": "public_client", "assertion": device_token } if self.system_version >= 1900 and penne_id is not None: req.form["penneId"] = penne_id response = await self.request(req, None, MODULE_ACCOUNT, use_power_state=True) return response.json async def login(self, id, password, access_token, app_token=None, na_country=None, skip_verification=False, is_persistent=True): req = http.HTTPRequest.post("/1.0.0/login") req.form = { "id": "%016x" %id, "password": password } if app_token: req.form["appAuthNToken"] = app_token if self.system_version >= 1800: if na_country is None: raise ValueError("na_country parameter is required for system version 18.0.0 and later") req.form["naCountry"] = na_country if self.system_version >= 2000: req.form["isPersistent"] = "true" if is_persistent else "false" if skip_verification: req.form["skipOp2Verification"] = "1" response = await self.request(req, access_token, MODULE_ACCOUNT, use_power_state=True) return response.json async def register(self, access_token): req = http.HTTPRequest.post("/1.0.0/users") response = await self.request(req, access_token, MODULE_ACCOUNT) return response.json async def update_presence(self, user_id, device_account_id, access_token, state, title_id, presence_group_id, app_fields={}, acd_index=0): app_fields = json.dumps(app_fields, separators=(",", ":")) req = http.HTTPRequest.patch("/1.0.0/users/%016x/device_accounts/%016x" %(user_id, device_account_id)) req.json = [ {"op": "replace", "path": "/presence/state", "value": state}, {"op": "add", "path": "/presence/extras/friends/appField", "value": app_fields}, {"op": "add", "path": "/presence/extras/friends/appInfo:appId", "value": "%016x" %title_id} ] if self.system_version >= 1900: req.json.append({"op": "add", "path": "/presence/extras/friends/appInfo:acdIndex", "value": acd_index}) req.json.append({"op": "add", "path": "/presence/extras/friends/appInfo:presenceGroupId", "value": "%016x" %presence_group_id}) response = await self.request(req, access_token, MODULE_FRIENDS) return response.json async def get_friends(self, user_id, access_token, count=300): req = http.HTTPRequest.get("/2.0.0/users/%016x/friends" %user_id) req.params = {"count": count} response = await self.request(req, access_token, MODULE_FRIENDS) return response.json ================================================ FILE: nintendo/switch/common.py ================================================ FIRMWARE_VERSIONS = { 900: "9.0.0-4.0", 901: "9.0.1-1.0", 910: "9.1.0-1.0", 920: "9.2.0-1.0", 1000: "10.0.0-6.0", 1001: "10.0.1-1.0", 1002: "10.0.2-1.0", 1003: "10.0.3-1.0", 1004: "10.0.3-1.0", 1010: "10.1.0-1.0", 1011: "10.1.0-1.0", 1020: "10.2.0-1.0", 1100: "11.0.0-5.0", 1101: "11.0.1-1.0", 1200: "12.0.0-4.0", 1201: "12.0.1-1.0", 1202: "12.0.2-1.0", 1203: "12.0.3-1.0", 1210: "12.1.0-1.0", 1300: "13.0.0-4.0", 1310: "13.1.0-1.2", 1320: "13.2.0-1.0", 1321: "13.2.1-1.0", 1400: "14.0.0-4.0", 1410: "14.1.0-1.0", 1411: "14.1.1-1.0", 1412: "14.1.2-1.0", 1500: "15.0.0-4.0", 1501: "15.0.1-1.0", 1600: "16.0.0-3.0", 1601: "16.0.1-1.0", 1602: "16.0.2-1.0", 1603: "16.0.3-1.0", 1610: "16.1.0-1.0", 1700: "17.0.0-6.0", 1701: "17.0.1-1.0", 1800: "18.0.0-4.0", 1801: "18.0.1-1.0", 1810: "18.1.0-1.0", 1900: "19.0.0-4.0", 1901: "19.0.1-1.0", 2000: "20.0.0-9.0", 2001: "20.0.1-1.0", 2010: "20.1.0-1.0", 2011: "20.1.1-1.0", 2015: "20.1.5-1.0", 2020: "20.2.0-1.0", 2030: "20.3.0-1.0", 2040: "20.4.0-1.0", 2050: "20.5.0-1.0", 2100: "21.0.0-5.0", 2101: "21.0.1-1.0", 2110: "21.1.0-1.0", 2120: "21.2.0-1.0", 2200: "22.0.0-3.0", 2210: "22.1.0-1.0", } ================================================ FILE: nintendo/switch/dauth.py ================================================ from Crypto.Hash import CMAC from Crypto.Cipher import AES from anynet import tls, http from nintendo import resources import base64 import json import time import logging logger = logging.getLogger(__name__) DAUTH_SOURCE = bytes.fromhex("8be45abcf987021523ca4f5e2300dbf0") SYSTEM_VERSION_DIGEST = { 900: "CusHY#00090000#-80vwBkUjWLb5Kpb_cnuTjBZ0rHwZHhN7R1-vg0Ti5c=", 901: "CusHY#00090001#qVDSOCehwMDCHyDnkXiTSJ1wEJZHtpRV_CLMKgD-fSw=", 910: "CusHY#00090100#vIPNrRbf30SoU8ZJ6uGklMqKAkyjHfdE9m6yLFeChkE=", 920: "CusHY#00090200#Uxxmc8gYnfMqxzdZdygZ_OrKo98O7QA65s_EkZnGsDo=", 1000: "CusHY#000a0000#EmdxOnZjZ9Ihf3Zskt_48pYgowAUeeJccU6tCBIweEc=", 1001: "CusHY#000a0001#JEuSEdid24qqHqQzfW1tuNsCGcCk-86gcPq0I7M1x18=", 1002: "CusHY#000a0002#BTOGo0giC7bbrNoi8JEm-FBzmXb2Kgpq4K3OzQrD5l8=", 1003: "CusHY#000a0003#4mBbTFYnE0Rtmh8NLCVq61rbvx0kJPQUxXkDpwj0V84=", 1004: "CusHY#000a0003#4mBbTFYnE0Rtmh8NLCVq61rbvx0kJPQUxXkDpwj0V84=", 1010: "CusHY#000a0100#Vlw9dIEqjxE2F5jDOQPYWXs2p7wIGyDYWXXIyQGdxcE=", 1011: "CusHY#000a0100#Vlw9dIEqjxE2F5jDOQPYWXs2p7wIGyDYWXXIyQGdxcE=", 1020: "CusHY#000a0200#90k0dE_eO7hRcs6ByTZMvgUm4lhEoqAlik96WkznQcQ=", 1100: "CusHY#000b0000#VyA0fsWi6ZBEOzVsseXIcEfFLqQMgW0tWzN2oJ7viqk=", 1101: "CusHY#000b0001#iI0rZ0Q2dg3Evhd-8GoYmp-KTE8malKe0GOJgXa-XG8=", 1200: "CusHY#000c0000#C-BynYNPXdQJNBZjx02Hizi8lRUSIKLwPGa5p8EY1uo=", 1201: "CusHY#000c0001#YXsU5FTbkUh18QH27L3woGqw5n1gIDpMGbPXM8oACzY=", 1202: "CusHY#000c0002#6tB3UVnmvT_nsNBMPSD-K1oe0IA1cYvYDyqDCjy2W_I=", 1203: "CusHY#000c0003#E8Ph6vISWsJtN0E3hsfVRoZMG1Qqkc-qGRlAp-Bs2SI=", 1210: "CusHY#000c0100#Hzs8Gtp6yKgGKMb732-5Q-NvbQcHCgBh_LQrrpg0bIs=", 1300: "CusHY#000d0000#r1xneESd4PiTRYIhVIl0bK1ST5L5BUmv_uGPLqc4PPo=", 1310: "CusHY#000d0100#plps6S3C43QHhkI2oNvYIFjNxQjTcLdUX2_biEI5w2w=", 1320: "CusHY#000d0200#JFVNVuG9x3V5tRshdD9FdJjgHOmzsrgXHocEPvW5eMM=", 1321: "CusHY#000d0201#V1i7M7oEhkDaH1lcGlHhGAnyHONMAnTAA6pGdZ7MFqc=", 1400: "CusHY#000e0000#35hWb15SBXTnbUfTMLBz9sCnfheuRGis0OTZqa7l8yw=", 1410: "CusHY#000e0100#ctIxSPR4jenzQNGc6y4zXIvzvF75ty53jN0T15Rjtmk=", 1411: "CusHY#000e0101#uTt4IVydkYqwYArOFR3BzOCmw0MkEeF_tZxHENYDh4E=", 1412: "CusHY#000e0102#jHk6_VwXVPPl3ijRZ5jRy5MIAcUW_Q2uFdfJ0vrjhCA=", 1500: "CusHY#000f0000#MJE7we0zvVhAnXN9uCU7fQAM7GiqGHpR5ECuC9G_nuU=", 1501: "CusHY#000f0001#TMqizZGvUaBZApmHHQE0Uo7vQ6xWuQxZ8JH87_HnnqI=", 1600: "CusHY#00100000#k_VrW8iX7QgupPlYZYhg3dLEVDhqGN_iXW5Mm0VYEvQ=", 1601: "CusHY#00100001#qHay53MkzVLOUU_Iy7_kyPlUMnaoi7HXCAmESYTft_c=", 1602: "CusHY#00100002#qjeCnaxVt5NjGjxosJOMVw-ZyR219B3qgAB3YtSil6g=", 1603: "CusHY#00100003#Lis4m_Z4pXlDAaBBxeRO66_glyu92IAf2-dHKNxYAJs=", 1610: "CusHY#00100100#3kOLHmbuMWa-kHN-SMtCkgNvwdwBHIb2b4f60BNNmrw=", 1700: "CusHY#00110000#ntMZ00Jmb7Rdu18Fy1FPZo7RO3h_MYIqxozbQQDcVaA=", 1701: "CusHY#00110001#7CmXEDXEN8wnVu-e7WY6Cv5CvmzjuG6EnKEkf1_jaC8=", 1800: "CusHY#00120000#U531L4Si9RbhOVeyVppe18WHkJ0k4_KzrNtygsekMNo=", 1801: "CusHY#00120001#chuxR_O35JFyJq7dIlT8yP1A-j1yBcF-iU4iVDjHt9g=", 1810: "CusHY#00120100#7pfwz-8raijuW2lv4UOi4Hukp-DuY898HEK6hEYUjSM=", 1900: "CusHY#00130000#x2jf5al2EkqJmdvmnTFaL6s4ic7X68N0dY9jnwwcL98=", 1901: "CusHY#00130001#6I1eeoSqDdjA7eXPDrsWBbdM-VxVhveQYiG1oNfNSt0=", } SYSTEM_VERSION_HEX = { 2000: "7147e1386c9b6c15d8f14e6ed68c4b9a7f28fb9b", 2001: "0b2540e5cd7498dd61f6caeca5136c73d9b1d21a", 2010: "fa9b24a1d97b9adf5fe462f7f0ee97e6ed6294d0", 2011: "9ffad64d79dd150490201461bdf66c8db963f57d", 2015: "0605c36a7aa2535fb8989a0d133a0b96b0d97a12", 2020: "ad939aa8ed828aa87f8ca9c6231bc76697298b8d", 2030: "c6061464f68281807f4780ae737392516d4813c7", 2040: "cc744ded0c0eb7b0a71917a97ec00926427cd652", 2050: "c7f472f9b64b7b0cba46a25e6a610f70613a4792", 2100: "f6b2425b6888a66590db104fc734891696e0ecb3", 2101: "066a75e6fab7316de34b88b60d229a0b2729e421", 2110: "0d7a6334ddc3d637f69ec3976b17a260efd68fd4", 2120: "ff8d6ddacae7c7fd1287e22c3c88bb961acb290c", 2200: "da42070c4ad25840c9ee25344bde9d0a8584f5a9", 2210: "1927752d2a83389d84e6d31c4c91710e04fa69aa", } USER_AGENT = { 900: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 9.3.0.0)", 901: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 9.3.0.0)", 910: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 9.3.0.0)", 920: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 9.3.0.0)", 1000: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 10.4.0.0)", 1001: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 10.4.0.0)", 1002: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 10.4.0.0)", 1003: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 10.4.0.0)", 1004: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 10.4.0.0)", 1010: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 10.4.0.0)", 1011: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 10.4.0.0)", 1020: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 10.4.0.0)", 1100: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 11.4.0.0)", 1101: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 11.4.0.0)", 1200: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 12.3.0.0)", 1201: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 12.3.0.0)", 1202: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 12.3.0.0)", 1203: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 12.3.0.0)", 1210: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 12.3.0.0)", 1300: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 13.3.0.0)", 1310: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 13.4.0.0)", 1320: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 13.4.0.0)", 1321: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 13.4.0.0)", 1400: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 14.3.0.0)", 1410: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 14.3.0.0)", 1411: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 14.3.0.0)", 1412: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 14.3.0.0)", 1500: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 15.3.0.0)", 1501: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 15.3.0.0)", 1600: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 16.2.0.0)", 1601: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 16.2.0.0)", 1602: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 16.2.0.0)", 1603: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 16.2.0.0)", 1610: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 16.2.0.0)", 1700: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 17.5.0.0)", 1701: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 17.5.0.0)", 1800: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 18.3.0.0)", 1801: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 18.3.0.0)", 1810: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 18.3.0.0)", 1900: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 19.3.0.0)", 1901: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 19.3.0.0)", 2000: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 20.5.4.0)", 2001: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 20.5.4.0)", 2010: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 20.5.4.0)", 2011: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 20.5.4.0)", 2015: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 20.5.4.0)", 2020: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 20.5.4.0)", 2030: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 20.5.4.0)", 2040: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 20.5.4.0)", 2050: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 20.5.4.0)", 2100: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 21.4.0.0)", 2101: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 21.4.0.0)", 2110: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 21.4.0.0)", 2120: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 21.4.0.0)", 2200: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 22.2.0.0)", 2210: "libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 22.2.0.0)", } KEY_GENERATION = { 900: 10, 901: 10, 910: 11, 920: 11, 1000: 11, 1001: 11, 1002: 11, 1003: 11, 1004: 11, 1010: 11, 1011: 11, 1020: 11, 1100: 11, 1101: 11, 1200: 11, 1201: 11, 1202: 11, 1203: 11, 1210: 11, 1300: 13, 1310: 13, 1320: 13, 1321: 13, 1400: 14, 1410: 14, 1411: 14, 1412: 14, 1500: 15, 1501: 15, 1600: 16, 1601: 16, 1602: 16, 1603: 16, 1610: 16, 1700: 17, 1701: 17, 1800: 17, 1801: 17, 1810: 17, 1900: 19, 1901: 19, 2000: 20, 2001: 20, 2010: 20, 2011: 20, 2015: 20, 2020: 20, 2030: 20, 2040: 20, 2050: 20, 2100: 21, 2101: 21, 2110: 21, 2120: 21, 2200: 22, 2210: 22, } API_VERSION = { 900: 6, 901: 6, 910: 6, 920: 6, 1000: 6, 1001: 6, 1002: 6, 1003: 6, 1004: 6, 1010: 6, 1011: 6, 1020: 6, 1100: 6, 1101: 6, 1200: 6, 1201: 6, 1202: 6, 1203: 6, 1210: 6, 1300: 7, 1310: 7, 1320: 7, 1321: 7, 1400: 7, 1410: 7, 1411: 7, 1412: 7, 1500: 7, 1501: 7, 1600: 7, 1601: 7, 1602: 7, 1603: 7, 1610: 7, 1700: 7, 1701: 7, 1800: 7, 1801: 7, 1810: 7, 1900: 7, 1901: 7, 2000: 8, 2001: 8, 2010: 8, 2011: 8, 2015: 8, 2020: 8, 2030: 8, 2040: 8, 2050: 8, 2100: 8, 2101: 8, 2110: 8, 2120: 8, 2200: 8, 2210: 8, } LATEST_VERSION = 2210 CLIENT_ID_SCSI = 0x146C8AC7B8A0DB52 CLIENT_ID_ER = 0x16E96F76850156D1 CLIENT_ID_ATUM = 0x3117B250CAB38F45 CLIENT_ID_ESHOP = 0x41F4A6491028E3C4 CLIENT_ID_BCAT = 0x67BF9945B45248C6 CLIENT_ID_SATA = 0x6AC5A6873FE5F68C CLIENT_ID_ACCOUNT_APPLET = 0x75FE236362FF5F8B CLIENT_ID_ACCOUNT = 0x81333C548B2E876D CLIENT_ID_NPNS = 0x83B72B05DC3278D7 CLIENT_ID_BAAS = 0x8F849B5D34778D8E CLIENT_ID_BEACH = 0x93AF0ACB26258DE9 CLIENT_ID_SPROFILE = 0xBAD8156F44AC935A CLIENT_ID_DRAGONS = 0xD5B6CAC2C1514C56 CLIENT_ID_SCSI_POLICY = 0xD98185ACB55994B4 CLIENT_ID_PCTL = 0xDC656EA03B63CF68 CLIENT_ID_PREPO = 0xDF51C436BC01C437 CLIENT_ID_PENNE = 0xE58171FE439390CE PRELOADED_DEVICE_TOKENS = [ CLIENT_ID_BAAS, CLIENT_ID_PCTL, CLIENT_ID_BEACH, CLIENT_ID_PREPO, CLIENT_ID_ER, CLIENT_ID_PENNE, CLIENT_ID_ACCOUNT, CLIENT_ID_ACCOUNT_APPLET, CLIENT_ID_SCSI, CLIENT_ID_DRAGONS, CLIENT_ID_SPROFILE ] PRELOADED_EDGE_TOKENS = [ (CLIENT_ID_BEACH, "akamai"), (CLIENT_ID_BCAT, "akamai"), (CLIENT_ID_SCSI_POLICY, "akamai"), (CLIENT_ID_SCSI, "akamai"), (CLIENT_ID_ESHOP, "akamai"), (CLIENT_ID_ATUM, "akamai"), (CLIENT_ID_ATUM, "fastly") ] class DAuthError(Exception): UNAUTHORIZED_DEVICE = 4 SYSTEM_UPDATE_REQUIRED = 7 BANNED_DEVICE = 8 INTERNAL_SERVER_ERROR = 9 GENERIC = 14 CHALLENGE_EXPIRED = 15 WRONG_MAC = 16 BROKEN_DEVICE = 17 def __init__(self, response, error): self.response = response self.code = int(error["code"]) self.message = error["message"] def __str__(self): return self.message class DAuthClient: def __init__(self, keys): self.keys = keys self.request_callback = http.request ca = resources.certificate("Nintendo_CA_G3.der") self.context = tls.TLSContext() self.context.set_authority(ca) self.host = "dauth-lp1.ndas.srv.nintendo.net" self.power_state = "FA" self.region = 1 self.system_version = LATEST_VERSION self.user_agent = USER_AGENT[self.system_version] self.system_version_hash = SYSTEM_VERSION_HEX[self.system_version] self.key_generation = KEY_GENERATION[self.system_version] self.api_version = API_VERSION[self.system_version] def set_request_callback(self, callback): self.request_callback = callback def set_context(self, context): self.context = context def set_certificate(self, cert, key): self.context.set_certificate(cert, key) def set_power_state(self, state): self.power_state = state def set_platform_region(self, region): self.region = region def set_host(self, host): self.host = host def set_system_version(self, version): if version not in USER_AGENT: raise ValueError("Unknown system version: %i" %version) self.system_version = version self.user_agent = USER_AGENT[version] self.key_generation = KEY_GENERATION[version] self.api_version = API_VERSION[version] if self.api_version < 8: self.system_version_hash = SYSTEM_VERSION_DIGEST[version] else: self.system_version_hash = SYSTEM_VERSION_HEX[version] async def request(self, req): if self.system_version < 1800: req.headers["Host"] = self.host req.headers["User-Agent"] = self.user_agent req.headers["Accept"] = "*/*" req.headers["X-Nintendo-PowerState"] = self.power_state req.headers["Content-Length"] = 0 req.headers["Content-Type"] = "application/x-www-form-urlencoded" elif self.system_version < 2000: req.headers["Host"] = self.host req.headers["Accept"] = "*/*" req.headers["Content-Type"] = "application/x-www-form-urlencoded" req.headers["X-Nintendo-PowerState"] = self.power_state req.headers["Content-Length"] = 0 else: req.headers["Host"] = self.host req.headers["Accept"] = "*/*" req.headers["User-Agent"] = self.user_agent if req.json: req.headers["Content-Type"] = "application/json" else: req.headers["Content-Type"] = "application/x-www-form-urlencoded" req.headers["X-Nintendo-PowerState"] = self.power_state req.headers["Content-Length"] = 0 response = await self.request_callback(self.host, req, self.context) if response.json and "errors" in response.json: logger.error("DAuth server returned errors:") for error in response.json["errors"]: logger.error(" (%s) %s", error["code"], error["message"]) raise DAuthError(response, response.json["errors"][0]) response.raise_if_error() return response async def challenge(self): req = http.HTTPRequest.post("/v%i/challenge" %self.api_version) req.form = { "key_generation": self.key_generation } response = await self.request(req) return response.json async def request_token(self, client_id, vendor_id="akamai", *, edge_token): # This is a generic method to reduce code duplication between device_token and edge_token # Use one of the preload_* functions on system version 20.0.0 and later, to mimic the # behavior of a real Switch. if self.system_version >= 2000: raise ValueError("This method is only available up to system version 19.0.1") challenge = await self.challenge() data = base64.b64decode(challenge["data"] + "==", "-_") path = "/v%i/device_auth_token" %self.api_version if edge_token: path = "/v%i/edge_token" %self.api_version req = http.HTTPRequest.post(path) req.rawform = { "challenge": challenge["challenge"], "client_id": "%016x" %client_id, "ist": "true" if self.region == 2 else "false", "key_generation": self.key_generation, "system_version": self.system_version_hash } if self.api_version >= 7 and edge_token: req.rawform["vendor_id"] = vendor_id string = http.formencode(req.rawform, False) req.rawform["mac"] = self.calculate_mac(string, data) response = await self.request(req) return response.json async def request_tokens(self, token_requests, *, edge_tokens): # This is a generic method to reduce code duplication between device_tokens and edge_tokens if self.system_version < 2000: raise ValueError("This method is only available on system version 20.0.0 and above.") challenge = await self.challenge() data = base64.b64decode(challenge["data"] + "==", "-_") system_version = "00%02x%02x%02x" %( self.system_version // 100, (self.system_version // 10) % 10, self.system_version % 10 ) form = { "challenge": challenge["challenge"], "fw_revision": self.system_version_hash, "ist": "true" if self.region == 2 else "false", "key_generation": self.key_generation, "system_version": system_version, "token_requests": json.dumps(token_requests, separators=(",", ":")) } string = http.formencode(form, False) mac = self.calculate_mac(string, data) path = "/v%i/device_auth_tokens" %self.api_version if edge_tokens: path = "/v%i/edge_tokens" %self.api_version req = http.HTTPRequest.post(path) req.json = { "system_version": system_version, "fw_revision": self.system_version_hash, "ist": self.region == 2, "token_requests": token_requests, "key_generation": self.key_generation, "challenge": challenge["challenge"], "mac": mac } response = await self.request(req) # Check if any errors have occurred errors = [] for result in response.json["results"]: if "error" in result: errors.append(result["error"]) if errors: logger.error("DAuth server returned errors:") for error in errors: logger.error(" (%s) %s", error["code"], error["message"]) raise DAuthError(response, errors[0]) return response.json async def device_token(self, client_id): return await self.request_token(client_id, edge_token=False) async def edge_token(self, client_id, vendor_id="akamai"): return await self.request_token(client_id, vendor_id, edge_token=True) async def device_tokens(self, client_ids): token_requests = [{"client_id": "%016x" %client_id} for client_id in client_ids] return await self.request_tokens(token_requests, edge_tokens=False) async def edge_tokens(self, token_requests): token_requests = [{"client_id": "%016x" %client_id, "vendor_id": vendor_id} for client_id, vendor_id in token_requests] return await self.request_tokens(token_requests, edge_tokens=True) async def preload_device_tokens(self): return await self.device_tokens(PRELOADED_DEVICE_TOKENS) async def preload_edge_tokens(self): return await self.edge_tokens(PRELOADED_EDGE_TOKENS) def get_master_key(self): keygen = self.key_generation keyname = "master_key_%02x" %(keygen - 1) return self.keys[keyname] def decrypt_key(self, key, kek): aes = AES.new(kek, AES.MODE_ECB) return aes.decrypt(key) def calculate_mac(self, form, data): kek_source = self.keys["aes_kek_generation_source"] master_key = self.get_master_key() key = self.decrypt_key(kek_source, master_key) key = self.decrypt_key(DAUTH_SOURCE, key) key = self.decrypt_key(data, key) mac = CMAC.new(key, ciphermod=AES) mac.update(form.encode()) return base64.b64encode(mac.digest(), b"-_").decode().rstrip("=") class DAuthCache: def __init__(self, client, expiration=None): self.client = client self.expiration = expiration self.device_tokens = {} self.edge_tokens = {} async def device_token(self, client_id): now = time.time() if client_id in self.device_tokens and self.device_tokens[client_id][1] > now: return self.device_tokens[client_id][0] if client_id in PRELOADED_DEVICE_TOKENS: response = await self.client.preload_device_tokens() else: response = await self.client.device_tokens([client_id]) for result in response["results"]: if self.expiration is not None: expiration = now + self.expiration else: expiration = now + result["expires_in"] self.device_tokens[int(result["client_id"], 16)] = (result["device_auth_token"], expiration) return self.device_tokens[client_id][0] async def edge_token(self, client_id, vendor_id="akamai"): now = time.time() key = (client_id, vendor_id) if key in self.edge_tokens and self.edge_tokens[key][1] > now: return self.edge_tokens[key][0] if key in PRELOADED_EDGE_TOKENS: response = await self.client.preload_edge_tokens() else: response = await self.client.edge_tokens([key]) for result in response["results"]: result_key = (int(result["client_id"], 16), result["vendor_id"]) if self.expiration is not None: expiration = now + self.expiration else: expiration = now + result["expires_in"] self.edge_tokens[result_key] = (result["dtoken"], expiration) return self.edge_tokens[key][0] ================================================ FILE: nintendo/switch/dragons.py ================================================ from anynet import tls, http from nintendo import resources from nintendo.switch import common, dauth import base64 import logging logger = logging.getLogger(__name__) USER_AGENT = "NintendoSDK Firmware/%s (platform:NX; did:%016x; eid:lp1)" API_VERSION = { 900: 1, 901: 1, 910: 1, 920: 1, 1000: 1, 1001: 1, 1002: 1, 1003: 1, 1004: 1, 1010: 1, 1011: 1, 1020: 1, 1100: 1, 1101: 1, 1200: 1, 1201: 1, 1202: 1, 1203: 1, 1210: 1, 1300: 1, 1310: 1, 1320: 1, 1321: 1, 1400: 1, 1410: 1, 1411: 1, 1412: 1, 1500: 1, 1501: 1, 1600: 1, 1601: 1, 1602: 1, 1603: 1, 1610: 1, 1700: 1, 1701: 1, 1800: 1, 1801: 1, 1810: 1, 1900: 1, 1901: 1, 2000: 2, 2001: 2, 2010: 2, 2011: 2, 2015: 2, 2020: 2, 2030: 2, 2040: 2, 2050: 2, 2100: 2, 2101: 2, 2110: 2, 2120: 2, 2200: 2, 2210: 2, } LATEST_VERSION = 2210 class DragonsError(Exception): def __init__(self, response): self.response = response self.type = response.json["type"] self.name = response.json["type"].split("/")[-1] self.title = response.json["title"] self.detail = response.json["detail"] self.status = response.json["number"] self.invalid_params = response.json.get("invalid-params") def __str__(self): return self.title class DragonsClient: def __init__(self, device_id=None): self.device_id = device_id self.request_callback = http.request ca = resources.certificate("Nintendo_Class_2_CA_G3.der") self.context = tls.TLSContext() self.context.set_authority(ca) self.host_dragons = "dragons.hac.lp1.dragons.nintendo.net" self.host_dragonst = "dragonst.hac.lp1.dragons.nintendo.net" self.host_tigers = "tigers.hac.lp1.dragons.nintendo.net" self.system_version = LATEST_VERSION self.user_agent_nim = None if self.device_id is not None: self.user_agent_nim = USER_AGENT %(common.FIRMWARE_VERSIONS[LATEST_VERSION], self.device_id) self.user_agent_dauth = dauth.USER_AGENT[LATEST_VERSION] self.api_version = API_VERSION[self.system_version] def set_request_callback(self, callback): self.request_callback = callback def set_context(self, context): self.context = context def set_certificate(self, cert, key): self.context.set_certificate(cert, key) def set_hosts(self, dragons, dragonst, tigers): self.host_dragons = dragons self.host_dragonst = dragonst self.host_tigers = tigers def set_system_version(self, version): if version not in common.FIRMWARE_VERSIONS: raise ValueError("Unknown system version: %i" %version) self.system_version = version if self.device_id is not None: self.user_agent_nim = USER_AGENT %(common.FIRMWARE_VERSIONS[version], self.device_id) self.user_agent_dauth = dauth.USER_AGENT[version] self.api_version = API_VERSION[self.system_version] async def request(self, req, host, device_token, *, account_id=None): if self.user_agent_nim is None: raise ValueError("This request requires a device id") req.headers["Host"] = host req.headers["Accept"] = "*/*" req.headers["User-Agent"] = self.user_agent_nim req.headers["DeviceAuthorization"] = "Bearer " + device_token if account_id is not None: req.headers["Nintendo-Account-Id"] = "%016x" %account_id if req.json is not None: req.headers["Content-Type"] = "application/json" req.headers["Content-Length"] = 0 else: req.headers["Content-Length"] = 0 req.headers["Content-Type"] = "application/x-www-form-urlencoded" response = await self.request_callback(host, req, self.context) if response.error() and response.json: logger.error("Dragons server returned an error: %s" %response.json) raise DragonsError(response) response.raise_if_error() return response async def request_dauth(self, req, device_token, title_id): req.headers["Host"] = self.host_dragons if self.system_version < 1800: req.headers["User-Agent"] = self.user_agent_dauth req.headers["Accept"] = "*/*" if self.system_version >= 2000: req.headers["User-Agent"] = self.user_agent_dauth req.headers["Content-Type"] = "application/json" req.headers["DeviceAuthorization"] = "Bearer " + device_token req.headers["Nintendo-Application-Id"] = "%016x" %title_id req.headers["Content-Length"] = 0 response = await self.request_callback(self.host_dragons, req, self.context) if response.error() and response.json: logger.error("Dragons server returned an error: %s" %response.json) raise DragonsError(response) response.raise_if_error() return response async def publish_elicense_archive(self, device_token, challenge, certificate, account_id): req = http.HTTPRequest.post("/v%i/elicense_archives/publish" %self.api_version) req.json = { "challenge": challenge, "certificate": base64.b64encode(certificate).decode() } response = await self.request(req, self.host_dragons, device_token, account_id=account_id) return response.json async def report_elicense_archive(self, device_token, elicense_archive_id, account_id): req = http.HTTPRequest.put("/v%i/elicense_archives/%s/report" %(self.api_version, elicense_archive_id)) await self.request(req, self.host_dragons, device_token, account_id=account_id) async def publish_device_linked_elicenses(self, device_token): req = http.HTTPRequest.post("/v%i/rights/publish_device_linked_elicenses" %self.api_version) response = await self.request(req, self.host_dragons, device_token) return response.json async def exercise_elicense(self, device_token, elicense_ids, account_ids, current_account_id): req = http.HTTPRequest.post("/v%i/elicenses/exercise" %self.api_version) req.json = { "elicense_ids": elicense_ids, "account_ids": ["%016x" %i for i in account_ids] } await self.request(req, self.host_dragons, device_token, account_id=current_account_id) async def contents_authorization_token_for_aauth(self, device_token, elicense_id, na_id, title_id): if self.system_version < 1500: raise ValueError("contents_authorization_token_for_aauth was added in system version 15.0.0") req = http.HTTPRequest.post("/v%i/contents_authorization_token_for_aauth/issue" %self.api_version) req.json = { "elicense_id": elicense_id, "na_id": "%016x" %na_id } response = await self.request_dauth(req, device_token, title_id) return response.json ================================================ FILE: nintendo/switch/five.py ================================================ from anynet import tls, http from nintendo import resources import base64 import logging logger = logging.getLogger(__name__) USER_AGENT = { 900: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 9.3.0.0; Add-on 9.3.0.0)", 901: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 9.3.0.0; Add-on 9.3.0.0)", 910: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 9.3.0.0; Add-on 9.3.0.0)", 920: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 9.3.0.0; Add-on 9.3.0.0)", 1000: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 10.4.0.0; Add-on 10.4.0.0)", 1001: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 10.4.0.0; Add-on 10.4.0.0)", 1002: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 10.4.0.0; Add-on 10.4.0.0)", 1003: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 10.4.0.0; Add-on 10.4.0.0)", 1004: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 10.4.0.0; Add-on 10.4.0.0)", 1010: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 10.4.0.0; Add-on 10.4.0.0)", 1011: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 10.4.0.0; Add-on 10.4.0.0)", 1020: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 10.4.0.0; Add-on 10.4.0.0)", 1100: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 11.4.0.0; Add-on 11.4.0.0)", 1101: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 11.4.0.0; Add-on 11.4.0.0)", 1200: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 12.3.0.0; Add-on 12.3.0.0)", 1201: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 12.3.0.0; Add-on 12.3.0.0)", 1202: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 12.3.0.0; Add-on 12.3.0.0)", 1203: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 12.3.0.0; Add-on 12.3.0.0)", 1210: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 12.3.0.0; Add-on 12.3.0.0)", 1300: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 13.3.0.0; Add-on 13.3.0.0)", 1310: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 13.4.0.0; Add-on 13.4.0.0)", 1320: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 13.4.0.0; Add-on 13.4.0.0)", 1321: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 13.4.0.0; Add-on 13.4.0.0)", 1400: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 14.3.0.0; Add-on 14.3.0.0)", 1410: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 14.3.0.0; Add-on 14.3.0.0)", 1411: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 14.3.0.0; Add-on 14.3.0.0)", 1412: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 14.3.0.0; Add-on 14.3.0.0)", 1500: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 15.3.0.0; Add-on 15.3.0.0)", 1501: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 15.3.0.0; Add-on 15.3.0.0)", 1600: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 16.2.0.0; Add-on 16.2.0.0)", 1601: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 16.2.0.0; Add-on 16.2.0.0)", 1602: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 16.2.0.0; Add-on 16.2.0.0)", 1603: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 16.2.0.0; Add-on 16.2.0.0)", 1610: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 16.2.0.0; Add-on 16.2.0.0)", 1700: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 17.5.0.0; Add-on 17.5.0.0)", 1701: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 17.5.0.0; Add-on 17.5.0.0)", 1800: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 18.3.0.0; Add-on 18.3.0.0)", 1801: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 18.3.0.0; Add-on 18.3.0.0)", 1810: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 18.3.0.0; Add-on 18.3.0.0)", 1900: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 19.3.0.0; Add-on 19.3.0.0)", 1901: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 19.3.0.0; Add-on 19.3.0.0)", 2000: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 20.5.4.0; Add-on 20.5.4.0)", 2001: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 20.5.4.0; Add-on 20.5.4.0)", 2010: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 20.5.4.0; Add-on 20.5.4.0)", 2011: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 20.5.4.0; Add-on 20.5.4.0)", 2015: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 20.5.4.0; Add-on 20.5.4.0)", 2020: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 20.5.4.0; Add-on 20.5.4.0)", 2030: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 20.5.4.0; Add-on 20.5.4.0)", 2040: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 20.5.4.0; Add-on 20.5.4.0)", 2050: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 20.5.4.0; Add-on 20.5.4.0)", 2100: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 21.4.0.0; Add-on 21.4.0.0)", 2101: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 21.4.0.0; Add-on 21.4.0.0)", 2110: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 21.4.0.0; Add-on 21.4.0.0)", 2120: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 21.4.0.0; Add-on 21.4.0.0)", 2200: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 22.2.0.0; Add-on 22.2.0.0)", 2210: "libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 22.2.0.0; Add-on 22.2.0.0)", } LATEST_VERSION = 2210 LANGUAGES = [ "en-US", "en-GB", "ja", "fr", "de", "es-419", "es", "it", "nl" "fr-CA", "pt", "ru", "zh-Hans", "zh-Hant", "ko", "pt-BR" ] class FiveError(Exception): INVALID_PARAMETER = 2 INVALID_REQUEST_URI = 3 UNAUTHORIZED = 6 RESOURCE_NOT_FOUND = 10 APPLICATION_DATA_TOO_LARGE = 11 def __init__(self, response): self.response = response self.code = int(response.json["error"]["code"]) self.message = response.json["error"]["message"] def __str__(self): return self.message class FiveClient: def __init__(self): self.request_callback = http.request ca = resources.certificate("Nintendo_CA_G3.der") self.context = tls.TLSContext() self.context.set_authority(ca) self.host = "app.lp1.five.nintendo.net" self.system_version = LATEST_VERSION self.user_agent = USER_AGENT[LATEST_VERSION] def set_request_callback(self, callback): self.request_callback = callback def set_context(self, context): self.context = context def set_host(self, host): self.host = host def set_system_version(self, version): if version not in USER_AGENT: raise ValueError("Unknown system version") self.system_version = version self.user_agent = USER_AGENT[version] async def request(self, req, access_token): req.headers["Host"] = self.host req.headers["User-Agent"] = self.user_agent req.headers["Accept"] = "*/*" if req.method != "GET": if req.json is not None: req.headers["Content-Type"] = "application/json" req.headers["Authorization"] = "Bearer " + access_token req.headers["Content-Length"] = 0 elif req.form is not None: req.headers["Content-Type"] = "application/x-www-form-urlencoded" req.headers["Authorization"] = "Bearer " + access_token req.headers["Content-Length"] = 0 else: req.headers["Authorization"] = "Bearer " + access_token req.headers["Content-Length"] = 0 req.headers["Content-Type"] = "application/x-www-form-urlencoded" else: req.headers["Authorization"] = "Bearer " + access_token response = await self.request_callback(self.host, req, self.context) if response.json and "error" in response.json: logger.warning("Five server returned an error: %s" %response.json) raise FiveError(response) response.raise_if_error() return response async def get_unread_invitation_count(self, access_token, user_id): if self.system_version < 2000: req = http.HTTPRequest.get("/v1/users/%016x/invitations/inbox" %user_id) req.params = { "fields": "count", "read": "false" } else: req = http.HTTPRequest.get("/v2/users/%016x/invitations/inbox" %user_id) req.params = { "fields": "count", "read": "false", "invitation_types": "friend" } response = await self.request(req, access_token) return response.json["count"] async def get_inbox(self, access_token, user_id): if self.system_version < 2000: req = http.HTTPRequest.get("/v1/users/%016x/invitations/inbox" %user_id) else: req = http.HTTPRequest.get("/v2/users/%016x/invitations/inbox" %user_id) req.params = { "invitation_types": "friend" } response = await self.request(req, access_token) return response.json async def get_invitation_group(self, access_token, invitation_group_id): req = http.HTTPRequest.get("/v1/invitation_groups/%i" %invitation_group_id) response = await self.request(req, access_token) return response.json async def mark_as_read(self, access_token, ids): req = http.HTTPRequest.patch("/v1/invitations") req.form = { "read": "true", "ids": ",".join("%016x" %id for id in ids) } await self.request(req, access_token) async def mark_all_as_read(self, access_token, user_id): req = http.HTTPRequest.patch("/v1/users/%016x/invitations/mark_as_read" %user_id) await self.request(req, access_token) async def send_invitation( self, access_token, receivers, application_id, application_group_id, application_data, messages, application_id_match=False, acd_index=0 ): # Sanity checks if len(receivers) > 16: raise ValueError("Too many receiver ids") for language, message in messages.items(): if language not in LANGUAGES: raise ValueError("'%s' is not a valid language" %language) if len(message) >= 0xC0: raise ValueError("Message for language '%s' is too long" %language) if len(application_data) > 0x400: raise ValueError("Application data is too large") url = "/v1/invitation_groups" if self.system_version >= 2000: url = "/v2/invitation_groups" req = http.HTTPRequest.post(url) req.json = { "receiver_ids": ["%016x" %id for id in receivers], } if self.system_version >= 2000: req.json["invitation_type"] = "friend" req.json["application_id"] = "%016x" %application_id if self.system_version >= 1900: req.json["acd_index"] = acd_index req.json["application_group_id"] = "%016x" %application_group_id if application_data: req.json["application_data"] = base64.b64encode(application_data).decode() req.json["messages"] = messages for language in LANGUAGES: if language in messages: req.json["messages"][language] = messages[language] req.json["application_id_match"] = application_id_match req.json_options["ensure_ascii"] = False response = await self.request(req, access_token) return response.json ================================================ FILE: nintendo/switch/sun.py ================================================ from anynet import tls, http from nintendo import resources from nintendo.switch import common import logging logger = logging.getLogger(__name__) USER_AGENT = "NintendoSDK Firmware/%s (platform:NX; did:%016x; eid:lp1)" LATEST_VERSION = 2210 class SunError(Exception): def __init__(self, response): self.response = response self.code = response.json["error"]["code"] self.message = response.json["error"]["message"] def __str__(self): return self.message class SunClient: def __init__(self, device_id): self.device_id = device_id self.request_callback = http.request ca = resources.certificate("Nintendo_Class_2_CA_G3.der") self.context = tls.TLSContext() self.context.set_authority(ca) self.host = "sun.hac.lp1.d4c.nintendo.net" self.user_agent = USER_AGENT %(common.FIRMWARE_VERSIONS[LATEST_VERSION], self.device_id) def set_request_callback(self, callback): self.request_callback = callback def set_context(self, context): self.context = context def set_certificate(self, cert, key): self.context.set_certificate(cert, key) def set_host(self, host): self.host = host def set_system_version(self, version): if version not in common.FIRMWARE_VERSIONS: raise ValueError("Unknown system version: %i" %version) self.user_agent = USER_AGENT %(common.FIRMWARE_VERSIONS[version], self.device_id) async def request(self, req): req.headers["Host"] = self.host req.headers["User-Agent"] = self.user_agent req.headers["Accept"] = "application/json" response = await self.request_callback(self.host, req, self.context) if response.error() and response.json: logger.error("Sun server returned an error: %s" %response.json) raise SunError(response) response.raise_if_error() return response async def system_update_meta(self): req = http.HTTPRequest.get("/v1/system_update_meta") req.params = { "device_id": "%016x" %self.device_id } response = await self.request(req) return response.json ================================================ FILE: setup.py ================================================ import setuptools long_description = \ "This library implements various network protocols made by Nintendo." setuptools.setup( name = "nintendoclients", version = "4.4.0", description = "Nintendo network library", long_description = long_description, author = "Yannik Marchand", author_email = "ymarchand@me.com", url = "https://github.com/kinnay/NintendoClients", license = "MIT", packages = [ "nintendo", "nintendo.nex", "nintendo.switch" ], package_data = { "nintendo": ["files/config/*", "files/cert/*"] }, install_requires = [ "anynet ~= 1.1", "pycryptodome" ] ) ================================================ FILE: tests/nex/test_backend.py ================================================ from nintendo.nex import backend, rmc, common, authentication, \ kerberos, account, settings import pytest HOST = "127.0.0.1" class AuthenticationServer(authentication.AuthenticationServer): def __init__(self, settings): super().__init__() self.settings = settings async def login(self, client, username): assert username == "username" pid = 1001 stick = kerberos.ServerTicket() stick.timestamp = common.DateTime.now() stick.source = pid stick.session_key = bytes(32) ctick = kerberos.ClientTicket() ctick.session_key = bytes(32) ctick.target = 100 ctick.internal = stick.encrypt(b"testkey", self.settings) kerb = kerberos.KeyDerivationOld(65000, 1024) key = kerb.derive_key(b"password", pid) connection_data = authentication.RVConnectionData() connection_data.main_station = common.StationURL( address=HOST, port=12346, PID=100, sid=1 ) connection_data.special_protocols = [] connection_data.special_station = common.StationURL() connection_data.server_time = common.DateTime.now() response = rmc.RMCResponse() response.result = common.Result.success() response.pid = pid response.ticket = ctick.encrypt(key, self.settings) response.connection_data = connection_data response.server_name = "server build name" return response class AccountManagementServer(account.AccountServer): async def get_name(self, client, pid): assert pid == 1000 return "test" @pytest.mark.anyio async def test_backend(): s = settings.default() auth_servers = [AuthenticationServer(s)] secure_servers = [AccountManagementServer()] async with rmc.serve(s, auth_servers, HOST, 12345): async with rmc.serve(s, secure_servers, HOST, 12346, key=b"testkey"): async with backend.connect(s, HOST, 12345) as client: async with client.login("username", "password") as secure_client: act = account.AccountClient(secure_client) assert await act.get_name(1000) == "test" ================================================ FILE: tests/nex/test_common.py ================================================ from nintendo.nex import common import pytest def test_result(): result = common.Result.success() assert result.is_success() assert not result.is_error() assert result.code() == 0x10001 assert result.name() == "success" result.raise_if_error() result = common.Result.success(0x1000A) assert result.code() == 0x1000A assert result.name() == "success" result = common.Result.error("Core::InvalidArgument") assert not result.is_success() assert result.is_error() assert result.code() == 0x8001000A assert result.name() == "Core::InvalidArgument" with pytest.raises(common.RMCError): result.raise_if_error() def test_rmcerror(): error = common.RMCError() assert error.name() == "Core::Unknown" assert error.code() == 0x80010001 result = common.RMCError().result() assert result.is_error() assert result.name() == "Core::Unknown" assert result.code() == 0x80010001 result = common.RMCError("Core::InvalidArgument").result() assert result.name() == "Core::InvalidArgument" assert result.code() == 0x8001000A result = common.RMCError(0x8001000A).result() assert result.name() == "Core::InvalidArgument" assert result.code() == 0x8001000A def test_resultrange(): rr = common.ResultRange() assert rr.offset == 0 assert rr.size == 10 rr = common.ResultRange(50, 100) assert rr.offset == 50 assert rr.size == 100 class TestStationURL: def test_repr(self): url = common.StationURL(PID=12345) assert repr(url) == "prudp:/PID=12345" def test_parse(self): url = common.StationURL.parse("prudp:/PID=12345") assert repr(url) == "prudp:/PID=12345" def test_parse_empty(self): url = common.StationURL.parse("") assert repr(url) == "prudp:/" def test_getitem(self): url = common.StationURL.parse("prudp:/address=1.2.3.4;port=12345") assert url["address"] == "1.2.3.4" assert url["port"] == 12345 assert url["PID"] == 0 with pytest.raises(KeyError): url["test"] def test_setitem(self): url = common.StationURL.parse("prudp:/address=1.2.3.4;port=12345") url["port"] = 12346 url["natf"] = 1 assert url["port"] == 12346 assert url["natf"] == 1 def test_scheme(self): url = common.StationURL.parse("prudps:/PID=100") assert url.scheme() == "prudps" def test_address(self): url = common.StationURL.parse("prudp:/address=1.2.3.4;port=12345") assert url.address() == ("1.2.3.4", 12345) def test_flags(self): url = common.StationURL(type=3) assert url.is_public() assert url.is_behind_nat() assert not url.is_global() url = common.StationURL(type=2) assert url.is_public() assert not url.is_behind_nat() assert url.is_global() class TestDateTime: def test_value(self): datetime = common.DateTime(135593643393) assert datetime.value() == 135593643393 def test_datetime(self): datetime = common.DateTime(135593643393) assert datetime.second() == 1 assert datetime.minute() == 54 assert datetime.hour() == 12 assert datetime.day() == 1 assert datetime.month() == 8 assert datetime.year() == 2020 def test_standard_datetime(self): import datetime dt = common.DateTime(135593643393).standard_datetime() assert dt == datetime.datetime(2020, 8, 1, 12, 54, 1, tzinfo=datetime.timezone.utc) def test_timestamp(self): datetime = common.DateTime(135593643393) assert datetime.timestamp() == 1596286441 def test_make(self): datetime = common.DateTime.make(2020, 10, 31, 14) assert datetime.timestamp() == 1604152800 def test_fromtimestamp(self): datetime = common.DateTime.fromtimestamp(1604149200) assert datetime.value() == 135605964800 def test_now(self): datetime = common.DateTime.now() assert datetime.year() >= 2020 def test_never(self): datetime = common.DateTime.never() assert datetime.value() == 0 def test_future(self): datetime = common.DateTime.future() assert datetime.value() == 0x9C3F3F7EFB ================================================ FILE: tests/nex/test_errors.py ================================================ from nintendo.nex import errors def test_basic(): assert errors.error_names[0x10001] == "Core::Unknown" assert errors.error_codes["Core::Unknown"] == 0x10001 ================================================ FILE: tests/nex/test_kerberos.py ================================================ from nintendo.nex import kerberos, settings, common def test_key_derivation_old(): keyderiv1 = kerberos.KeyDerivationOld() keyderiv2 = kerberos.KeyDerivationOld(5, 10) assert keyderiv1.derive_key(b"password", 123456) == bytes.fromhex("bd9d83b0d4102b72de3e14f44938c989") assert keyderiv2.derive_key(b"password", 123456) == bytes.fromhex("6ba537f0cc7e0d25813f2ea010eb2115") def test_key_derivation_new(): keyderiv1 = kerberos.KeyDerivationNew() keyderiv2 = kerberos.KeyDerivationNew(5, 10) assert keyderiv1.derive_key(b"password", 123456) == bytes.fromhex("591b45defe20abcd6ec412b63fbacff5") assert keyderiv2.derive_key(b"password", 123456) == bytes.fromhex("09409830bf949ab56fae81bd028fe18d") def test_kerberos_encryption(): kerb = kerberos.KerberosEncryption(b"key") data = kerb.encrypt(b"test message") assert data == bytes.fromhex("7f09479904e21e393b2a6f1ed5b96acc69a869dce66679d0cedb242d") assert kerb.check(data) assert not kerb.check(b"\x7e" + data[1:]) assert kerb.decrypt(data) == b"test message" def test_client_ticket(): ticket = kerberos.ClientTicket() ticket.session_key = bytes(range(32)) ticket.internal = b"internal buffer" ticket.target = 123456 s = settings.default() data = ticket.encrypt(b"key", s) ticket = kerberos.ClientTicket.decrypt(data, b"key", s) assert ticket.session_key == bytes(range(32)) assert ticket.internal == b"internal buffer" assert ticket.target == 123456 def test_server_ticket(): ticket = kerberos.ServerTicket() ticket.timestamp = common.DateTime.fromtimestamp(1596279690) ticket.session_key = bytes(range(32)) ticket.source = 123456 s = settings.default() data = ticket.encrypt(b"key", s) ticket = kerberos.ServerTicket.decrypt(data, b"key", s) assert ticket.timestamp.timestamp() == 1596279690 assert ticket.session_key == bytes(range(32)) assert ticket.source == 123456 def test_server_ticket_old(): ticket = kerberos.ServerTicket() ticket.timestamp = common.DateTime.fromtimestamp(1596279690) ticket.session_key = bytes(range(32)) ticket.source = 123456 s = settings.default() s["kerberos.ticket_version"] = 0 data = ticket.encrypt(b"key", s) ticket = kerberos.ServerTicket.decrypt(data, b"key", s) assert ticket.timestamp.timestamp() == 1596279690 assert ticket.session_key == bytes(range(32)) assert ticket.source == 123456 def test_credentials(): ticket = kerberos.ClientTicket() creds = kerberos.Credentials(ticket, 1000, 2000) assert creds.ticket == ticket assert creds.pid == 1000 assert creds.cid == 2000 ================================================ FILE: tests/nex/test_nex_streams.py ================================================ from nintendo.nex import streams, settings, common class TestStreamOut: def test_pid(self): stream = streams.StreamOut(settings.default()) stream.pid(12345) assert stream.get() == bytes.fromhex("39300000") stream = streams.StreamOut(settings.load("switch")) stream.pid(12345) assert stream.get() == bytes.fromhex("3930000000000000") def test_result(self): stream = streams.StreamOut(settings.default()) stream.result(common.Result.success()) assert stream.get() == bytes.fromhex("01000100") def test_list(self): stream = streams.StreamOut(settings.default()) stream.list([1,2,3,4], stream.u8) assert stream.get() == bytes.fromhex("0400000001020304") def test_map(self): stream = streams.StreamOut(settings.default()) stream.map({1: 10, 2: 11}, stream.u8, stream.u16) assert stream.get() == bytes.fromhex("02000000010a00020b00") def test_string(self): stream = streams.StreamOut(settings.default()) stream.string("test string") assert stream.get() == b"\x0C\0test string\0" def test_stationurl(self): stream = streams.StreamOut(settings.default()) stream.stationurl(common.StationURL("prudps", PID=1, CID=100)) assert stream.get() == b"\x16\0prudps:/PID=1;CID=100\0" def test_datetime(self): stream = streams.StreamOut(settings.default()) stream.datetime(common.DateTime(135605968896)) assert stream.get() == bytes.fromhex("00e0be921f000000") def test_buffer(self): stream = streams.StreamOut(settings.default()) stream.buffer(b"test buffer") assert stream.get() == b"\x0B\0\0\0test buffer" def test_qbuffer(self): stream = streams.StreamOut(settings.default()) stream.qbuffer(b"test qbuffer") assert stream.get() == b"\x0C\0test qbuffer" def test_add(self): stream = streams.StreamOut(settings.default()) stream.add(common.ResultRange()) assert stream.get() == bytes.fromhex("000000000a000000") stream = streams.StreamOut(settings.load("switch")) stream.add(common.ResultRange()) assert stream.get() == bytes.fromhex("0008000000000000000a000000") def test_anydata(self): stream = streams.StreamOut(settings.default()) stream.anydata(common.NullData()) assert stream.get() == b"\x09\0NullData\0\x04\0\0\0\0\0\0\0" stream = streams.StreamOut(settings.load("switch")) stream.anydata(common.NullData()) assert stream.get() == b"\x09\0NullData\0\x0E\0\0\0\x0A\0\0\0\0\0\0\0\0\0\0\0\0\0" def test_variant(self): stream = streams.StreamOut(settings.default()) stream.variant(None) assert stream.get() == b"\0" stream = streams.StreamOut(settings.default()) stream.variant(-12345) assert stream.get() == bytes.fromhex("01c7cfffffffffffff") stream = streams.StreamOut(settings.default()) stream.variant(123.45) assert stream.get() == bytes.fromhex("02cdccccccccdc5e40") stream = streams.StreamOut(settings.default()) stream.variant(True) stream.variant(False) assert stream.get() == bytes.fromhex("03010300") stream = streams.StreamOut(settings.default()) stream.variant("hello") assert stream.get() == b"\x04\x06\0hello\0" stream = streams.StreamOut(settings.default()) stream.variant(common.DateTime.never()) assert stream.get() == bytes.fromhex("050000000000000000") stream = streams.StreamOut(settings.default()) stream.variant(12345) assert stream.get() == bytes.fromhex("063930000000000000") class TestStreamIn: def test_pid(self): data = bytes.fromhex("39300000") stream = streams.StreamIn(data, settings.default()) assert stream.pid() == 12345 assert stream.eof() data = bytes.fromhex("3930000000000000") stream = streams.StreamIn(data, settings.load("switch")) assert stream.pid() == 12345 assert stream.eof() def test_result(self): data = bytes.fromhex("01000100") stream = streams.StreamIn(data, settings.default()) assert stream.result().code() == 0x10001 def test_repeat(self): data = bytes.fromhex("0102030400000000140000001400000020000000") stream = streams.StreamIn(data, settings.default()) ints = stream.repeat(stream.u8, 4) rrs = stream.repeat(common.ResultRange, 2) assert ints == [1, 2, 3, 4] assert rrs[0].offset == 0 and rrs[0].size == 20 assert rrs[1].offset == 20 and rrs[1].size == 32 def test_list(self): data = bytes.fromhex("0400000001020304") stream = streams.StreamIn(data, settings.default()) assert stream.list(stream.u8) == [1, 2, 3, 4] data = bytes.fromhex("020000000000000014000000280000003c000000") stream = streams.StreamIn(data, settings.default()) rrs = stream.list(common.ResultRange) assert rrs[0].offset == 0 and rrs[0].size == 20 assert rrs[1].offset == 40 and rrs[1].size == 60 def test_map(self): value = {1: 10, 2: 11} data = bytes.fromhex("02000000010a00020b00") stream = streams.StreamIn(data, settings.default()) assert stream.map(stream.u8, stream.u16) == value data = bytes.fromhex("01000000393000001400000005000000") stream = streams.StreamIn(data, settings.default()) map = stream.map(stream.pid, common.ResultRange) assert map[12345].offset == 20 assert map[12345].size == 5 def test_string(self): data = b"\x0C\0test string\0" stream = streams.StreamIn(data, settings.default()) assert stream.string() == "test string" def test_stationurl(self): data = b"\x16\0prudps:/PID=1;CID=100\0" stream = streams.StreamIn(data, settings.default()) url = stream.stationurl() assert url.scheme() == "prudps" assert url["PID"] == 1 assert url["CID"] == 100 def test_datetime(self): data = bytes.fromhex("00e0be921f000000") stream = streams.StreamIn(data, settings.default()) assert stream.datetime().value() == 135605968896 def test_buffer(self): data = b"\x0B\0\0\0test buffer" stream = streams.StreamIn(data, settings.default()) assert stream.buffer() == b"test buffer" def test_qbuffer(self): data = b"\x0C\0test qbuffer" stream = streams.StreamIn(data, settings.default()) assert stream.qbuffer() == b"test qbuffer" def test_substream(self): data = b"\x08\0\0\0\x64\0\0\0\xc8\0\0\0\xff\0\0\0" stream = streams.StreamIn(data, settings.default()) substream = stream.substream() assert stream.u32() == 255 assert substream.u32() == 100 assert substream.u32() == 200 assert substream.eof() def test_extract(self): data = b"\0\0\0\0\x0a\0\0\0" stream = streams.StreamIn(data, settings.default()) rr = stream.extract(common.ResultRange) assert rr.offset == 0 assert rr.size == 10 data = b"\0\x08\0\0\0\0\0\0\0\x0a\0\0\0" stream = streams.StreamIn(data, settings.load("switch")) rr = stream.extract(common.ResultRange) assert rr.offset == 0 assert rr.size == 10 def test_anydata(self): data = b"\x09\0NullData\0\x04\0\0\0\0\0\0\0" stream = streams.StreamIn(data, settings.default()) assert isinstance(stream.anydata(), common.NullData) assert stream.eof() data = b"\x09\0NullData\0\x0E\0\0\0\x0A\0\0\0\0\0\0\0\0\0\0\0\0\0" stream = streams.StreamIn(data, settings.load("switch")) assert isinstance(stream.anydata(), common.NullData) assert stream.eof() def test_variant(self): data = b"\0" stream = streams.StreamIn(data, settings.default()) assert stream.variant() is None data = bytes.fromhex("01c7cfffffffffffff") stream = streams.StreamIn(data, settings.default()) assert stream.variant() == -12345 data = bytes.fromhex("02cdccccccccdc5e40") stream = streams.StreamIn(data, settings.default()) assert stream.variant() == 123.45 data = bytes.fromhex("03010300") stream = streams.StreamIn(data, settings.default()) assert stream.variant() is True assert stream.variant() is False data = b"\x04\x06\0hello\0" stream = streams.StreamIn(data, settings.default()) assert stream.variant() == "hello" data = bytes.fromhex("050000000000000000") stream = streams.StreamIn(data, settings.default()) assert stream.variant().value() == 0 data = bytes.fromhex("06c7cfffffffffffff") stream = streams.StreamIn(data, settings.default()) assert stream.variant() == 0xFFFFFFFFFFFFCFC7 ================================================ FILE: tests/nex/test_prudp.py ================================================ from nintendo.nex import prudp, settings, kerberos, common import pytest HOST = "127.0.0.1" @pytest.mark.anyio async def test_v0(): s = settings.load("3ds") s["prudp.access_key"] = b"access key" async def handler(client): assert await client.recv() == b"ping" await client.send(b"pong") async with prudp.serve(handler, s, HOST, 12345): async with prudp.connect(s, HOST, 12345) as client: assert client.remote_address() == (HOST, 12345) await client.send(b"ping") assert await client.recv() == b"pong" @pytest.mark.anyio async def test_v1(): s = settings.default() async def handler(client): assert await client.recv() == b"ping" await client.send(b"pong") async with prudp.serve(handler, s, HOST, 12345): async with prudp.connect(s, HOST, 12345) as client: await client.send(b"ping") assert await client.recv() == b"pong" @pytest.mark.anyio async def test_lite(): s = settings.load("switch") async def handler(client): assert await client.recv() == b"ping" await client.send(b"pong") async with prudp.serve(handler, s, HOST, 12345): async with prudp.connect(s, HOST, 12345) as client: await client.send(b"ping") assert await client.recv() == b"pong" @pytest.mark.anyio async def test_v0_alt(): s = settings.load("3ds") s["prudp_v0.signature_version"] = 1 s["prudp_v0.flags_version"] = 0 s["prudp_v0.checksum_version"] = 0 async def handler(client): assert await client.recv() == b"ping" await client.send(b"pong") async with prudp.serve(handler, s, HOST, 12345): async with prudp.connect(s, HOST, 12345) as client: await client.send(b"ping") assert await client.recv() == b"pong" @pytest.mark.anyio async def test_compression(): s = settings.default() s["prudp.compression"] = s.COMPRESSION_ZLIB async def handler(client): assert await client.recv() == b"ping" await client.send(b"pong") async with prudp.serve(handler, s, HOST, 12345): async with prudp.connect(s, HOST, 12345) as client: await client.send(b"ping") assert await client.recv() == b"pong" @pytest.mark.anyio async def test_fragmentation(): s = settings.default() s["prudp.fragment_size"] = 10 async def handler(client): assert await client.recv() == b"a" * 40 await client.send(b"b" * 40) async with prudp.serve(handler, s, HOST, 12345): async with prudp.connect(s, HOST, 12345) as client: await client.send(b"a" * 40) assert await client.recv() == b"b" * 40 @pytest.mark.anyio async def test_unreliable(): s = settings.default() async def handler(client): assert await client.recv_unreliable() == b"ping" await client.send_unreliable(b"pong") async with prudp.serve(handler, s, HOST, 12345): async with prudp.connect(s, HOST, 12345) as client: await client.send_unreliable(b"ping") assert await client.recv_unreliable() == b"pong" @pytest.mark.anyio async def test_substreams(): s = settings.default() s["prudp.max_substream_id"] = 1 async def handler(client): assert await client.recv(0) == b"test1" assert await client.recv(0) == b"test3" assert await client.recv(1) == b"test2" await client.send(b"pong", 1) async with prudp.serve(handler, s, HOST, 12345): async with prudp.connect(s, HOST, 12345) as client: await client.send(b"test1", 0) await client.send(b"test2", 1) await client.send(b"test3", 0) assert await client.recv(1) == b"pong" @pytest.mark.anyio async def test_client_transport(): s = settings.default() async def handler(client): data = await client.recv() await client.send(data[::-1]) async with prudp.serve(handler, s, HOST, 12345): async with prudp.connect_transport(s, HOST, 12345) as transport: async with transport.connect(1) as client1: async with transport.connect(1) as client2: await client1.send(b"ping") await client2.send(b"test") assert await client1.recv() == b"gnip" assert await client2.recv() == b"tset" @pytest.mark.anyio async def test_server_transport(): s = settings.default() async def handler1(client): assert await client.recv() == b"ping1" await client.send(b"pong1") async def handler2(client): assert await client.recv() == b"ping2" await client.send(b"pong2") async with prudp.serve_transport(s, HOST, 12345) as transport: async with transport.serve(handler1, 1): async with transport.serve(handler2, 2): async with prudp.connect(s, HOST, 12345, 1) as client: await client.send(b"ping1") assert await client.recv() == b"pong1" async with prudp.connect(s, HOST, 12345, 2) as client: await client.send(b"ping2") assert await client.recv() == b"pong2" @pytest.mark.anyio async def test_negotiation(): s1 = settings.default() s1["prudp.minor_version"] = 2 s2 = settings.default() s2["prudp.minor_version"] = 5 async def handler(client): assert client.minor_version() == 2 async with prudp.serve(handler, s1, HOST, 12345): async with prudp.connect(s2, HOST, 12345) as client: assert client.minor_version() == 2 @pytest.mark.anyio async def test_pid(): s = settings.default() async def handler(client): assert client.pid() is None async with prudp.serve(handler, s, HOST, 12345): async with prudp.connect(s, HOST, 12345) as client: assert client.pid() is None @pytest.mark.anyio async def test_credentials(): s = settings.default() async def handler(client): assert client.pid() == 1000 ticket = kerberos.ServerTicket() ticket.timestamp = common.DateTime.now() ticket.source = 1000 ticket.session_key = bytes(32) data = ticket.encrypt(b"server key", s) ticket = kerberos.ClientTicket() ticket.session_key = bytes(32) ticket.target = 1001 ticket.internal = data creds = kerberos.Credentials(ticket, 1000, 2000) async with prudp.serve(handler, s, HOST, 12345, key=b"server key"): async with prudp.connect(s, HOST, 12345, credentials=creds) as client: assert client.pid() == 1000 ================================================ FILE: tests/nex/test_rmc.py ================================================ from nintendo.nex import rmc, common, authentication, settings import pytest import anyio HOST = "127.0.0.1" class AuthenticationServer(authentication.AuthenticationServer): def __init__(self): super().__init__() self.flag = False async def logout(self, client): self.flag = True async def get_name(self, client, pid): return str(pid) @pytest.mark.anyio async def test_simple(): s = settings.default() servers = [AuthenticationServer()] async with rmc.serve(s, servers, HOST, 12345): async with rmc.connect(s, HOST, 12345) as client: assert client.remote_address() == (HOST, 12345) auth = authentication.AuthenticationClient(client) result = await auth.get_name(12345) assert result == "12345" @pytest.mark.anyio async def test_unimplemented_protocol(): s = settings.default() servers = [] async with rmc.serve(s, servers, HOST, 12345): async with rmc.connect(s, HOST, 12345) as client: assert client.remote_address() == (HOST, 12345) auth = authentication.AuthenticationClient(client) try: result = await auth.get_name(12345) except common.RMCError as e: assert e.result().name() == "Core::NotImplemented" @pytest.mark.anyio async def test_logout_event(): s = settings.default() server = AuthenticationServer() async with rmc.serve(s, [server], HOST, 12345): async with rmc.connect(s, HOST, 12345) as client: assert not server.flag await anyio.sleep(.1) # Wait a bit assert server.flag ================================================ FILE: tests/nex/test_settings.py ================================================ from nintendo.nex import settings def test_constants(): s = settings.default() assert s.TRANSPORT_UDP == 0 assert s.TRANSPORT_TCP == 1 assert s.TRANSPORT_WEBSOCKET == 2 assert s.COMPRESSION_NONE == 0 assert s.COMPRESSION_ZLIB == 1 assert s.ENCRYPTION_NONE == 0 assert s.ENCRYPTION_RC4 == 1 def test_basic(): s = settings.default() assert s["kerberos.key_size"] == 32 copy = s.copy() s["kerberos.key_size"] = 100 assert s["kerberos.key_size"] == 100 assert copy["kerberos.key_size"] == 32 s.reset() assert s["kerberos.key_size"] == 32 s.load("friends") assert s["kerberos.key_size"] == 16 ================================================ FILE: tests/switch/test_aauth.py ================================================ from nintendo.switch import aauth from anynet import http import pytest import struct TOKEN_REQUEST_1300 = \ "POST /v3/application_auth_token HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "User-Agent: libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 13.3.0.0; Add-on 13.3.0.0)\r\n" \ "Accept: */*\r\n" \ "X-Nintendo-PowerState: FA\r\n" \ "Content-Length: 1428\r\n" \ "Content-Type: application/x-www-form-urlencoded\r\n" \ "Expect: 100-continue\r\n\r\n" \ "application_id=0100123001234000&application_version=00070000&" \ "device_auth_token=device.token&media_type=DIGITAL&cert=" TOKEN_REQUEST_1500 = \ "POST /v4/application_auth_token HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "User-Agent: libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 15.3.0.0; Add-on 15.3.0.0)\r\n" \ "Accept: */*\r\n" \ "X-Nintendo-PowerState: FA\r\n" \ "Content-Length: 134\r\n" \ "Content-Type: application/x-www-form-urlencoded\r\n\r\n" \ "application_id=0100123001234000&application_version=00070000&" \ "device_auth_token=device.token&media_type=DIGITAL&cert=token.from.dragons" TOKEN_REQUEST_1800 = \ "POST /v4/application_auth_token HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "Accept: */*\r\n" \ "Content-Type: application/x-www-form-urlencoded\r\n" \ "X-Nintendo-PowerState: FA\r\n" \ "Content-Length: 134\r\n\r\n" \ "application_id=0100123001234000&application_version=00070000&" \ "device_auth_token=device.token&media_type=DIGITAL&cert=token.from.dragons" TOKEN_REQUEST_1900 = \ "POST /v5/application_auth_token HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "Accept: */*\r\n" \ "Content-Type: application/x-www-form-urlencoded\r\n" \ "X-Nintendo-PowerState: FA\r\n" \ "Content-Length: 133\r\n\r\n" \ "application_id=0100123001234000&application_version=00070000&" \ "device_auth_token=device.token&auth_type=DIGITAL&cert=token.from.dragons" CHALLENGE_REQUEST_1300 = \ "POST /v3/challenge HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "User-Agent: libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 13.3.0.0; Add-on 13.3.0.0)\r\n" \ "Accept: */*\r\n" \ "Content-Length: 31\r\n" \ "Content-Type: application/x-www-form-urlencoded\r\n\r\n" \ "&device_auth_token=device.token" CHALLENGE_REQUEST_1900 = \ "POST /v5/challenge HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "Accept: */*\r\n" \ "Content-Type: application/x-www-form-urlencoded\r\n" \ "Content-Length: 30\r\n\r\n" \ "device_auth_token=device.token" CHALLENGE_REQUEST_2000 = \ "POST /v5/challenge HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "Accept: */*\r\n" \ "User-Agent: libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 20.5.4.0)\r\n" \ "Content-Type: application/x-www-form-urlencoded\r\n" \ "Content-Length: 30\r\n\r\n" \ "device_auth_token=device.token" GAMECARD_REQUEST_1300 = \ "POST /v3/application_auth_token HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "User-Agent: libcurl (nnHttp; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 13.3.0.0; Add-on 13.3.0.0)\r\n" \ "Accept: */*\r\n" \ "X-Nintendo-PowerState: FA\r\n" \ "Content-Length: 132\r\n" \ "Content-Type: application/x-www-form-urlencoded\r\n\r\n" \ "application_id=0100123001234000&application_version=00070000&device_auth_token=device.token&media_type=GAMECARD&gvt=Z3Z0&cert=Y2VydA" GAMECARD_REQUEST_1900 = \ "POST /v5/application_auth_token HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "Accept: */*\r\n" \ "Content-Type: application/x-www-form-urlencoded\r\n" \ "X-Nintendo-PowerState: FA\r\n" \ "Content-Length: 179\r\n\r\n" \ "application_id=0100123001234000&application_version=00070000&device_auth_token=device.token&auth_type=GAMECARD&gvt=Z3Z0&cert=Y2VydA&challenge=challenge&challenge_src=challenge_src" GAMECARD_REQUEST_2000 = \ "POST /v5/application_auth_token HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "Accept: */*\r\n" \ "User-Agent: libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 20.5.4.0)\r\n" \ "Content-Type: application/x-www-form-urlencoded\r\n" \ "X-Nintendo-PowerState: FA\r\n" \ "Content-Length: 179\r\n\r\n" \ "application_id=0100123001234000&application_version=00070000&device_auth_token=device.token&auth_type=GAMECARD&gvt=Z3Z0&cert=Y2VydA&challenge=challenge&challenge_src=challenge_src" CERT = struct.pack("Q", 0x0100123001234000) CERT += bytes(0x18) @pytest.mark.anyio async def test_aauth_1300(): async def handler(client, request): text = request.encode().decode() assert text.startswith(TOKEN_REQUEST_1300) assert text[1375:1385] == "&cert_key=" response = http.HTTPResponse(200) response.json = { "application_auth_token": "application token" } return response async with http.serve(handler, "localhost", 12345): client = aauth.AAuthClient() client.set_host("localhost:12345") client.set_system_version(1300) client.set_context(None) response = await client.auth_digital( 0x0100123001234000, 0x70000, "device.token", CERT ) assert response["application_auth_token"] == "application token" @pytest.mark.anyio async def test_aauth_1500(): async def handler(client, request): assert request.encode().decode() == TOKEN_REQUEST_1500 response = http.HTTPResponse(200) response.json = { "application_auth_token": "application token" } return response async with http.serve(handler, "localhost", 12345): client = aauth.AAuthClient() client.set_host("localhost:12345") client.set_system_version(1500) client.set_context(None) response = await client.auth_digital( 0x0100123001234000, 0x70000, "device.token", "token.from.dragons" ) assert response["application_auth_token"] == "application token" @pytest.mark.anyio async def test_aauth_1800(): async def handler(client, request): assert request.encode().decode() == TOKEN_REQUEST_1800 response = http.HTTPResponse(200) response.json = { "application_auth_token": "application token" } return response async with http.serve(handler, "localhost", 12345): client = aauth.AAuthClient() client.set_host("localhost:12345") client.set_system_version(1800) client.set_context(None) response = await client.auth_digital( 0x0100123001234000, 0x70000, "device.token", "token.from.dragons" ) assert response["application_auth_token"] == "application token" @pytest.mark.anyio async def test_aauth_1900(): async def handler(client, request): assert request.encode().decode() == TOKEN_REQUEST_1900 response = http.HTTPResponse(200) response.json = { "application_auth_token": "application token" } return response async with http.serve(handler, "localhost", 12345): client = aauth.AAuthClient() client.set_host("localhost:12345") client.set_system_version(1900) client.set_context(None) response = await client.auth_digital( 0x0100123001234000, 0x70000, "device.token", "token.from.dragons" ) assert response["application_auth_token"] == "application token" @pytest.mark.anyio async def test_challenge_1300(): async def handler(client, request): text = request.encode().decode() assert text == CHALLENGE_REQUEST_1300 response = http.HTTPResponse(200) response.json = { "seed": "seed", "value": "value" } return response async with http.serve(handler, "localhost", 12345): client = aauth.AAuthClient() client.set_host("localhost:12345") client.set_system_version(1300) client.set_context(None) response = await client.challenge("device.token") assert response["seed"] == "seed" @pytest.mark.anyio async def test_challenge_1900(): async def handler(client, request): text = request.encode().decode() assert text == CHALLENGE_REQUEST_1900 response = http.HTTPResponse(200) response.json = { "challenge": "challenge", "challenge_src": "challenge_src", "seed": "seed", } return response async with http.serve(handler, "localhost", 12345): client = aauth.AAuthClient() client.set_host("localhost:12345") client.set_system_version(1900) client.set_context(None) response = await client.challenge("device.token") assert response["seed"] == "seed" @pytest.mark.anyio async def test_challenge_2000(): async def handler(client, request): text = request.encode().decode() assert text == CHALLENGE_REQUEST_2000 response = http.HTTPResponse(200) response.json = { "challenge": "challenge", "challenge_src": "challenge_src", "seed": "seed", } return response async with http.serve(handler, "localhost", 12345): client = aauth.AAuthClient() client.set_host("localhost:12345") client.set_system_version(2000) client.set_context(None) response = await client.challenge("device.token") assert response["seed"] == "seed" @pytest.mark.anyio async def test_gamecard_1300(): async def handler(client, request): text = request.encode().decode() assert text == GAMECARD_REQUEST_1300 response = http.HTTPResponse(200) response.json = { "application_auth_token": "application token" } return response async with http.serve(handler, "localhost", 12345): client = aauth.AAuthClient() client.set_host("localhost:12345") client.set_system_version(1300) client.set_context(None) response = await client.auth_gamecard( 0x0100123001234000, 0x70000, "device.token", b"cert", b"gvt" ) assert response["application_auth_token"] == "application token" @pytest.mark.anyio async def test_gamecard_1900(): async def handler(client, request): text = request.encode().decode() assert text == GAMECARD_REQUEST_1900 response = http.HTTPResponse(200) response.json = { "application_auth_token": "application token" } return response async with http.serve(handler, "localhost", 12345): client = aauth.AAuthClient() client.set_host("localhost:12345") client.set_system_version(1900) client.set_context(None) response = await client.auth_gamecard( 0x0100123001234000, 0x70000, "device.token", b"cert", b"gvt", "challenge", "challenge_src" ) assert response["application_auth_token"] == "application token" @pytest.mark.anyio async def test_gamecard_2000(): async def handler(client, request): text = request.encode().decode() assert text == GAMECARD_REQUEST_2000 response = http.HTTPResponse(200) response.json = { "application_auth_token": "application token" } return response async with http.serve(handler, "localhost", 12345): client = aauth.AAuthClient() client.set_host("localhost:12345") client.set_system_version(2000) client.set_context(None) response = await client.auth_gamecard( 0x0100123001234000, 0x70000, "device.token", b"cert", b"gvt", "challenge", "challenge_src" ) assert response["application_auth_token"] == "application token" @pytest.mark.anyio async def test_aauth_error(): async def handler(client, request): response = http.HTTPResponse(400) response.json = { "errors": [{"code": "0118", "message": "Invalid parameter in request."}] } return response async with http.serve(handler, "localhost", 12345): client = aauth.AAuthClient() client.set_host("localhost:12345") client.set_system_version(1500) client.set_context(None) with pytest.raises(aauth.AAuthError): await client.auth_nocert(0, 0, "device.token") ================================================ FILE: tests/switch/test_atumn.py ================================================ from nintendo.switch import atumn from anynet import http import pytest TEST_DEVICE_ID = 0x6265ca40780b1c0d TEST_SYSTEM_UPDATE_TITLE_ID = 0x0100000000000816 TEST_SYSTEM_UPDATE_TITLE_VERSION = 1140851708 TEST_TITLE_ID = 0x0100000000000006 TEST_TITLE_VERSION = 1140851648 TEST_CONTENT_ID = "e3a44d36db9756202bef1dcd3bfb65ef" SYSTEM_UPDATE_HEAD_REQUEST = \ "HEAD /t/s/0100000000000816/1140851708?device_id=6265ca40780b1c0d HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "Accept: */*\r\n" \ "User-Agent: NintendoSDK Firmware/17.0.0-6.0 (platform:NX; did:6265ca40780b1c0d; eid:lp1)\r\n" \ "\r\n" SYSTEM_UPDATE_GET_REQUEST = \ "GET /c/s/170ca33980ff8e9cdad31c6add0f38b6 HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "Accept: */*\r\n" \ "User-Agent: NintendoSDK Firmware/17.0.0-6.0 (platform:NX; did:6265ca40780b1c0d; eid:lp1)\r\n" \ "\r\n" SYSTEM_TITLE_HEAD_REQUEST = \ "HEAD /t/a/0100000000000006/1140851648?device_id=6265ca40780b1c0d HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "Accept: */*\r\n" \ "User-Agent: NintendoSDK Firmware/17.0.0-6.0 (platform:NX; did:6265ca40780b1c0d; eid:lp1)\r\n" \ "\r\n" SYSTEM_TITLE_GET_REQUEST = \ "GET /c/a/aa4c1492ab0ab849fbc1002eb3ecc784 HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "Accept: */*\r\n" \ "User-Agent: NintendoSDK Firmware/17.0.0-6.0 (platform:NX; did:6265ca40780b1c0d; eid:lp1)\r\n" \ "\r\n" CONTENT_REQUEST = \ "GET /c/c/e3a44d36db9756202bef1dcd3bfb65ef HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "Accept: */*\r\n" \ "User-Agent: NintendoSDK Firmware/17.0.0-6.0 (platform:NX; did:6265ca40780b1c0d; eid:lp1)\r\n" \ "\r\n" @pytest.mark.anyio async def test_download_content_metadata_system_update(): async def handler(client, request): data = request.encode().decode() if data == SYSTEM_UPDATE_HEAD_REQUEST: response = http.HTTPResponse(200) response.headers = { "X-Nintendo-Content-ID": "170ca33980ff8e9cdad31c6add0f38b6" } return response elif data == SYSTEM_UPDATE_GET_REQUEST: response = http.HTTPResponse(200) response.body = b"test data" return response else: raise ValueError("Incorrect request") async with http.serve(handler, "localhost", 12345): client = atumn.AtumnClient(TEST_DEVICE_ID) client.set_host("localhost:12345") client.set_system_version(1700) client.set_context(None) response = await client.download_content_metadata( TEST_SYSTEM_UPDATE_TITLE_ID, TEST_SYSTEM_UPDATE_TITLE_VERSION, system_update=True ) assert response == b"test data" @pytest.mark.anyio async def test_download_content_metadata_normal_title(): async def handler(client, request): data = request.encode().decode() if data == SYSTEM_TITLE_HEAD_REQUEST: response = http.HTTPResponse(200) response.headers = { "X-Nintendo-Content-ID": "aa4c1492ab0ab849fbc1002eb3ecc784" } return response elif data == SYSTEM_TITLE_GET_REQUEST: response = http.HTTPResponse(200) response.body = b"test data" return response else: raise ValueError("Incorrect request") async with http.serve(handler, "localhost", 12345): client = atumn.AtumnClient(TEST_DEVICE_ID) client.set_host("localhost:12345") client.set_system_version(1700) client.set_context(None) response = await client.download_content_metadata( TEST_TITLE_ID, TEST_TITLE_VERSION ) assert response == b"test data" @pytest.mark.anyio async def test_download_content(): async def handler(client, request): data = request.encode().decode() assert data == CONTENT_REQUEST response = http.HTTPResponse(200) response.body = b"test data" return response async with http.serve(handler, "localhost", 12345): client = atumn.AtumnClient(TEST_DEVICE_ID) client.set_host("localhost:12345") client.set_system_version(1700) client.set_context(None) response = await client.download_content(TEST_CONTENT_ID) assert response == b"test data" ================================================ FILE: tests/switch/test_baas.py ================================================ from nintendo.switch import baas from anynet import http import pytest import struct AUTHENTICATE_REQUEST_1200 = \ "POST /1.0.0/application/token HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "User-Agent: libcurl (nnAccount; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 12.3.0.0; Add-on 12.3.0.0)\r\n" \ "Accept: */*\r\n" \ "X-Nintendo-PowerState: FA\r\n" \ "Content-Length: 46\r\n" \ "Content-Type: application/x-www-form-urlencoded\r\n\r\n" \ "grantType=public_client&assertion=device.token" AUTHENTICATE_REQUEST_1900 = \ "POST /1.0.0/application/token HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "User-Agent: libcurl (nnAccount; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 19.3.0.0; Add-on 19.3.0.0)\r\n" \ "Accept: */*\r\n" \ "X-Nintendo-PowerState: FA\r\n" \ "Content-Length: 62\r\n" \ "Content-Type: application/x-www-form-urlencoded\r\n\r\n" \ "grantType=public_client&assertion=device.token&penneId=penneId" AUTHENTICATE_REQUEST_2000 = \ "POST /1.0.0/application/token HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "User-Agent: libcurl (nnAccount; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 20.5.4.0; Add-on 20.5.4.0)\r\n" \ "Accept: */*\r\n" \ "X-Nintendo-PowerState: FA\r\n" \ "Content-Length: 62\r\n" \ "Content-Type: application/x-www-form-urlencoded\r\n\r\n" \ "grantType=public_client&assertion=device.token&penneId=penneId" LOGIN_REQUEST_1200 = \ "POST /1.0.0/login HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "User-Agent: libcurl (nnAccount; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 12.3.0.0; Add-on 12.3.0.0)\r\n" \ "Accept: */*\r\n" \ "Authorization: Bearer access.token\r\n" \ "X-Nintendo-PowerState: FA\r\n" \ "Content-Length: 93\r\n" \ "Content-Type: application/x-www-form-urlencoded\r\n\r\n" \ "id=1234567890abcdef&" \ "password=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&" \ "appAuthNToken=app.token" LOGIN_REQUEST_2000 = \ "POST /1.0.0/login HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "User-Agent: libcurl (nnAccount; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 20.5.4.0; Add-on 20.5.4.0)\r\n" \ "Accept: */*\r\n" \ "Authorization: Bearer access.token\r\n" \ "X-Nintendo-PowerState: FA\r\n" \ "Content-Length: 124\r\n" \ "Content-Type: application/x-www-form-urlencoded\r\n\r\n" \ "id=1234567890abcdef&password=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&appAuthNToken=app.token&naCountry=NL&isPersistent=true" LOGIN_REQUEST_2110 = \ "POST /1.0.0/login HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "Accept: */*\r\n" \ "User-Agent: libcurl (nnAccount; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 21.4.0.0; Add-on 21.4.0.0)\r\n" \ "Content-Type: application/x-www-form-urlencoded\r\n" \ "Authorization: Bearer access.token\r\n" \ "X-Nintendo-PowerState: FA\r\n" \ "Content-Length: 124\r\n\r\n" \ "id=1234567890abcdef&password=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&appAuthNToken=app.token&naCountry=NL&isPersistent=true" REGISTER_REQUEST = \ "POST /1.0.0/users HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "User-Agent: libcurl (nnAccount; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 15.3.0.0; Add-on 15.3.0.0)\r\n" \ "Accept: */*\r\n" \ "Authorization: Bearer access.token\r\n" \ "Content-Length: 0\r\n" \ "Content-Type: application/x-www-form-urlencoded\r\n" \ "\r\n" UPDATE_PRESENCE_REQUEST_1500 = \ "PATCH /1.0.0/users/aaaaaaaaaaaaaaaa/device_accounts/bbbbbbbbbbbbbbbb HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "User-Agent: libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 15.3.0.0; Add-on 15.3.0.0)\r\n" \ "Accept: */*\r\n" \ "Content-Type: application/json-patch+json\r\n" \ "Authorization: Bearer access.token\r\n" \ "Content-Length: 315\r\n" \ "\r\n" \ '[{"op":"replace","path":"/presence/state","value":"ONLINE"},' \ '{"op":"add","path":"/presence/extras/friends/appField","value":"{}"},' \ '{"op":"add","path":"/presence/extras/friends/appInfo:appId","value":"010040600c5ce000"},' \ '{"op":"add","path":"/presence/extras/friends/appInfo:presenceGroupId","value":"010040600c5ce000"}]' UPDATE_PRESENCE_REQUEST_1900 = \ "PATCH /1.0.0/users/aaaaaaaaaaaaaaaa/device_accounts/bbbbbbbbbbbbbbbb HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "User-Agent: libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 19.3.0.0; Add-on 19.3.0.0)\r\n" \ "Accept: */*\r\n" \ "Content-Type: application/json-patch+json\r\n" \ "Authorization: Bearer access.token\r\n" \ "Content-Length: 389\r\n" \ "\r\n" \ '[{"op":"replace","path":"/presence/state","value":"ONLINE"},' \ '{"op":"add","path":"/presence/extras/friends/appField","value":"{}"},' \ '{"op":"add","path":"/presence/extras/friends/appInfo:appId","value":"010040600c5ce000"},' \ '{"op":"add","path":"/presence/extras/friends/appInfo:acdIndex","value":0},' \ '{"op":"add","path":"/presence/extras/friends/appInfo:presenceGroupId","value":"010040600c5ce000"}]' GET_FRIENDS_REQUEST = \ "GET /2.0.0/users/aaaaaaaaaaaaaaaa/friends?count=300 HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "User-Agent: libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 15.3.0.0; Add-on 15.3.0.0)\r\n" \ "Accept: */*\r\n" \ "Authorization: Bearer access.token\r\n" \ "\r\n" @pytest.mark.anyio async def test_authenticate_1200(): async def handler(client, request): assert request.encode().decode() == AUTHENTICATE_REQUEST_1200 response = http.HTTPResponse(200) response.json = { "accessToken": "access.token" } return response async with http.serve(handler, "localhost", 12345): client = baas.BAASClient() client.set_host("localhost:12345") client.set_system_version(1200) client.set_context(None) response = await client.authenticate("device.token") assert response["accessToken"] == "access.token" @pytest.mark.anyio async def test_authenticate_1900(): async def handler(client, request): assert request.encode().decode() == AUTHENTICATE_REQUEST_1900 response = http.HTTPResponse(200) response.json = { "accessToken": "access.token" } return response async with http.serve(handler, "localhost", 12345): client = baas.BAASClient() client.set_host("localhost:12345") client.set_system_version(1900) client.set_context(None) response = await client.authenticate("device.token", "penneId") assert response["accessToken"] == "access.token" @pytest.mark.anyio async def test_authenticate_2000(): async def handler(client, request): assert request.encode().decode() == AUTHENTICATE_REQUEST_2000 response = http.HTTPResponse(200) response.json = { "accessToken": "access.token" } return response async with http.serve(handler, "localhost", 12345): client = baas.BAASClient() client.set_host("localhost:12345") client.set_system_version(2000) client.set_context(None) response = await client.authenticate("device.token", "penneId") assert response["accessToken"] == "access.token" @pytest.mark.anyio async def test_login_1200(): async def handler(client, request): assert request.encode().decode() == LOGIN_REQUEST_1200 response = http.HTTPResponse(200) response.json = { "idToken": "id.token" } return response async with http.serve(handler, "localhost", 12345): client = baas.BAASClient() client.set_host("localhost:12345") client.set_system_version(1200) client.set_context(None) response = await client.login( 0x1234567890abcdef, "a" * 40, "access.token", "app.token" ) assert response["idToken"] == "id.token" @pytest.mark.anyio async def test_login_2000(): async def handler(client, request): assert request.encode().decode() == LOGIN_REQUEST_2000 response = http.HTTPResponse(200) response.json = { "idToken": "id.token" } return response async with http.serve(handler, "localhost", 12345): client = baas.BAASClient() client.set_host("localhost:12345") client.set_system_version(2000) client.set_context(None) response = await client.login( 0x1234567890abcdef, "a" * 40, "access.token", "app.token", "NL" ) assert response["idToken"] == "id.token" @pytest.mark.anyio async def test_login_2110(): async def handler(client, request): assert request.encode().decode() == LOGIN_REQUEST_2110 response = http.HTTPResponse(200) response.json = { "idToken": "id.token" } return response async with http.serve(handler, "localhost", 12345): client = baas.BAASClient() client.set_host("localhost:12345") client.set_system_version(2110) client.set_context(None) response = await client.login( 0x1234567890abcdef, "a" * 40, "access.token", "app.token", "NL" ) assert response["idToken"] == "id.token" @pytest.mark.anyio async def test_register(): async def handler(client, request): assert request.encode().decode() == REGISTER_REQUEST return http.HTTPResponse(200) async with http.serve(handler, "localhost", 12345): client = baas.BAASClient() client.set_host("localhost:12345") client.set_system_version(1500) client.set_context(None) await client.register("access.token") @pytest.mark.anyio async def test_update_presence_1500(): async def handler(client, request): assert request.encode().decode() == UPDATE_PRESENCE_REQUEST_1500 return http.HTTPResponse(200) async with http.serve(handler, "localhost", 12345): client = baas.BAASClient() client.set_host("localhost:12345") client.set_system_version(1500) client.set_context(None) await client.update_presence( 0xaaaaaaaaaaaaaaaa, 0xbbbbbbbbbbbbbbbb, "access.token", baas.PresenceState.ONLINE, 0x010040600c5ce000, 0x010040600c5ce000 ) @pytest.mark.anyio async def test_update_presence_1900(): async def handler(client, request): assert request.encode().decode() == UPDATE_PRESENCE_REQUEST_1900 return http.HTTPResponse(200) async with http.serve(handler, "localhost", 12345): client = baas.BAASClient() client.set_host("localhost:12345") client.set_system_version(1900) client.set_context(None) await client.update_presence( 0xaaaaaaaaaaaaaaaa, 0xbbbbbbbbbbbbbbbb, "access.token", baas.PresenceState.ONLINE, 0x010040600c5ce000, 0x010040600c5ce000 ) @pytest.mark.anyio async def test_get_friends(): async def handler(client, request): assert request.encode().decode() == GET_FRIENDS_REQUEST return http.HTTPResponse(200) async with http.serve(handler, "localhost", 12345): client = baas.BAASClient() client.set_host("localhost:12345") client.set_system_version(1500) client.set_context(None) await client.get_friends(0xaaaaaaaaaaaaaaaa, "access.token") ================================================ FILE: tests/switch/test_dauth.py ================================================ from nintendo.switch import dauth from anynet import http import pytest CHALLENGE_REQUEST_1200 = \ "POST /v6/challenge HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "User-Agent: libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 12.3.0.0)\r\n" \ "Accept: */*\r\n" \ "X-Nintendo-PowerState: FA\r\n" \ "Content-Length: 17\r\n" \ "Content-Type: application/x-www-form-urlencoded\r\n\r\n" \ "key_generation=11" CHALLENGE_REQUEST_1300 = \ "POST /v7/challenge HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "User-Agent: libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 13.3.0.0)\r\n" \ "Accept: */*\r\n" \ "X-Nintendo-PowerState: FA\r\n" \ "Content-Length: 17\r\n" \ "Content-Type: application/x-www-form-urlencoded\r\n\r\n" \ "key_generation=13" CHALLENGE_REQUEST_1800 = \ "POST /v7/challenge HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "Accept: */*\r\n" \ "Content-Type: application/x-www-form-urlencoded\r\n" \ "X-Nintendo-PowerState: FA\r\n" \ "Content-Length: 17\r\n\r\n" \ "key_generation=17" CHALLENGE_REQUEST_2000 = \ "POST /v8/challenge HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "Accept: */*\r\n" \ "User-Agent: libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 20.5.4.0)\r\n" \ "Content-Type: application/x-www-form-urlencoded\r\n" \ "X-Nintendo-PowerState: FA\r\n" \ "Content-Length: 17\r\n\r\n" \ "key_generation=20" TOKEN_REQUEST_1200 = \ "POST /v6/device_auth_token HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "User-Agent: libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 12.3.0.0)\r\n" \ "Accept: */*\r\n" \ "X-Nintendo-PowerState: FA\r\n" \ "Content-Length: 211\r\n" \ "Content-Type: application/x-www-form-urlencoded\r\n\r\n" \ "challenge=vaNgVZZH7gUse0y3t8Cksuln-TAVtvBmcD-ow59qp0E=&" \ "client_id=8f849b5d34778d8e&ist=false&key_generation=11&" \ "system_version=CusHY#000c0000#C-BynYNPXdQJNBZjx02Hizi8lRUSIKLwPGa5p8EY1uo=&" \ "mac=xRB_6mgnNqrnF9DRsEpYMg" DEVICE_TOKEN_REQUEST_1300 = \ "POST /v7/device_auth_token HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "User-Agent: libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 13.3.0.0)\r\n" \ "Accept: */*\r\n" \ "X-Nintendo-PowerState: FA\r\n" \ "Content-Length: 211\r\n" \ "Content-Type: application/x-www-form-urlencoded\r\n\r\n" \ "challenge=TzJ0EB3EvsWvQI5aPj15uaNVH9paGdsWB4l-eI5uzW0=&" \ "client_id=8f849b5d34778d8e&ist=false&key_generation=13&" \ "system_version=CusHY#000d0000#r1xneESd4PiTRYIhVIl0bK1ST5L5BUmv_uGPLqc4PPo=&" \ "mac=dGMjt0ShsDr-uNrsHtCB1g" DEVICE_TOKEN_REQUEST_1800 = \ "POST /v7/device_auth_token HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "Accept: */*\r\n" \ "Content-Type: application/x-www-form-urlencoded\r\n" \ "X-Nintendo-PowerState: FA\r\n" \ "Content-Length: 211\r\n\r\n" \ "challenge=TzJ0EB3EvsWvQI5aPj15uaNVH9paGdsWB4l-eI5uzW0=&" \ "client_id=8f849b5d34778d8e&ist=false&key_generation=17&" \ "system_version=CusHY#00120000#U531L4Si9RbhOVeyVppe18WHkJ0k4_KzrNtygsekMNo=&" \ "mac=c4SgqSjdfdNFoRM35ChrLw" DEVICE_TOKEN_REQUEST_2000 = \ "POST /v8/device_auth_tokens HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "Accept: */*\r\n" \ "User-Agent: libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 20.5.4.0)\r\n" \ "Content-Type: application/json\r\n" \ "X-Nintendo-PowerState: FA\r\n" \ "Content-Length: 293\r\n\r\n" \ '{"system_version":"00140000","fw_revision":"7147e1386c9b6c15d8f14e6ed68c4b9a7f28fb9b","ist":false,"token_requests":[{"client_id":"8f849b5d34778d8e"},{"client_id":"dc656ea03b63cf68"}],"key_generation":20,"challenge":"TzJ0EB3EvsWvQI5aPj15uaNVH9paGdsWB4l-eI5uzW0=","mac":"49YDQDn9UTq6iQGMdW5B8Q"}' EDGE_TOKEN_REQUEST_2000 = \ "POST /v8/edge_tokens HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "Accept: */*\r\n" \ "User-Agent: libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 20.5.4.0)\r\n" \ "Content-Type: application/json\r\n" \ "X-Nintendo-PowerState: FA\r\n" \ "Content-Length: 335\r\n\r\n" \ '{"system_version":"00140000","fw_revision":"7147e1386c9b6c15d8f14e6ed68c4b9a7f28fb9b","ist":false,"token_requests":[{"client_id":"93af0acb26258de9","vendor_id":"akamai"},{"client_id":"67bf9945b45248c6","vendor_id":"akamai"}],"key_generation":20,"challenge":"TzJ0EB3EvsWvQI5aPj15uaNVH9paGdsWB4l-eI5uzW0=","mac":"bB8LFaSTRsZtrWQD9Ew1-Q"}' @pytest.mark.anyio async def test_dauth_1200(): async def handler(client, request): if request.path == "/v6/challenge": assert request.encode().decode() == CHALLENGE_REQUEST_1200 response = http.HTTPResponse(200) response.json = { "challenge": "vaNgVZZH7gUse0y3t8Cksuln-TAVtvBmcD-ow59qp0E=", "data": "dlL7ZBNSLmYo1hUlKYZiUA==" } return response else: assert request.encode().decode() == TOKEN_REQUEST_1200 response = http.HTTPResponse(200) response.json = { "device_auth_token": "device token" } return response async with http.serve(handler, "localhost", 12345): keys = { "aes_kek_generation_source": bytes.fromhex("485d45ad27c07c7e538c0183f90ee845"), "master_key_0a": bytes.fromhex("37eed242e0f2ce6f8371e783c1a6a0ae") } client = dauth.DAuthClient(keys) client.set_host("localhost:12345") client.set_system_version(1200) client.set_context(None) response = await client.device_token(dauth.CLIENT_ID_BAAS) token = response["device_auth_token"] assert token == "device token" @pytest.mark.anyio async def test_dauth_1300(): async def handler(client, request): if request.path == "/v7/challenge": assert request.encode().decode() == CHALLENGE_REQUEST_1300 response = http.HTTPResponse(200) response.json = { "challenge": "TzJ0EB3EvsWvQI5aPj15uaNVH9paGdsWB4l-eI5uzW0=", "data": "4SxW91vqVg6pz4CXMH2Ouw==" } return response else: assert request.encode().decode() == DEVICE_TOKEN_REQUEST_1300 response = http.HTTPResponse(200) response.json = { "device_auth_token": "device token" } return response async with http.serve(handler, "localhost", 12345): keys = { "aes_kek_generation_source": bytes.fromhex("cae2728f56af642d5d59dfc23bd314a2"), "master_key_0c": bytes.fromhex("f1642c98bddb5850eb23d0cebab7dc05") } client = dauth.DAuthClient(keys) client.set_host("localhost:12345") client.set_system_version(1300) client.set_context(None) response = await client.device_token(dauth.CLIENT_ID_BAAS) token = response["device_auth_token"] assert token == "device token" @pytest.mark.anyio async def test_dauth_1800(): async def handler(client, request): if request.path == "/v7/challenge": assert request.encode().decode() == CHALLENGE_REQUEST_1800 response = http.HTTPResponse(200) response.json = { "challenge": "TzJ0EB3EvsWvQI5aPj15uaNVH9paGdsWB4l-eI5uzW0=", "data": "4SxW91vqVg6pz4CXMH2Ouw==" } return response else: assert request.encode().decode() == DEVICE_TOKEN_REQUEST_1800 response = http.HTTPResponse(200) response.json = { "device_auth_token": "device token" } return response async with http.serve(handler, "localhost", 12345): keys = { "aes_kek_generation_source": bytes.fromhex("1092ce3d2c208c250ebe248537f2df73"), "master_key_10": bytes.fromhex("2fcb5dd5355a220a12eaeb8069bb75e1") } client = dauth.DAuthClient(keys) client.set_host("localhost:12345") client.set_system_version(1800) client.set_context(None) response = await client.device_token(dauth.CLIENT_ID_BAAS) token = response["device_auth_token"] assert token == "device token" @pytest.mark.anyio async def test_dauth_2000(): async def handler(client, request): if request.path == "/v8/challenge": assert request.encode().decode() == CHALLENGE_REQUEST_2000 response = http.HTTPResponse(200) response.json = { "challenge": "TzJ0EB3EvsWvQI5aPj15uaNVH9paGdsWB4l-eI5uzW0=", "data": "4SxW91vqVg6pz4CXMH2Ouw==" } return response else: assert request.encode().decode() == DEVICE_TOKEN_REQUEST_2000 response = http.HTTPResponse(200) response.json = {"results": []} return response async with http.serve(handler, "localhost", 12345): keys = { "aes_kek_generation_source": bytes.fromhex("1092ce3d2c208c250ebe248537f2df73"), "master_key_13": bytes.fromhex("f09f742cf07cceb584410e13c507e27e") } client = dauth.DAuthClient(keys) client.set_host("localhost:12345") client.set_system_version(2000) client.set_context(None) await client.device_tokens([ dauth.CLIENT_ID_BAAS, dauth.CLIENT_ID_PCTL ]) @pytest.mark.anyio async def test_edge_token_2000(): async def handler(client, request): if request.path == "/v8/challenge": assert request.encode().decode() == CHALLENGE_REQUEST_2000 response = http.HTTPResponse(200) response.json = { "challenge": "TzJ0EB3EvsWvQI5aPj15uaNVH9paGdsWB4l-eI5uzW0=", "data": "4SxW91vqVg6pz4CXMH2Ouw==" } return response else: assert request.encode().decode() == EDGE_TOKEN_REQUEST_2000 response = http.HTTPResponse(200) response.json = {"results": []} return response async with http.serve(handler, "localhost", 12345): keys = { "aes_kek_generation_source": bytes.fromhex("1092ce3d2c208c250ebe248537f2df73"), "master_key_13": bytes.fromhex("f09f742cf07cceb584410e13c507e27e") } client = dauth.DAuthClient(keys) client.set_host("localhost:12345") client.set_system_version(2000) client.set_context(None) await client.edge_tokens([ (dauth.CLIENT_ID_BEACH, "akamai"), (dauth.CLIENT_ID_BCAT, "akamai") ]) @pytest.mark.anyio async def test_dauth_error(): async def handler(client, request): response = http.HTTPResponse(400) response.json = { "errors": [{"code": "0014", "message": "Invalid parameter in request."}] } return response async with http.serve(handler, "localhost", 12345): client = dauth.DAuthClient({}) client.set_host("localhost:12345") client.set_system_version(1300) client.set_context(None) try: await client.challenge() except dauth.DAuthError as e: assert e.code == dauth.DAuthError.GENERIC else: pytest.fail("DAuth client should have raised an exception") ================================================ FILE: tests/switch/test_dragons.py ================================================ from nintendo.switch import dragons from anynet import http import pytest TEST_DEVICE_ID = 0x12345678 TEST_DEVICE_TOKEN = "device.token" TEST_ELICENSE_ID = "337c8aaef372df9c2c239ebaaf49f723" TEST_ACCOUNT_ID = 0x72b0f0bdb31753d5 TEST_APPLICATION_ID = 0x010040600C5CE000 PUBLISH_DEVICE_LINKED_ELICENSES_REQUEST = \ "POST /v1/rights/publish_device_linked_elicenses HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "Accept: */*\r\n" \ "User-Agent: NintendoSDK Firmware/15.0.0-4.0 (platform:NX; did:0000000012345678; eid:lp1)\r\n" \ "DeviceAuthorization: Bearer device.token\r\n" \ "Content-Length: 0\r\n" \ "Content-Type: application/x-www-form-urlencoded\r\n" \ "\r\n" EXERCISE_ELICENSE_REQUEST = \ "POST /v1/elicenses/exercise HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "Accept: */*\r\n" \ "User-Agent: NintendoSDK Firmware/15.0.0-4.0 (platform:NX; did:0000000012345678; eid:lp1)\r\n" \ "DeviceAuthorization: Bearer device.token\r\n" \ "Nintendo-Account-Id: 72b0f0bdb31753d5\r\n" \ "Content-Type: application/json\r\n" \ "Content-Length: 88\r\n" \ "\r\n" \ '{"elicense_ids":["337c8aaef372df9c2c239ebaaf49f723"],"account_ids":["72b0f0bdb31753d5"]}' AAUTH_TOKEN_REQUEST_1500 = \ "POST /v1/contents_authorization_token_for_aauth/issue HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "User-Agent: libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 15.3.0.0)\r\n" \ "Accept: */*\r\n" \ "Content-Type: application/json\r\n" \ "DeviceAuthorization: Bearer device.token\r\n" \ "Nintendo-Application-Id: 010040600c5ce000\r\n" \ "Content-Length: 77\r\n" \ "\r\n" \ '{"elicense_id":"337c8aaef372df9c2c239ebaaf49f723","na_id":"72b0f0bdb31753d5"}' AAUTH_TOKEN_REQUEST_1800 = \ "POST /v1/contents_authorization_token_for_aauth/issue HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "Accept: */*\r\n" \ "Content-Type: application/json\r\n" \ "DeviceAuthorization: Bearer device.token\r\n" \ "Nintendo-Application-Id: 010040600c5ce000\r\n" \ "Content-Length: 77\r\n" \ "\r\n" \ '{"elicense_id":"337c8aaef372df9c2c239ebaaf49f723","na_id":"72b0f0bdb31753d5"}' AAUTH_TOKEN_REQUEST_2000 = \ "POST /v2/contents_authorization_token_for_aauth/issue HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "Accept: */*\r\n" \ "User-Agent: libcurl (nnDauth; 16f4553f-9eee-4e39-9b61-59bc7c99b7c8; SDK 20.5.4.0)\r\n" \ "Content-Type: application/json\r\n" \ "DeviceAuthorization: Bearer device.token\r\n" \ "Nintendo-Application-Id: 010040600c5ce000\r\n" \ "Content-Length: 77\r\n\r\n" \ '{"elicense_id":"337c8aaef372df9c2c239ebaaf49f723","na_id":"72b0f0bdb31753d5"}' @pytest.mark.anyio async def test_publish_device_linked_elicenses(): async def handler(client, request): assert request.encode().decode() == PUBLISH_DEVICE_LINKED_ELICENSES_REQUEST response = http.HTTPResponse(200) response.json = {"elicenses": []} return response async with http.serve(handler, "localhost", 12345): client = dragons.DragonsClient(TEST_DEVICE_ID) client.set_hosts("localhost:12345", None, None) client.set_system_version(1500) client.set_context(None) response = await client.publish_device_linked_elicenses(TEST_DEVICE_TOKEN) assert "elicenses" in response @pytest.mark.anyio async def test_exercise_elicense(): async def handler(client, request): assert request.encode().decode() == EXERCISE_ELICENSE_REQUEST response = http.HTTPResponse(200) return response async with http.serve(handler, "localhost", 12345): client = dragons.DragonsClient(TEST_DEVICE_ID) client.set_hosts("localhost:12345", None, None) client.set_system_version(1500) client.set_context(None) await client.exercise_elicense( TEST_DEVICE_TOKEN, [TEST_ELICENSE_ID], [TEST_ACCOUNT_ID], TEST_ACCOUNT_ID ) @pytest.mark.anyio async def test_contents_authorization_token_for_aauth_1500(): async def handler(client, request): assert request.encode().decode() == AAUTH_TOKEN_REQUEST_1500 response = http.HTTPResponse(200) response.json = { "contents_authorization_token": "auth token" } return response async with http.serve(handler, "localhost", 12345): client = dragons.DragonsClient() client.set_hosts("localhost:12345", None, None) client.set_system_version(1500) client.set_context(None) response = await client.contents_authorization_token_for_aauth( TEST_DEVICE_TOKEN, TEST_ELICENSE_ID, TEST_ACCOUNT_ID, TEST_APPLICATION_ID ) assert response["contents_authorization_token"] == "auth token" @pytest.mark.anyio async def test_contents_authorization_token_for_aauth_1800(): async def handler(client, request): assert request.encode().decode() == AAUTH_TOKEN_REQUEST_1800 response = http.HTTPResponse(200) response.json = { "contents_authorization_token": "auth token" } return response async with http.serve(handler, "localhost", 12345): client = dragons.DragonsClient() client.set_hosts("localhost:12345", None, None) client.set_system_version(1800) client.set_context(None) response = await client.contents_authorization_token_for_aauth( TEST_DEVICE_TOKEN, TEST_ELICENSE_ID, TEST_ACCOUNT_ID, TEST_APPLICATION_ID ) assert response["contents_authorization_token"] == "auth token" @pytest.mark.anyio async def test_contents_authorization_token_for_aauth_2000(): async def handler(client, request): assert request.encode().decode() == AAUTH_TOKEN_REQUEST_2000 response = http.HTTPResponse(200) response.json = { "contents_authorization_token": "auth token" } return response async with http.serve(handler, "localhost", 12345): client = dragons.DragonsClient() client.set_hosts("localhost:12345", None, None) client.set_system_version(2000) client.set_context(None) response = await client.contents_authorization_token_for_aauth( TEST_DEVICE_TOKEN, TEST_ELICENSE_ID, TEST_ACCOUNT_ID, TEST_APPLICATION_ID ) assert response["contents_authorization_token"] == "auth token" ================================================ FILE: tests/switch/test_five.py ================================================ from nintendo.switch import five from anynet import http import pytest UNREAD_INVITATION_COUNT_REQUEST = \ """GET /v1/users/aaaaaaaaaaaaaaaa/invitations/inbox?fields=count&read=false HTTP/1.1 Host: localhost:12345 User-Agent: libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 15.3.0.0; Add-on 15.3.0.0) Accept: */* Authorization: Bearer access token """ GET_INBOX_REQUEST = \ """GET /v1/users/aaaaaaaaaaaaaaaa/invitations/inbox HTTP/1.1 Host: localhost:12345 User-Agent: libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 15.3.0.0; Add-on 15.3.0.0) Accept: */* Authorization: Bearer access token """ GET_INVITATION_GROUP_REQUEST = \ """GET /v1/invitation_groups/12345 HTTP/1.1 Host: localhost:12345 User-Agent: libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 15.3.0.0; Add-on 15.3.0.0) Accept: */* Authorization: Bearer access token """ MARK_ALL_AS_READ_REQUEST = \ """PATCH /v1/users/aaaaaaaaaaaaaaaa/invitations/mark_as_read HTTP/1.1 Host: localhost:12345 User-Agent: libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 15.3.0.0; Add-on 15.3.0.0) Accept: */* Authorization: Bearer access token Content-Length: 0 Content-Type: application/x-www-form-urlencoded """ SEND_INVITATION_REQUEST = \ """POST /v1/invitation_groups HTTP/1.1 Host: localhost:12345 User-Agent: libcurl (nnFriends; 789f928b-138e-4b2f-afeb-1acae821d897; SDK 15.3.0.0; Add-on 15.3.0.0) Accept: */* Content-Type: application/json Authorization: Bearer access token Content-Length: 241 {"receiver_ids":["bbbbbbbbbbbbbbbb"],"application_id":"010036b0034e4000","application_group_id":"010036b0034e4000","application_data":"YXBwbGljYXRpb24gZGF0YQ==","messages":{"ja":"\u4e00\u7dd2\u306b\u904a\u3073\u307e\u3057\u3087\u3046\uff01"},"application_id_match":false}""" def check(handler, version): def decorator(callback): async def function(): client = five.FiveClient() client.set_host("localhost:12345") client.set_system_version(version) client.set_context(None) async with http.serve(handler, "localhost", 12345): await callback(client) return pytest.mark.anyio(function) return decorator def check_simple(version): async def handler(client, request): return http.HTTPResponse(200) return check(handler, version) def check_request(expected_request, version, *, response={}): async def handler(client, request): request.json_options["ensure_ascii"] = False assert request.encode().decode() == expected_request.replace("\n", "\r\n") resp = http.HTTPResponse(200) resp.json = response return resp return check(handler, version) @check_request(UNREAD_INVITATION_COUNT_REQUEST, 1501, response={"count": 0}) async def test_get_unread_invitation_count(client): await client.get_unread_invitation_count("access token", 0xaaaaaaaaaaaaaaaa) @check_request(GET_INBOX_REQUEST, 1501) async def test_get_inbox(client): await client.get_inbox("access token", 0xaaaaaaaaaaaaaaaa) @check_request(GET_INVITATION_GROUP_REQUEST, 1501) async def test_get_invitation_group(client): await client.get_invitation_group("access token", 12345) @check_simple(1501) async def test_mark_as_read(client): await client.mark_as_read("access token", [10000, 10001, 10002]) @check_request(MARK_ALL_AS_READ_REQUEST, 1501) async def test_mark_all_as_read(client): await client.mark_all_as_read("access token", 0xaaaaaaaaaaaaaaaa) @check_request(SEND_INVITATION_REQUEST, 1501) async def test_send_invitation(client): receivers = [0xbbbbbbbbbbbbbbbb] title_id = 0x010036b0034e4000 messages = { # Check if UTF-8 is handled correctly "ja": "\u4e00\u7dd2\u306b\u904a\u3073\u307e\u3057\u3087\u3046\uff01" } await client.send_invitation("access token", receivers, title_id, title_id, b"application data", messages) ================================================ FILE: tests/switch/test_sun.py ================================================ from nintendo.switch import sun from anynet import http import pytest TEST_DEVICE_ID = 0x6265ca40780b1c0d SYSTEM_UPDATE_META_REQUEST = \ "GET /v1/system_update_meta?device_id=6265ca40780b1c0d HTTP/1.1\r\n" \ "Host: localhost:12345\r\n" \ "User-Agent: NintendoSDK Firmware/17.0.0-6.0 (platform:NX; did:6265ca40780b1c0d; eid:lp1)\r\n" \ "Accept: application/json\r\n" \ "\r\n" @pytest.mark.anyio async def test_system_update_meta(): async def handler(client, request): assert request.encode().decode() == SYSTEM_UPDATE_META_REQUEST response = http.HTTPResponse(200) response.json = {"system_update_metas": []} return response async with http.serve(handler, "localhost", 12345): client = sun.SunClient(TEST_DEVICE_ID) client.set_host("localhost:12345") client.set_system_version(1700) client.set_context(None) response = await client.system_update_meta() assert "system_update_metas" in response