nex-protocols-common-go/match-making/update_session_host.go
2025-01-01 19:55:13 +00:00

102 lines
3.9 KiB
Go

package matchmaking
import (
"slices"
"github.com/PretendoNetwork/nex-go/v2"
"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/database"
"github.com/PretendoNetwork/nex-protocols-common-go/v2/match-making/tracking"
match_making "github.com/PretendoNetwork/nex-protocols-go/v2/match-making"
notifications "github.com/PretendoNetwork/nex-protocols-go/v2/notifications"
notifications_types "github.com/PretendoNetwork/nex-protocols-go/v2/notifications/types"
)
func (commonProtocol *CommonProtocol) updateSessionHost(err error, packet nex.PacketInterface, callID uint32, gid types.UInt32, isMigrateOwner types.Bool) (*nex.RMCMessage, *nex.Error) {
if err != nil {
common_globals.Logger.Error(err.Error())
return nil, nex.NewError(nex.ResultCodes.Core.InvalidArgument, "change_error")
}
commonProtocol.manager.Mutex.Lock()
gathering, _, participants, _, nexError := database.FindGatheringByID(commonProtocol.manager, uint32(gid))
if nexError != nil {
commonProtocol.manager.Mutex.Unlock()
return nil, nexError
}
connection := packet.Sender().(*nex.PRUDPConnection)
endpoint := connection.Endpoint().(*nex.PRUDPEndPoint)
if !slices.Contains(participants, uint64(connection.PID())) {
commonProtocol.manager.Mutex.Unlock()
return nil, nex.NewError(nex.ResultCodes.RendezVous.PermissionDenied, "change_error")
}
if !isMigrateOwner {
nexError = database.UpdateSessionHost(commonProtocol.manager, uint32(gid), gathering.OwnerPID, connection.PID())
if nexError != nil {
commonProtocol.manager.Mutex.Unlock()
return nil, nexError
}
nexError = tracking.LogChangeHost(commonProtocol.manager.Database, connection.PID(), uint32(gid), gathering.HostPID, connection.PID())
if nexError != nil {
commonProtocol.manager.Mutex.Unlock()
return nil, nexError
}
} else {
if uint32(gathering.Flags) & match_making.GatheringFlags.ParticipantsChangeOwner == 0 {
commonProtocol.manager.Mutex.Unlock()
return nil, nex.NewError(nex.ResultCodes.RendezVous.InvalidOperation, "change_error")
}
nexError = database.UpdateSessionHost(commonProtocol.manager, uint32(gid), connection.PID(), connection.PID())
if nexError != nil {
commonProtocol.manager.Mutex.Unlock()
return nil, nexError
}
nexError = tracking.LogChangeHost(commonProtocol.manager.Database, connection.PID(), uint32(gid), gathering.HostPID, connection.PID())
if nexError != nil {
commonProtocol.manager.Mutex.Unlock()
return nil, nexError
}
nexError = tracking.LogChangeOwner(commonProtocol.manager.Database, connection.PID(), uint32(gid), gathering.OwnerPID, connection.PID())
if nexError != nil {
commonProtocol.manager.Mutex.Unlock()
return nil, nexError
}
category := notifications.NotificationCategories.OwnershipChanged
subtype := notifications.NotificationSubTypes.OwnershipChanged.None
oEvent := notifications_types.NewNotificationEvent()
oEvent.PIDSource = connection.PID()
oEvent.Type = types.NewUInt32(notifications.BuildNotificationType(category, subtype))
oEvent.Param1 = gid
oEvent.Param2 = types.NewUInt32(uint32(connection.PID())) // TODO - This assumes a legacy client. Will not work on the Switch
// TODO - StrParam doesn't have this value on some servers
// * https://github.com/kinnay/NintendoClients/issues/101
// * unixTime := time.Now()
// * oEvent.StrParam = strconv.FormatInt(unixTime.UnixMicro(), 10)
common_globals.SendNotificationEvent(endpoint, oEvent, common_globals.RemoveDuplicates(participants))
}
commonProtocol.manager.Mutex.Unlock()
rmcResponse := nex.NewRMCSuccess(endpoint, nil)
rmcResponse.ProtocolID = match_making.ProtocolID
rmcResponse.MethodID = match_making.MethodUpdateSessionHost
rmcResponse.CallID = callID
if commonProtocol.OnAfterUpdateSessionHost != nil {
go commonProtocol.OnAfterUpdateSessionHost(packet, gid, isMigrateOwner)
}
return rmcResponse, nil
}