Skip to content

feat: NEX 4.x.x compatibility #56

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Aug 16, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions match-making/database/disconnect_participant.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func DisconnectParticipant(manager *common_globals.MatchmakingManager, connectio
// * If the gathering is a PersistentGathering and the gathering isn't set to leave when disconnecting, ignore and continue
//
// TODO - Is the match_making.GatheringFlags.PersistentGathering check correct here?
if uint32(gathering.Flags) & match_making.GatheringFlags.PersistentGathering != 0 || (gatheringType == "PersistentGathering" && uint32(gathering.Flags) & match_making.GatheringFlags.PersistentGatheringLeaveParticipation == 0) {
if uint32(gathering.Flags)&match_making.GatheringFlags.PersistentGathering != 0 || (gatheringType == "PersistentGathering" && uint32(gathering.Flags)&match_making.GatheringFlags.PersistentGatheringLeaveParticipation == 0) {
continue
}

Expand All @@ -67,7 +67,7 @@ func DisconnectParticipant(manager *common_globals.MatchmakingManager, connectio
}

// * If the gathering is a persistent gathering and allows zero users, only remove the participant from the gathering
if uint32(gathering.Flags) & (match_making.GatheringFlags.PersistentGathering | match_making.GatheringFlags.PersistentGatheringAllowZeroUsers) != 0 {
if uint32(gathering.Flags)&(match_making.GatheringFlags.PersistentGathering|match_making.GatheringFlags.PersistentGatheringAllowZeroUsers) != 0 {
continue
}

Expand All @@ -87,7 +87,7 @@ func DisconnectParticipant(manager *common_globals.MatchmakingManager, connectio
// * This flag tells the server to change the matchmake session owner if they disconnect
// * If the flag is not set, delete the session
// * More info: https://nintendo-wiki.pretendo.network/docs/nex/protocols/match-making/types#flags
if uint32(gathering.Flags) & match_making.GatheringFlags.DisconnectChangeOwner == 0 {
if uint32(gathering.Flags)&match_making.GatheringFlags.DisconnectChangeOwner == 0 {
nexError = UnregisterGathering(manager, connection.PID(), uint32(gathering.ID))
if nexError != nil {
common_globals.Logger.Error(nexError.Error())
Expand All @@ -99,8 +99,8 @@ func DisconnectParticipant(manager *common_globals.MatchmakingManager, connectio

oEvent := notifications_types.NewNotificationEvent()
oEvent.PIDSource = connection.PID().Copy().(types.PID)
oEvent.Type = types.NewUInt32(notifications.BuildNotificationType(category, subtype))
oEvent.Param1 = gathering.ID
oEvent.Type = types.UInt32(notifications.BuildNotificationType(category, subtype))
oEvent.Param1 = types.UInt64(gathering.ID)

common_globals.SendNotificationEvent(connection.Endpoint().(*nex.PRUDPEndPoint), oEvent, common_globals.RemoveDuplicates(participants))

Expand All @@ -125,8 +125,8 @@ func DisconnectParticipant(manager *common_globals.MatchmakingManager, connectio

oEvent := notifications_types.NewNotificationEvent()
oEvent.PIDSource = connection.PID().Copy().(types.PID)
oEvent.Type = types.NewUInt32(notifications.BuildNotificationType(category, subtype))
oEvent.Param1 = gathering.ID
oEvent.Type = types.UInt32(notifications.BuildNotificationType(category, subtype))
oEvent.Param1 = types.UInt64(gathering.ID)

// TODO - Should the notification actually be sent to all participants?
common_globals.SendNotificationEvent(connection.Endpoint().(*nex.PRUDPEndPoint), oEvent, common_globals.RemoveDuplicates(participants))
Expand All @@ -144,14 +144,14 @@ func DisconnectParticipant(manager *common_globals.MatchmakingManager, connectio

oEvent := notifications_types.NewNotificationEvent()
oEvent.PIDSource = connection.PID().Copy().(types.PID)
oEvent.Type = types.NewUInt32(notifications.BuildNotificationType(category, subtype))
oEvent.Param1 = gathering.ID
oEvent.Param2 = types.NewUInt32(uint32(connection.PID())) // TODO - This assumes a legacy client. Will not work on the Switch
oEvent.Type = types.UInt32(notifications.BuildNotificationType(category, subtype))
oEvent.Param1 = types.UInt64(gathering.ID)
oEvent.Param2 = types.UInt64(connection.PID())

var participantEndedTargets []uint64

// * When the VerboseParticipants or VerboseParticipantsEx flags are set, all participant notification events are sent to everyone
if uint32(gathering.Flags) & (match_making.GatheringFlags.VerboseParticipants | match_making.GatheringFlags.VerboseParticipantsEx) != 0 {
if uint32(gathering.Flags)&(match_making.GatheringFlags.VerboseParticipants|match_making.GatheringFlags.VerboseParticipantsEx) != 0 {
participantEndedTargets = common_globals.RemoveDuplicates(participants)
} else {
participantEndedTargets = []uint64{uint64(gathering.OwnerPID)}
Expand Down
20 changes: 10 additions & 10 deletions match-making/database/end_gathering_participation.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func EndGatheringParticipation(manager *common_globals.MatchmakingManager, gathe
}

// * If the gathering is a persistent gathering and allows zero users, only remove the participant from the gathering
if uint32(gathering.Flags) & (match_making.GatheringFlags.PersistentGathering | match_making.GatheringFlags.PersistentGatheringAllowZeroUsers) != 0 {
if uint32(gathering.Flags)&(match_making.GatheringFlags.PersistentGathering|match_making.GatheringFlags.PersistentGatheringAllowZeroUsers) != 0 {
return nil
}

Expand All @@ -49,7 +49,7 @@ func EndGatheringParticipation(manager *common_globals.MatchmakingManager, gathe
// * This flag tells the server to change the matchmake session owner if they disconnect
// * If the flag is not set, delete the session
// * More info: https://nintendo-wiki.pretendo.network/docs/nex/protocols/match-making/types#flags
if uint32(gathering.Flags) & match_making.GatheringFlags.DisconnectChangeOwner == 0 {
if uint32(gathering.Flags)&match_making.GatheringFlags.DisconnectChangeOwner == 0 {
nexError = UnregisterGathering(manager, connection.PID(), gatheringID)
if nexError != nil {
return nexError
Expand All @@ -60,8 +60,8 @@ func EndGatheringParticipation(manager *common_globals.MatchmakingManager, gathe

oEvent := notifications_types.NewNotificationEvent()
oEvent.PIDSource = connection.PID().Copy().(types.PID)
oEvent.Type = types.NewUInt32(notifications.BuildNotificationType(category, subtype))
oEvent.Param1 = types.NewUInt32(gatheringID)
oEvent.Type = types.UInt32(notifications.BuildNotificationType(category, subtype))
oEvent.Param1 = types.UInt64(gatheringID)

common_globals.SendNotificationEvent(connection.Endpoint().(*nex.PRUDPEndPoint), oEvent, common_globals.RemoveDuplicates(newParticipants))

Expand All @@ -88,8 +88,8 @@ func EndGatheringParticipation(manager *common_globals.MatchmakingManager, gathe

oEvent := notifications_types.NewNotificationEvent()
oEvent.PIDSource = connection.PID().Copy().(types.PID)
oEvent.Type = types.NewUInt32(notifications.BuildNotificationType(category, subtype))
oEvent.Param1 = types.NewUInt32(gatheringID)
oEvent.Type = types.UInt32(notifications.BuildNotificationType(category, subtype))
oEvent.Param1 = types.UInt64(gatheringID)

// TODO - Should the notification actually be sent to all participants?
common_globals.SendNotificationEvent(connection.Endpoint().(*nex.PRUDPEndPoint), oEvent, common_globals.RemoveDuplicates(participants))
Expand All @@ -106,15 +106,15 @@ func EndGatheringParticipation(manager *common_globals.MatchmakingManager, gathe

oEvent := notifications_types.NewNotificationEvent()
oEvent.PIDSource = connection.PID().Copy().(types.PID)
oEvent.Type = types.NewUInt32(notifications.BuildNotificationType(category, subtype))
oEvent.Param1 = types.NewUInt32(gatheringID)
oEvent.Param2 = types.NewUInt32(uint32((connection.PID()))) // TODO - This assumes a legacy client. Will not work on the Switch
oEvent.Type = types.UInt32(notifications.BuildNotificationType(category, subtype))
oEvent.Param1 = types.UInt64(gatheringID)
oEvent.Param2 = types.UInt64(connection.PID())
oEvent.StrParam = types.NewString(message)

var participationEndedTargets []uint64

// * When the VerboseParticipants or VerboseParticipantsEx flags are set, all participant notification events are sent to everyone
if uint32(gathering.Flags) & (match_making.GatheringFlags.VerboseParticipants | match_making.GatheringFlags.VerboseParticipantsEx) != 0 {
if uint32(gathering.Flags)&(match_making.GatheringFlags.VerboseParticipants|match_making.GatheringFlags.VerboseParticipantsEx) != 0 {
participationEndedTargets = common_globals.RemoveDuplicates(participants)
} else {
participationEndedTargets = []uint64{uint64(gathering.OwnerPID)}
Expand Down
22 changes: 11 additions & 11 deletions match-making/database/join_gathering.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func JoinGathering(manager *common_globals.MatchmakingManager, gatheringID uint3
}

if maxParticipants != 0 {
if uint32(len(participants)) + uint32(vacantParticipants) > maxParticipants {
if uint32(len(participants))+uint32(vacantParticipants) > maxParticipants {
return 0, nex.NewError(nex.ResultCodes.RendezVous.SessionFull, "change_error")
}
}
Expand Down Expand Up @@ -72,7 +72,7 @@ func JoinGathering(manager *common_globals.MatchmakingManager, gatheringID uint3
var participantJoinedTargets []uint64

// * When the VerboseParticipants or VerboseParticipantsEx flags are set, all participant notification events are sent to everyone
if flags & (match_making.GatheringFlags.VerboseParticipants | match_making.GatheringFlags.VerboseParticipantsEx) != 0 {
if flags&(match_making.GatheringFlags.VerboseParticipants|match_making.GatheringFlags.VerboseParticipantsEx) != 0 {
participantJoinedTargets = common_globals.RemoveDuplicates(totalParticipants)
} else {
// * If the new participant is the same as the owner, then we are creating a new gathering.
Expand All @@ -89,28 +89,28 @@ func JoinGathering(manager *common_globals.MatchmakingManager, gatheringID uint3

oEvent := notifications_types.NewNotificationEvent()
oEvent.PIDSource = connection.PID()
oEvent.Type = types.NewUInt32(notifications.BuildNotificationType(notificationCategory, notificationSubtype))
oEvent.Param1 = types.NewUInt32(gatheringID)
oEvent.Param2 = types.NewUInt32(uint32(connection.PID())) // TODO - This assumes a legacy client. Will not work on the Switch
oEvent.Type = types.UInt32(notifications.BuildNotificationType(notificationCategory, notificationSubtype))
oEvent.Param1 = types.UInt64(gatheringID)
oEvent.Param2 = types.UInt64(connection.PID())
oEvent.StrParam = types.NewString(joinMessage)
oEvent.Param3 = types.NewUInt32(uint32(len(totalParticipants)))
oEvent.Param3 = types.UInt64(len(totalParticipants))

common_globals.SendNotificationEvent(connection.Endpoint().(*nex.PRUDPEndPoint), oEvent, participantJoinedTargets)

// * This flag also sends a recap of all currently connected players on the gathering to the participant that is connecting
if flags & match_making.GatheringFlags.VerboseParticipantsEx != 0 {
if flags&match_making.GatheringFlags.VerboseParticipantsEx != 0 {
// TODO - Should this actually be deduplicated?
for _, participant := range common_globals.RemoveDuplicates(participants) {
notificationCategory := notifications.NotificationCategories.Participation
notificationSubtype := notifications.NotificationSubTypes.Participation.NewParticipant

oEvent := notifications_types.NewNotificationEvent()
oEvent.PIDSource = connection.PID()
oEvent.Type = types.NewUInt32(notifications.BuildNotificationType(notificationCategory, notificationSubtype))
oEvent.Param1 = types.NewUInt32(gatheringID)
oEvent.Param2 = types.NewUInt32(uint32(participant)) // TODO - This assumes a legacy client. Will not work on the Switch
oEvent.Type = types.UInt32(notifications.BuildNotificationType(notificationCategory, notificationSubtype))
oEvent.Param1 = types.UInt64(gatheringID)
oEvent.Param2 = types.UInt64(participant)
oEvent.StrParam = types.NewString(joinMessage)
oEvent.Param3 = types.NewUInt32(uint32(len(totalParticipants)))
oEvent.Param3 = types.UInt64(len(totalParticipants))

// * Send the notification to the joining participant
common_globals.SendNotificationEvent(connection.Endpoint().(*nex.PRUDPEndPoint), oEvent, []uint64{uint64(connection.PID())})
Expand Down
32 changes: 16 additions & 16 deletions match-making/database/join_gathering_with_participants.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import (
"slices"

"github.com/PretendoNetwork/nex-go/v2"
"github.com/PretendoNetwork/nex-protocols-go/v2/match-making/constants"
"github.com/PretendoNetwork/nex-go/v2/types"
common_globals "github.com/PretendoNetwork/nex-protocols-common-go/v2/globals"
"github.com/PretendoNetwork/nex-protocols-common-go/v2/match-making/tracking"
match_making "github.com/PretendoNetwork/nex-protocols-go/v2/match-making"
"github.com/PretendoNetwork/nex-protocols-go/v2/match-making/constants"
notifications "github.com/PretendoNetwork/nex-protocols-go/v2/notifications"
notifications_types "github.com/PretendoNetwork/nex-protocols-go/v2/notifications/types"
pqextended "github.com/PretendoNetwork/pq-extended"
Expand All @@ -30,7 +30,7 @@ func JoinGatheringWithParticipants(manager *common_globals.MatchmakingManager, g
}
}

if uint32(len(oldParticipants) + 1 + len(additionalParticipants)) > maxParticipants {
if uint32(len(oldParticipants)+1+len(additionalParticipants)) > maxParticipants {
return 0, nex.NewError(nex.ResultCodes.RendezVous.SessionFull, "change_error")
}

Expand Down Expand Up @@ -71,7 +71,7 @@ func JoinGatheringWithParticipants(manager *common_globals.MatchmakingManager, g
var participantJoinedTargets []uint64

// * When the VerboseParticipants or the VerboseParticipantsEx flags are set, all participant notification events are sent to everyone
if flags & (match_making.GatheringFlags.VerboseParticipants | match_making.GatheringFlags.VerboseParticipantsEx) != 0 {
if flags&(match_making.GatheringFlags.VerboseParticipants|match_making.GatheringFlags.VerboseParticipantsEx) != 0 {
participantJoinedTargets = common_globals.RemoveDuplicates(participants)
} else {
participantJoinedTargets = []uint64{ownerPID}
Expand All @@ -89,9 +89,9 @@ func JoinGatheringWithParticipants(manager *common_globals.MatchmakingManager, g

oEvent := notifications_types.NewNotificationEvent()
oEvent.PIDSource = connection.PID()
oEvent.Type = types.NewUInt32(notifications.BuildNotificationType(notificationCategory, notificationSubtype))
oEvent.Param1 = types.NewUInt32(gatheringID)
oEvent.Param2 = types.NewUInt32(uint32(participant)) // TODO - This assumes a legacy client. Will not work on the Switch
oEvent.Type = types.UInt32(notifications.BuildNotificationType(notificationCategory, notificationSubtype))
oEvent.Param1 = types.UInt64(gatheringID)
oEvent.Param2 = types.UInt64(participant)

// * Send the notification to the participant
common_globals.SendNotificationEvent(connection.Endpoint().(*nex.PRUDPEndPoint), oEvent, []uint64{participant})
Expand All @@ -100,35 +100,35 @@ func JoinGatheringWithParticipants(manager *common_globals.MatchmakingManager, g
for _, participant := range newParticipants {
// * If the new participant is the same as the owner, then we are creating a new gathering.
// * We don't need to send the new participant notification event in that case
if flags & (match_making.GatheringFlags.VerboseParticipants | match_making.GatheringFlags.VerboseParticipantsEx) != 0 || uint64(connection.PID()) != ownerPID {
if flags&(match_making.GatheringFlags.VerboseParticipants|match_making.GatheringFlags.VerboseParticipantsEx) != 0 || uint64(connection.PID()) != ownerPID {
notificationCategory := notifications.NotificationCategories.Participation
notificationSubtype := notifications.NotificationSubTypes.Participation.NewParticipant

oEvent := notifications_types.NewNotificationEvent()
oEvent.PIDSource = connection.PID()
oEvent.Type = types.NewUInt32(notifications.BuildNotificationType(notificationCategory, notificationSubtype))
oEvent.Param1 = types.NewUInt32(gatheringID)
oEvent.Param2 = types.NewUInt32(uint32(participant)) // TODO - This assumes a legacy client. Will not work on the Switch
oEvent.Type = types.UInt32(notifications.BuildNotificationType(notificationCategory, notificationSubtype))
oEvent.Param1 = types.UInt64(gatheringID)
oEvent.Param2 = types.UInt64(participant)
oEvent.StrParam = types.NewString(joinMessage)
oEvent.Param3 = types.NewUInt32(uint32(len(participants)))
oEvent.Param3 = types.UInt64(len(participants))

common_globals.SendNotificationEvent(connection.Endpoint().(*nex.PRUDPEndPoint), oEvent, participantJoinedTargets)
}

// * This flag also sends a recap of all currently connected players on the gathering to the participant that is connecting
if flags & match_making.GatheringFlags.VerboseParticipantsEx != 0 {
if flags&match_making.GatheringFlags.VerboseParticipantsEx != 0 {
// TODO - Should this actually be deduplicated?
for _, oldParticipant := range common_globals.RemoveDuplicates(oldParticipants) {
notificationCategory := notifications.NotificationCategories.Participation
notificationSubtype := notifications.NotificationSubTypes.Participation.NewParticipant

oEvent := notifications_types.NewNotificationEvent()
oEvent.PIDSource = connection.PID()
oEvent.Type = types.NewUInt32(notifications.BuildNotificationType(notificationCategory, notificationSubtype))
oEvent.Param1 = types.NewUInt32(gatheringID)
oEvent.Param2 = types.NewUInt32(uint32(oldParticipant)) // TODO - This assumes a legacy client. Will not work on the Switch
oEvent.Type = types.UInt32(notifications.BuildNotificationType(notificationCategory, notificationSubtype))
oEvent.Param1 = types.UInt64(gatheringID)
oEvent.Param2 = types.UInt64(oldParticipant)
oEvent.StrParam = types.NewString(joinMessage)
oEvent.Param3 = types.NewUInt32(uint32(len(participants)))
oEvent.Param3 = types.UInt64(len(participants))

// * Send the notification to the joining participant
common_globals.SendNotificationEvent(connection.Endpoint().(*nex.PRUDPEndPoint), oEvent, []uint64{participant})
Expand Down
8 changes: 4 additions & 4 deletions match-making/database/migrate_gathering_ownership.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ func MigrateGatheringOwnership(manager *common_globals.MatchmakingManager, conne

oEvent := notifications_types.NewNotificationEvent()
oEvent.PIDSource = connection.PID().Copy().(types.PID)
oEvent.Type = types.NewUInt32(notifications.BuildNotificationType(category, subtype))
oEvent.Param1 = gathering.ID
oEvent.Type = types.UInt32(notifications.BuildNotificationType(category, subtype))
oEvent.Param1 = types.UInt64(gathering.ID)

common_globals.SendNotificationEvent(connection.Endpoint().(*nex.PRUDPEndPoint), oEvent, uniqueParticipants)
return 0, nil
Expand All @@ -62,8 +62,8 @@ func MigrateGatheringOwnership(manager *common_globals.MatchmakingManager, conne
oEvent := notifications_types.NewNotificationEvent()
oEvent.PIDSource = connection.PID().Copy().(types.PID)
oEvent.Type = types.NewUInt32(notifications.BuildNotificationType(category, subtype))
oEvent.Param1 = gathering.ID
oEvent.Param2 = types.NewUInt32(uint32(newOwner)) // TODO - This assumes a legacy client. Will not work on the Switch
oEvent.Param1 = types.UInt64(gathering.ID)
oEvent.Param2 = types.UInt64(newOwner)

// TODO - StrParam doesn't have this value on some servers
// * https://github.com/kinnay/NintendoClients/issues/101
Expand Down
2 changes: 1 addition & 1 deletion match-making/unregister_gathering.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func (commonProtocol *CommonProtocol) unregisterGathering(err error, packet nex.
oEvent := notifications_types.NewNotificationEvent()
oEvent.PIDSource = connection.PID().Copy().(types.PID)
oEvent.Type = types.NewUInt32(notifications.BuildNotificationType(category, subtype))
oEvent.Param1 = idGathering
oEvent.Param1 = types.UInt64(idGathering)

common_globals.SendNotificationEvent(endpoint, oEvent, common_globals.RemoveDuplicates(participants))

Expand Down
Loading