-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Initial support for persistent gatherings/communities
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.
- Loading branch information
1 parent
bcc53de
commit 25c233f
Showing
38 changed files
with
1,367 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package matchmake_extension | ||
|
||
import ( | ||
"github.com/PretendoNetwork/nex-go/v2" | ||
"github.com/PretendoNetwork/nex-go/v2/types" | ||
common_globals "github.com/PretendoNetwork/nex-protocols-common-go/v2/globals" | ||
match_making_database "github.com/PretendoNetwork/nex-protocols-common-go/v2/match-making/database" | ||
"github.com/PretendoNetwork/nex-protocols-common-go/v2/matchmake-extension/database" | ||
match_making_types "github.com/PretendoNetwork/nex-protocols-go/v2/match-making/types" | ||
matchmake_extension "github.com/PretendoNetwork/nex-protocols-go/v2/matchmake-extension" | ||
) | ||
|
||
func (commonProtocol *CommonProtocol) createCommunity(err error, packet nex.PacketInterface, callID uint32, community match_making_types.PersistentGathering, strMessage types.String) (*nex.RMCMessage, *nex.Error) { | ||
if err != nil { | ||
common_globals.Logger.Error(err.Error()) | ||
return nil, nex.NewError(nex.ResultCodes.Core.InvalidArgument, "change_error") | ||
} | ||
|
||
if !common_globals.CheckValidPersistentGathering(community) { | ||
return nil, nex.NewError(nex.ResultCodes.Core.InvalidArgument, "change_error") | ||
} | ||
|
||
connection := packet.Sender().(*nex.PRUDPConnection) | ||
endpoint := connection.Endpoint().(*nex.PRUDPEndPoint) | ||
|
||
commonProtocol.manager.Mutex.Lock() | ||
|
||
createdPersistentGatherings, nexError := database.GetCreatedPersistentGatherings(commonProtocol.manager, connection.PID()) | ||
if nexError != nil { | ||
commonProtocol.manager.Mutex.Unlock() | ||
return nil, nexError | ||
} | ||
|
||
if createdPersistentGatherings >= commonProtocol.PersistentGatheringCreationMax { | ||
commonProtocol.manager.Mutex.Unlock() | ||
return nil, nex.NewError(nex.ResultCodes.RendezVous.PersistentGatheringCreationMax, "change_error") | ||
} | ||
|
||
nexError = database.CreatePersistentGathering(commonProtocol.manager, connection, &community) | ||
if nexError != nil { | ||
commonProtocol.manager.Mutex.Unlock() | ||
return nil, nexError | ||
} | ||
|
||
// TODO - Is this right? Mario Kart 7 sets 0 max participants | ||
if community.MaximumParticipants > 0 { | ||
_, nexError = match_making_database.JoinGathering(commonProtocol.manager, uint32(community.ID), connection, 1, string(strMessage)) | ||
if nexError != nil { | ||
commonProtocol.manager.Mutex.Unlock() | ||
return nil, nexError | ||
} | ||
} | ||
|
||
commonProtocol.manager.Mutex.Unlock() | ||
|
||
rmcResponseStream := nex.NewByteStreamOut(endpoint.LibraryVersions(), endpoint.ByteStreamSettings()) | ||
|
||
community.ID.WriteTo(rmcResponseStream) | ||
|
||
rmcResponseBody := rmcResponseStream.Bytes() | ||
|
||
rmcResponse := nex.NewRMCSuccess(endpoint, rmcResponseBody) | ||
rmcResponse.ProtocolID = matchmake_extension.ProtocolID | ||
rmcResponse.MethodID = matchmake_extension.MethodCreateCommunity | ||
rmcResponse.CallID = callID | ||
|
||
if commonProtocol.OnAfterCreateCommunity != nil { | ||
go commonProtocol.OnAfterCreateCommunity(packet, community, strMessage) | ||
} | ||
|
||
return rmcResponse, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54 changes: 54 additions & 0 deletions
54
matchmake-extension/database/create_persistent_gathering.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package database | ||
|
||
import ( | ||
"github.com/PretendoNetwork/nex-go/v2" | ||
"github.com/PretendoNetwork/nex-go/v2/types" | ||
common_globals "github.com/PretendoNetwork/nex-protocols-common-go/v2/globals" | ||
match_making_database "github.com/PretendoNetwork/nex-protocols-common-go/v2/match-making/database" | ||
match_making_types "github.com/PretendoNetwork/nex-protocols-go/v2/match-making/types" | ||
pqextended "github.com/PretendoNetwork/pq-extended" | ||
) | ||
|
||
// CreatePersistentGathering creates a new PersistentGathering on the database. No participants are added | ||
func CreatePersistentGathering(manager *common_globals.MatchmakingManager, connection *nex.PRUDPConnection, persistentGathering *match_making_types.PersistentGathering) *nex.Error { | ||
_, nexError := match_making_database.RegisterGathering(manager, connection.PID(), types.NewPID(0), &persistentGathering.Gathering, "PersistentGathering") | ||
if nexError != nil { | ||
return nexError | ||
} | ||
|
||
attribs := make([]uint32, len(persistentGathering.Attribs)) | ||
for i, value := range persistentGathering.Attribs { | ||
attribs[i] = uint32(value) | ||
} | ||
|
||
_, err := manager.Database.Exec(`INSERT INTO matchmaking.persistent_gatherings ( | ||
id, | ||
community_type, | ||
password, | ||
attribs, | ||
application_buffer, | ||
participation_start_date, | ||
participation_end_date | ||
) VALUES ( | ||
$1, | ||
$2, | ||
$3, | ||
$4, | ||
$5, | ||
$6, | ||
$7 | ||
)`, | ||
uint32(persistentGathering.Gathering.ID), | ||
uint32(persistentGathering.CommunityType), | ||
string(persistentGathering.Password), | ||
pqextended.Array(attribs), | ||
[]byte(persistentGathering.ApplicationBuffer), | ||
persistentGathering.ParticipationStartDate.Standard(), | ||
persistentGathering.ParticipationEndDate.Standard(), | ||
) | ||
if err != nil { | ||
return nex.NewError(nex.ResultCodes.Core.Unknown, err.Error()) | ||
} | ||
|
||
return nil | ||
} |
Oops, something went wrong.