From 7ea395eec2ee9fe005174b2cda32aaa306f93d4a Mon Sep 17 00:00:00 2001 From: Rambo6Glaz <39063367+EpicUsername12@users.noreply.github.com> Date: Thu, 3 Apr 2025 03:05:31 +0900 Subject: [PATCH] Improve QR2 kick order by sending it to all QR2-authenticated sessions --- gpcm/kick.go | 75 +++++++++++----------------------------------------- qr2/group.go | 33 +++++++++++------------ 2 files changed, 31 insertions(+), 77 deletions(-) diff --git a/gpcm/kick.go b/gpcm/kick.go index 8968acb..5b66c28 100644 --- a/gpcm/kick.go +++ b/gpcm/kick.go @@ -1,48 +1,11 @@ package gpcm import ( - "strconv" "time" "wwfc/common" "wwfc/qr2" ) -// Expects a global mutex to be locked -// This function will return all sessions that are matched with the player `profileID` -func getSessionsMatchedWithPlayer(gameName string, profileID uint32) []*GameSpySession { - - var matchedPlayers []*GameSpySession - - // Check if the user is part of a group - var foundGroup *qr2.GroupInfo - groups := qr2.GetGroups([]string{gameName}, []string{}, false) - for _, group := range groups { - for _, playerInfo := range group.Players { - pid, err := strconv.ParseUint(playerInfo.ProfileID, 10, 32) - if err == nil { - if uint32(pid) == profileID { - foundGroup = &group - break - } - } - } - } - - // If the user is part of a group, send a kick order to all players in the group - if foundGroup != nil { - for _, playerInfo := range foundGroup.Players { - pid, err := strconv.ParseUint(playerInfo.ProfileID, 10, 32) - if err == nil { - if session, exists := sessions[uint32(pid)]; exists { - matchedPlayers = append(matchedPlayers, session) - } - } - } - } - - return matchedPlayers -} - func kickPlayer(profileID uint32, reason string) { if session, exists := sessions[profileID]; exists { errorMessage := WWFCMsgKickedGeneric @@ -72,24 +35,21 @@ func kickPlayer(profileID uint32, reason string) { return } - players := getSessionsMatchedWithPlayer(session.GameName, profileID) session.replyError(GPError{ ErrorCode: ErrConnectionClosed.ErrorCode, ErrorString: "The player was kicked from the server. Reason: " + reason, Fatal: true, WWFCMessage: errorMessage, }) - - // After 3 seconds, send kick order to all players in the group - // This is to prevent the restricted player from staying in the group if he ignores the GPCM kick - go func(players []*GameSpySession) { - time.AfterFunc(3*time.Second, func() { - for _, player := range players { - qr2.OrderKickFromGroup(player.User.ProfileId, profileID) - } - }) - }(players) } + + // After 3 seconds, send kick order to all players + // This is to prevent the restricted player from staying in the group if he ignores the GPCM kick + go func() { + time.AfterFunc(3*time.Second, func() { + qr2.OrderKickFromGroups(profileID) + }) + }() } func KickPlayer(profileID uint32, reason string) { @@ -104,7 +64,6 @@ func KickPlayerCustomMessage(profileID uint32, reason string, message WWFCErrorM defer mutex.Unlock() if session, exists := sessions[profileID]; exists { - players := getSessionsMatchedWithPlayer(session.GameName, profileID) session.replyError(GPError{ ErrorCode: ErrConnectionClosed.ErrorCode, ErrorString: "The player was kicked from the server. Reason: " + reason, @@ -112,15 +71,13 @@ func KickPlayerCustomMessage(profileID uint32, reason string, message WWFCErrorM WWFCMessage: message, Reason: reason, }) - - // After 3 seconds, send kick order to all players in the group - // This is to prevent the restricted player from staying in the group if he ignores the GPCM kick - go func(players []*GameSpySession) { - time.AfterFunc(3*time.Second, func() { - for _, player := range players { - qr2.OrderKickFromGroup(player.User.ProfileId, profileID) - } - }) - }(players) } + + // After 3 seconds, send kick order to all players + // This is to prevent the restricted player from staying in the group if he ignores the GPCM kick + go func() { + time.AfterFunc(3*time.Second, func() { + qr2.OrderKickFromGroups(profileID) + }) + }() } diff --git a/qr2/group.go b/qr2/group.go index f2f3efe..a6bda4c 100644 --- a/qr2/group.go +++ b/qr2/group.go @@ -584,28 +584,25 @@ func loadGroups() error { return nil } -func OrderKickFromGroup(profileID uint32, profileToKick uint32) { - moduleName := "QR2:OrderKickFromGroup/" + strconv.FormatUint(uint64(profileID), 10) - - login, exists := logins[profileID] - if !exists || login == nil { - return - } - - session := login.session - if session == nil { - return - } +// Send kick order to all QR2-authenticated session to kick a player from their group +func OrderKickFromGroups(profileToKick uint32) { + moduleName := "QR2:OrderKickFromGroup/" + strconv.FormatUint(uint64(profileToKick), 10) mutex.Lock() defer mutex.Unlock() - message := createResponseHeader(ClientKickPeerOrder, session.SessionID) - message = append(message, 0) // padding for 4 byte alignment - message = binary.BigEndian.AppendUint32(message, profileToKick) - _, err := masterConn.WriteTo(message, &session.Addr) - if err != nil { - logging.Error(moduleName, "Error sending message:", err.Error()) + var numSent int = 0 + for _, session := range sessions { + message := createResponseHeader(ClientKickPeerOrder, session.SessionID) + message = append(message, 0) // padding for 4 byte alignment + message = binary.BigEndian.AppendUint32(message, profileToKick) + _, err := masterConn.WriteTo(message, &session.Addr) + if err != nil { + logging.Error(moduleName, "Error sending message:", err.Error()) + } + + numSent++ } + logging.Notice(moduleName, "Sent kick order message to", aurora.Cyan(numSent), "player(s)") }