Add callback function `ValidateLoginData` on the `ticket-granting` and
`secure-connection` common protocols to allow validation of the given
login data on the `LoginEx` or `RegisterEx` methods. Alongside that, add
a toggle on the `secure-connection` common protocol for enabling or
disabling the insecure `Register` method, like the one for `Login` on
`ticket-granting`.
Also implement the Pretendo token validation inside the globals section,
so that both common protocols can use them. The common protocols include
an option to use the Pretendo token validation `SetPretendoValidation`
on that protocol, but custom handling can be added by setting the
callback function to a custom one.
And finally, replace the error handling on the protocols to set any
errors that aren't related to invalid arguments on `%retval%`. This is
accurate as per previous research, since this is where errors like
maintenace or validation failures get populated.
By default, both of the insecure methods are disabled. That means that
current game servers that use the insecure `Register` method will have
to enable them using `EnableInsecureRegister`. Server implementers
**MUST NOT** enable both of the insecure methods at the same time.
The new `SetPretendoValidation` function expects an AES key as an
argument. This matches with the AES key that is stored on the server
list from the account server, after being hex-decoded. Servers are
expected to set the AES key from an environment variable and validate
that the input provided is valid (the key must be decoded using
`hex.DecodeString` before being provided to the validation fucntion).
The NotificationData methods are used by games to send notifications to
friends about user activity, among others. These notifications are
created or updated using `UpdateNotificationData`, which the server will
register and send to the connected friends (as seen on Mario Tennis Open).
The lifetime of these notifications is the same as the connection of the
user who sends them. That is, when a user sends a notification and then
disconnects, the notifications will be discarded.
All notifications sent over `UpdateNotificationData` are logged inside
the `tracking.notification_data` table to prevent abuse. The type of
these notifications is also constrained to a range of specific values
reserved for game-specific purposes (from 101 to 108).
Implement methods that are needed for Mario Kart 7 communities to work.
Note that support for communities on MK7 is partial since the community
statistics don't load because legacy Ranking isn't implemented. Aside
from that, players can create communities and join others without
issues. Other games which use persistent gatherings may or may not work.
In order to support the `ParticipationCount`, we replace matchmake
session joins with a wrapper which checks if the session is attached to
a community, and if it is, it will increment the participation count of
the player in a new table named `community_participations`. The
`MatchmakeSessionCount` is handled more easily by checking the sessions
that belong to the corresponding community.
A new parameter is also added named `PersistentGatheringCreationMax`
with a default value of 4, as reported and tested on various games. This
allows game servers to change the maximum number of active persistent
gatherings that a player can create. For example, Mario Kart 7 supports
up to 8 persistent gatherings instead of the default of 4.
In Mario Kart 7 there is no limitation on the number of players that can
"join" to a community. That is because they don't really join to it but
they create matchmake sessions linked to the persistent gathering (in
fact, the `MaximumParticipants` parameter on persistent gatherings is
set to 0). Thus, the `participants` parameter is unused in communities
(at least on MK7) and we instead log community participations with a new
tracking table `tracking.participate_community`.
Some changes also had to be done in other places like participant
disconnection handling or gathering registrations in order to implement
persistent gatherings accurately.
As a temporary workaround until real Ranked matchmaking is implemented, attributes[1] is in use, but some games send '' for this. Just skip ranking in that case instead of erroring out.
Assign a new host when the current host is disconnecting from a
gathering. To simplify the implementation, set the owner of the
gathering as the new host.
Fixes Splatoon where the client doesn't transfer the host by
themselves.
Keep tracking on gathering (un)registrations, participants joining and
leaving and host and owner changes. All tracking is managed inside the
database functions except for the host and owner changes.
The `matchmaking.participants` now remains useless from this change at
the moment, so remove it for now.