Improve QR2 kick order by sending it to all QR2-authenticated sessions

This commit is contained in:
Rambo6Glaz 2025-04-03 03:05:31 +09:00
parent 2e83f14d4e
commit 7ea395eec2
2 changed files with 31 additions and 77 deletions

View File

@ -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)
})
}()
}

View File

@ -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)")
}