From acab015f31d07979eaff988cdb637b635cb9ce7e Mon Sep 17 00:00:00 2001 From: mkwcat Date: Mon, 11 Dec 2023 10:31:33 -0500 Subject: [PATCH] Reverse QR2 dependency on GPCM --- gpcm/login.go | 17 +++++------------ gpcm/main.go | 2 ++ qr2/logins.go | 27 +++++++++++++++++++++++++++ qr2/session.go | 21 +++++++++++---------- 4 files changed, 45 insertions(+), 22 deletions(-) create mode 100644 qr2/logins.go diff --git a/gpcm/login.go b/gpcm/login.go index c695752..88d0859 100644 --- a/gpcm/login.go +++ b/gpcm/login.go @@ -12,6 +12,7 @@ import ( "wwfc/common" "wwfc/database" "wwfc/logging" + "wwfc/qr2" ) func generateResponse(gpcmChallenge, nasChallenge, authToken, clientChallenge string) string { @@ -183,6 +184,10 @@ func (g *GameSpySession) login(command common.GameSpyCommand) { g.ModuleName = "GPCM:" + strconv.FormatInt(int64(g.User.ProfileId), 10) g.ModuleName += "/" + common.CalcFriendCodeString(g.User.ProfileId, "RMCJ") + // Notify QR2 of the login + // TODO: Get ingamesn and cfc from NAS + qr2.Login(g.User.ProfileId, "", "", g.Conn.RemoteAddr().String()) + payload := common.CreateGameSpyMessage(common.GameSpyCommand{ Command: "lc", CommandValue: "2", @@ -207,15 +212,3 @@ func IsLoggedIn(profileID uint32) bool { session, exists := sessions[profileID] return exists && session.LoggedIn } - -func GetSessionIP(profileID uint32) string { - mutex.Lock() - defer mutex.Unlock() - - session, exists := sessions[profileID] - if exists && session.LoggedIn { - return session.Conn.RemoteAddr().String() - } - - return "" -} diff --git a/gpcm/main.go b/gpcm/main.go index 18fd04b..9e39545 100644 --- a/gpcm/main.go +++ b/gpcm/main.go @@ -13,6 +13,7 @@ import ( "wwfc/common" "wwfc/database" "wwfc/logging" + "wwfc/qr2" ) type GameSpySession struct { @@ -77,6 +78,7 @@ func StartServer() { func (g *GameSpySession) closeSession() { if g.LoggedIn { + qr2.Logout(g.User.ProfileId) g.sendLogoutStatus() } diff --git a/qr2/logins.go b/qr2/logins.go new file mode 100644 index 0000000..c3d0af2 --- /dev/null +++ b/qr2/logins.go @@ -0,0 +1,27 @@ +package qr2 + +type LoginInfo struct { + ProfileID uint32 + InGameName string + ConsoleFriendCode string + GPPublicIP string +} + +var logins = map[uint32]LoginInfo{} + +func Login(profileID uint32, inGameName, consoleFriendCode, publicIP string) { + mutex.Lock() + logins[profileID] = LoginInfo{ + ProfileID: profileID, + InGameName: inGameName, + ConsoleFriendCode: consoleFriendCode, + GPPublicIP: publicIP, + } + mutex.Unlock() +} + +func Logout(profileID uint32) { + mutex.Lock() + delete(logins, profileID) + mutex.Unlock() +} diff --git a/qr2/session.go b/qr2/session.go index 19a7646..b1577c7 100644 --- a/qr2/session.go +++ b/qr2/session.go @@ -9,7 +9,6 @@ import ( "sync" "time" "wwfc/common" - "wwfc/gpcm" "wwfc/logging" ) @@ -116,10 +115,12 @@ func setSessionData(sessionId uint32, payload map[string]string, addr net.Addr) return *session, true } - if pid, ok := session.Data["dwc_pid"]; ok && pid != "" { - payload["dwc_pid"] = pid + // Save certain fields + for k, v := range session.Data { + if k[0] == '+' || k == "dwc_pid" { + payload[k] = v + } } - payload["+searchid"] = session.Data["+searchid"] session.Data = payload session.LastKeepAlive = time.Now().Unix() @@ -146,16 +147,16 @@ func (session *Session) setProfileID(moduleName string, newPID string) bool { return false } - // Lookup the profile ID in GPCM and verify it's logged in. - // Maybe we don't need this? It relies on GPCM being hosted in the same application, and - // makes GPCM a dependency of QR2. Perhaps we could use the database. - gpcmIP := gpcm.GetSessionIP(uint32(profileID)) - if gpcmIP == "" { + // Check if the public IP matches the one used for the GPCM session + var gpPublicIP string + if loginInfo, ok := logins[uint32(profileID)]; ok { + gpPublicIP = loginInfo.GPPublicIP + } else { logging.Error(moduleName, "Provided dwc_pid is not logged in:", aurora.Cyan(newPID)) return false } - if strings.Split(gpcmIP, ":")[0] != strings.Split(session.Addr.String(), ":")[0] { + if strings.Split(gpPublicIP, ":")[0] != strings.Split(session.Addr.String(), ":")[0] { logging.Error(moduleName, "Caller public IP does not match GPCM session") return false }