diff --git a/Generals/Code/GameEngine/Include/Common/GameEngine.h b/Generals/Code/GameEngine/Include/Common/GameEngine.h
index 3022de14faa..014a8628fa3 100644
--- a/Generals/Code/GameEngine/Include/Common/GameEngine.h
+++ b/Generals/Code/GameEngine/Include/Common/GameEngine.h
@@ -81,7 +81,6 @@ class GameEngine : public SubsystemInterface
virtual void serviceWindowsOS(void) {}; ///< service the native OS
virtual Bool isActive(void) {return m_isActive;} ///< returns whether app has OS focus.
virtual void setIsActive(Bool isActive) { m_isActive = isActive; };
- virtual void checkAbnormalQuitting(void); ///< check if user is quitting at an unusual time - as in cheating!
protected:
diff --git a/Generals/Code/GameEngine/Include/GameClient/GUICallbacks.h b/Generals/Code/GameEngine/Include/GameClient/GUICallbacks.h
index 07e3ded5e01..8cd3209dbdf 100644
--- a/Generals/Code/GameEngine/Include/GameClient/GUICallbacks.h
+++ b/Generals/Code/GameEngine/Include/GameClient/GUICallbacks.h
@@ -263,12 +263,6 @@ extern WindowMsgHandledType WOLBuddyOverlayInput( GameWindow *window, UnsignedIn
extern void WOLBuddyOverlayRCMenuInit( WindowLayout *layout, void *userData );
extern WindowMsgHandledType WOLBuddyOverlayRCMenuSystem( GameWindow *window, UnsignedInt msg, WindowMsgData mData1, WindowMsgData mData2 );
-// GameSpy Player Info Overlay ---------------------------------------------------------------------------------
-extern void GameSpyPlayerInfoOverlayInit( WindowLayout *layout, void *userData );
-extern void GameSpyPlayerInfoOverlayUpdate( WindowLayout *layout, void *userData );
-extern void GameSpyPlayerInfoOverlayShutdown( WindowLayout *layout, void *userData );
-extern WindowMsgHandledType GameSpyPlayerInfoOverlaySystem( GameWindow *window, UnsignedInt msg, WindowMsgData mData1, WindowMsgData mData2 );
-extern WindowMsgHandledType GameSpyPlayerInfoOverlayInput( GameWindow *window, UnsignedInt msg, WindowMsgData mData1, WindowMsgData mData2 );
// Popup host Game Internet -----------------------------------------------------------------------------------
extern void PopupHostGameInit( WindowLayout *layout, void *userData );
diff --git a/Generals/Code/GameEngine/Include/GameClient/LoadScreen.h b/Generals/Code/GameEngine/Include/GameClient/LoadScreen.h
index 6cb73b7b203..54a412ab799 100644
--- a/Generals/Code/GameEngine/Include/GameClient/LoadScreen.h
+++ b/Generals/Code/GameEngine/Include/GameClient/LoadScreen.h
@@ -179,37 +179,6 @@ class MultiPlayerLoadScreen : public LoadScreen
///////////////////////////////////////////////////////////////////////////////////////////////////
// class MultiPlayerLoadScreen is to be used for multiplayer communication on the loadscreens
//// ///////////////////////////////////////////////////////////////////////////////////////////////
-class GameSpyLoadScreen : public LoadScreen
-{
-public:
- GameSpyLoadScreen( void );
- virtual ~GameSpyLoadScreen( void );
-
- virtual void init( GameInfo *game ); ///< Init the loadscreen
- virtual void reset( void ); ///< Reset the system
- virtual void update( void )
- {
- DEBUG_CRASH(("Call update(Int) instead. This update isn't supported"));
- };
- virtual void update(Int percent); ///< Update the state of the progress bar
- void processProgress(Int playerId, Int percentage);
- virtual void setProgressRange( Int min, Int max ) { }
-private:
- GameWindow *m_progressBars[MAX_SLOTS]; ///< pointer array to all the progress bars on the window
- GameWindow *m_playerNames[MAX_SLOTS]; ///< pointer array to all the static text player names on the window
- GameWindow *m_playerSide[MAX_SLOTS]; ///< pointer array to all the static text player sides
- GameWindow *m_playerFavoriteFactions[MAX_SLOTS]; ///< pointer array to all the static text player sides
- GameWindow *m_playerTotalDisconnects[MAX_SLOTS]; ///< pointer array to all the static text player sides
- GameWindow *m_playerWin[MAX_SLOTS]; ///< pointer array to all the static text player sides
- GameWindow *m_playerWinLosses[MAX_SLOTS]; ///< pointer array to all the static text player sides
- GameWindow *m_playerRank[MAX_SLOTS]; ///< pointer array to all the static text player sides
- GameWindow *m_playerOfficerMedal[MAX_SLOTS]; ///< pointer array to all the static text player munkees
- GameWindow *m_mapPreview;
- GameWindow *m_buttonMapStartPosition[MAX_SLOTS];
-
- Int m_playerLookup[MAX_SLOTS]; ///< lookup table to translate network slot info screen slot (to account for holes in the slot list)
-};
-
///////////////////////////////////////////////////////////////////////////////////////////////////
// class MapTransferLoadScreen is to be used for map transfers before multiplayer game load screens
//// ///////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy.h b/Generals/Code/GameEngine/Include/GameNetwork/GameSpy.h
deleted file mode 100644
index 9b3ba17a4c9..00000000000
--- a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: GameSpy.h //////////////////////////////////////////////////////
-// Generals GameSpy stuff
-// Author: Matthew D. Campbell, February 2002
-
-#pragma once
-
-#ifndef __GameSpy_H__
-#define __GameSpy_H__
-
-#include "GameSpy/Peer/Peer.h"
-
-#include "GameClient/Color.h"
-#include "Common/STLTypedefs.h"
-
-class GameSpyGroupRoom
-{
-public:
- GameSpyGroupRoom() { m_name = AsciiString::TheEmptyString; m_groupID = m_numWaiting = m_maxWaiting = m_numGames = m_numPlaying = 0; }
- AsciiString m_name;
- Int m_groupID;
- Int m_numWaiting;
- Int m_maxWaiting;
- Int m_numGames;
- Int m_numPlaying;
-};
-typedef std::map GroupRoomMap;
-
-class GameSpyChatInterface : public SubsystemInterface
-{
-public:
- virtual ~GameSpyChatInterface() { };
-
- virtual void init( void ) = 0;
- virtual void reset( void ) = 0;
- virtual void update( void ) = 0;
-
- virtual Bool isConnected( void ) = 0;
- virtual void login(AsciiString loginName, AsciiString password = AsciiString::TheEmptyString, AsciiString email = AsciiString::TheEmptyString) = 0;
- virtual void reconnectProfile( void ) = 0;
- virtual void disconnectFromChat( void ) = 0;
-
- virtual void UTMRoom( RoomType roomType, const char *key, const char *val, Bool authenticate = FALSE ) = 0;
- virtual void UTMPlayer( const char *name, const char *key, const char *val, Bool authenticate = FALSE ) = 0;
- virtual void startGame( void ) = 0;
- virtual void leaveRoom( RoomType roomType ) = 0;
- virtual void setReady( Bool ready ) = 0;
- virtual void enumPlayers( RoomType roomType, peerEnumPlayersCallback callback, void *userData ) = 0;
- virtual void startListingGames( peerListingGamesCallback callback ) = 0;
- virtual void stopListingGames( void ) = 0;
-
- virtual void joinGroupRoom( Int ID ) = 0;
- virtual void joinStagingRoom( GServer server, AsciiString password ) = 0;
- virtual void createStagingRoom( AsciiString gameName, AsciiString password, Int maxPlayers ) = 0;
- virtual void joinBestGroupRoom( void ) = 0;
-
- inline PEER getPeer( void ) { return m_peer; }
- inline AsciiString getLoginName( void ) { return m_loginName; }
- inline AsciiString getPassword( void ) { return m_password; }
- inline GroupRoomMap* getGroupRooms( void ) { return &m_groupRooms; }
- inline Int getCurrentGroupRoomID( void ) { return m_currentGroupRoomID; }
- inline Bool getUsingProfile( void ) { return m_usingProfiles; }
- inline Int getProfileID( void ) { return m_profileID; }
-
- inline void setCurrentGroupRoomID( Int ID ) { m_currentGroupRoomID = ID; }
- void clearGroupRoomList(void);
- inline Int getNumGroupRooms( void ) { return m_groupRooms.size(); }
-
-
-protected:
-
- AsciiString m_loginName;
- AsciiString m_password;
- AsciiString m_email;
- Bool m_usingProfiles;
- Int m_profileID;
- PEER m_peer;
-
- GroupRoomMap m_groupRooms;
- Int m_currentGroupRoomID;
-};
-
-GameSpyChatInterface *createGameSpyChat( void );
-
-extern GameSpyChatInterface *TheGameSpyChat;
-
-
-void JoinRoomCallback(PEER peer, PEERBool success,
- PEERJoinResult result, RoomType roomType,
- void *param); ///< Called when we (fail to) join a room. param is address of Bool to store result
-
-void ListGroupRoomsCallback(PEER peer, PEERBool success,
- int groupID, GServer server,
- const char * name, int numWaiting,
- int maxWaiting, int numGames,
- int numPlaying, void * param); ///< Called while listing group rooms
-
-enum GameSpyColors {
- GSCOLOR_DEFAULT = 0,
- GSCOLOR_CURRENTROOM,
- GSCOLOR_ROOM,
- GSCOLOR_GAME,
- GSCOLOR_PLAYER_NORMAL,
- GSCOLOR_PLAYER_OWNER,
- GSCOLOR_PLAYER_BUDDY,
- GSCOLOR_PLAYER_SELF,
- GSCOLOR_CHAT_NORMAL,
- GSCOLOR_CHAT_EMOTE,
- GSCOLOR_CHAT_OWNER,
- GSCOLOR_CHAT_OWNER_EMOTE,
- GSCOLOR_CHAT_PRIVATE,
- GSCOLOR_CHAT_PRIVATE_EMOTE,
- GSCOLOR_CHAT_PRIVATE_OWNER,
- GSCOLOR_CHAT_PRIVATE_OWNER_EMOTE,
- GSCOLOR_CHAT_BUDDY,
- GSCOLOR_CHAT_SELF,
- GSCOLOR_ACCEPT_TRUE,
- GSCOLOR_ACCEPT_FALSE,
- GSCOLOR_MAX
-};
-
-extern const Color GameSpyColor[GSCOLOR_MAX];
-
-
-#endif // __GameSpy_H__
diff --git a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/BuddyDefs.h b/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/BuddyDefs.h
deleted file mode 100644
index 6a2cac82b7e..00000000000
--- a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/BuddyDefs.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: BuddyDefs.h //////////////////////////////////////////////////////
-// Generals GameSpy Buddy (GP) definitions
-// Author: Matthew D. Campbell, July 2002
-
-#pragma once
-
-#ifndef __BUDDYDEFS_H__
-#define __BUDDYDEFS_H__
-
-void HandleBuddyResponses(void);
-void PopulateOldBuddyMessages(void);
-
-#endif // __BUDDYDEFS_H__
diff --git a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/BuddyThread.h b/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/BuddyThread.h
deleted file mode 100644
index c368acc3921..00000000000
--- a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/BuddyThread.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: BuddyThread.h //////////////////////////////////////////////////////
-// Generals GameSpy BuddyList thread class interface
-// Author: Matthew D. Campbell, June 2002
-
-#pragma once
-
-#ifndef __BUDDYTHREAD_H__
-#define __BUDDYTHREAD_H__
-
-#include "GameSpy/GP/GP.h"
-
-#define MAX_BUDDY_CHAT_LEN 128
-
-// this class encapsulates a request for the buddy thread
-class BuddyRequest
-{
-public:
- enum
- {
- BUDDYREQUEST_LOGIN, // attempt to login
- BUDDYREQUEST_RELOGIN, // log in after being disconnected
- BUDDYREQUEST_LOGOUT, // log out if connected
- BUDDYREQUEST_MESSAGE,
- BUDDYREQUEST_LOGINNEW, // attempt to create a new nick and login
- //BUDDYREQUEST_DELETELOGIN,
- BUDDYREQUEST_ADDBUDDY, // add someone to your buddy list
- BUDDYREQUEST_DELBUDDY, // delete someone from your buddy list
- BUDDYREQUEST_OKADD, // allow someone to add you to their buddy list
- BUDDYREQUEST_DENYADD, // don't allow someone to add you to their buddy list
- BUDDYREQUEST_SETSTATUS, // Set our status
- BUDDYREQUEST_DELETEACCT, // Delete our account
- BUDDYREQUEST_MAX
- } buddyRequestType;
-
- union
- {
- struct
- {
- GPProfile recipient;
- WideChar text[MAX_BUDDY_CHAT_LEN];
- } message;
-
- struct
- {
- char nick[GP_NICK_LEN];
- char email[GP_EMAIL_LEN];
- char password[GP_PASSWORD_LEN];
- Bool hasFirewall;
- } login;
-
- struct
- {
- GPProfile id;
- WideChar text[MAX_BUDDY_CHAT_LEN];
- } addbuddy;
-
- struct
- {
- GPProfile id;
- } profile;
-
- struct
- {
- GPEnum status;
- char statusString[GP_STATUS_STRING_LEN];
- char locationString[GP_LOCATION_STRING_LEN];
- } status;
-
- } arg;
-};
-
-//-------------------------------------------------------------------------
-
-// this class encapsulates an action the buddy thread wants from the UI
-class BuddyResponse
-{
-public:
- enum
- {
- BUDDYRESPONSE_LOGIN,
- BUDDYRESPONSE_DISCONNECT,
- BUDDYRESPONSE_MESSAGE,
- BUDDYRESPONSE_REQUEST,
- BUDDYRESPONSE_STATUS,
- BUDDYRESPONSE_MAX
- } buddyResponseType;
-
- GPProfile profile;
- GPResult result;
-
- union
- {
- struct
- {
- UnsignedInt date;
- char nick[GP_NICK_LEN];
- WideChar text[MAX_BUDDY_CHAT_LEN];
- } message;
-
- struct
- {
- char nick[GP_NICK_LEN];
- char email[GP_EMAIL_LEN];
- char countrycode[GP_COUNTRYCODE_LEN];
- WideChar text[GP_REASON_LEN];
- } request;
-
- struct
- {
- //GPResult result;
- GPErrorCode errorCode;
- char errorString[MAX_BUDDY_CHAT_LEN];
- GPEnum fatal;
- } error;
-
- struct
- {
- char nick[GP_NICK_LEN];
- char email[GP_EMAIL_LEN];
- char countrycode[GP_COUNTRYCODE_LEN];
- char location[GP_LOCATION_STRING_LEN];
- GPEnum status;
- char statusString[GP_STATUS_STRING_LEN];
- } status;
- } arg;
-};
-
-//-------------------------------------------------------------------------
-
-// this is the actual message queue used to pass messages between threads
-class GameSpyBuddyMessageQueueInterface
-{
-public:
- virtual ~GameSpyBuddyMessageQueueInterface() {}
- virtual void startThread( void ) = 0;
- virtual void endThread( void ) = 0;
- virtual Bool isThreadRunning( void ) = 0;
- virtual Bool isConnected( void ) = 0;
- virtual Bool isConnecting( void ) = 0;
-
- virtual void addRequest( const BuddyRequest& req ) = 0;
- virtual Bool getRequest( BuddyRequest& req ) = 0;
-
- virtual void addResponse( const BuddyResponse& resp ) = 0;
- virtual Bool getResponse( BuddyResponse& resp ) = 0;
-
- virtual GPProfile getLocalProfileID( void ) = 0;
-
- static GameSpyBuddyMessageQueueInterface* createNewMessageQueue( void );
-};
-
-extern GameSpyBuddyMessageQueueInterface *TheGameSpyBuddyMessageQueue;
-
-
-#endif // __BUDDYTHREAD_H__
diff --git a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/GSConfig.h b/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/GSConfig.h
deleted file mode 100644
index 561c2f232a5..00000000000
--- a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/GSConfig.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: GSConfig.h ///////////////////////////////////////////////////////////
-// Author: Matthew D. Campbell, Sept 2002
-// Description: GameSpy online config
-///////////////////////////////////////////////////////////////////////////////
-
-#pragma once
-
-#ifndef __GSCONFIG_H__
-#define __GSCONFIG_H__
-
-#include "Common/AsciiString.h"
-#include "Common/STLTypedefs.h"
-
-class GameSpyConfigInterface
-{
-public:
- virtual ~GameSpyConfigInterface() {}
-
- // Pings
- virtual std::list getPingServers(void) = 0;
- virtual Int getNumPingRepetitions(void) = 0;
- virtual Int getPingTimeoutInMs(void) = 0;
- virtual Int getPingCutoffGood( void ) = 0;
- virtual Int getPingCutoffBad( void ) = 0;
-
- // QM
- virtual std::list getQMMaps(void) = 0;
- virtual Int getQMBotID(void) = 0;
- virtual Int getQMChannel(void) = 0;
- virtual void setQMChannel(Int channel) = 0;
-
- // Player Info
- virtual Int getPointsForRank(Int rank) = 0;
- virtual Bool isPlayerVIP(Int id) = 0;
-
- // mangler Info
- virtual Bool getManglerLocation(Int index, AsciiString& host, UnsignedShort& port) = 0;
-
- // Ladder / Any other external parsing
- virtual AsciiString getLeftoverConfig(void) = 0;
-
- // NAT Timeouts
- virtual Int getTimeBetweenRetries() = 0;
- virtual Int getMaxManglerRetries() = 0;
- virtual time_t getRetryInterval() = 0;
- virtual time_t getKeepaliveInterval() = 0;
- virtual time_t getPortTimeout() = 0;
- virtual time_t getRoundTimeout() = 0;
-
- // Custom match
- virtual Bool restrictGamesToLobby() = 0;
-
- static GameSpyConfigInterface* create(AsciiString config);
-};
-
-extern GameSpyConfigInterface *TheGameSpyConfig;
-
-#endif // __GSCONFIG_H__
diff --git a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/GameResultsThread.h b/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/GameResultsThread.h
deleted file mode 100644
index 4cb190ca0f3..00000000000
--- a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/GameResultsThread.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: GameResultsThread.h //////////////////////////////////////////////////////
-// Generals game results thread class interface
-// Author: Matthew D. Campbell, August 2002
-
-#pragma once
-
-#ifndef __GAMERESULTSTHREAD_H__
-#define __GAMERESULTSTHREAD_H__
-
-#include "Common/SubsystemInterface.h"
-
-// this class encapsulates a request for the thread
-class GameResultsRequest
-{
-public:
- std::string hostname;
- UnsignedShort port;
- std::string results;
-};
-
-//-------------------------------------------------------------------------
-
-// this class encapsulates a response from the thread
-class GameResultsResponse
-{
-public:
- std::string hostname;
- UnsignedShort port;
- Bool sentOk;
-};
-
-//-------------------------------------------------------------------------
-
-// this is the actual message queue used to pass messages between threads
-class GameResultsInterface : public SubsystemInterface
-{
-public:
- virtual ~GameResultsInterface() {}
- virtual void startThreads( void ) = 0;
- virtual void endThreads( void ) = 0;
- virtual Bool areThreadsRunning( void ) = 0;
-
- virtual void addRequest( const GameResultsRequest& req ) = 0;
- virtual Bool getRequest( GameResultsRequest& resp ) = 0;
-
- virtual void addResponse( const GameResultsResponse& resp ) = 0;
- virtual Bool getResponse( GameResultsResponse& resp ) = 0;
-
- static GameResultsInterface* createNewGameResultsInterface( void );
-
- virtual Bool areGameResultsBeingSent( void ) = 0;
-};
-
-extern GameResultsInterface *TheGameResultsQueue;
-
-
-#endif // __GAMERESULTSTHREAD_H__
diff --git a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/LadderDefs.h b/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/LadderDefs.h
deleted file mode 100644
index b7f1ba53834..00000000000
--- a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/LadderDefs.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: LadderDefs.h //////////////////////////////////////////////////////
-// Generals ladder definitions
-// Author: Matthew D. Campbell, August 2002
-
-#pragma once
-
-#ifndef __LADDERDEFS_H__
-#define __LADDERDEFS_H__
-
-#include "Common/UnicodeString.h"
-#include "Common/AsciiString.h"
-#include "Common/STLTypedefs.h"
-
-class GameWindow;
-
-class LadderInfo
-{
-public:
- LadderInfo();
- UnicodeString name;
- UnicodeString description;
- UnicodeString location;
- Int playersPerTeam;
- Int minWins;
- Int maxWins;
- Bool randomMaps;
- Bool randomFactions;
- Bool validQM;
- Bool validCustom;
- std::list validMaps;
- std::list validFactions;
- AsciiString cryptedPassword;
- AsciiString address;
- UnsignedShort port;
- AsciiString homepageURL;
- Bool submitReplay; // with game results
- Int index;
-};
-
-typedef std::list LadderInfoList;
-
-class LadderList
-{
-public:
- LadderList();
- ~LadderList();
-
- const LadderInfo* findLadder( const AsciiString& addr, UnsignedShort port );
- const LadderInfo* findLadderByIndex( Int index ); // doesn't look in local ladders
- const LadderInfoList* getLocalLadders( void );
- const LadderInfoList* getSpecialLadders( void );
- const LadderInfoList* getStandardLadders( void );
-
-private:
- void loadLocalLadders( void );
- void checkLadder( AsciiString fname, Int index );
- LadderInfoList m_localLadders;
- LadderInfoList m_specialLadders;
- LadderInfoList m_standardLadders;
-};
-
-extern LadderList *TheLadderList;
-
-#endif // __LADDERDEFS_H__
diff --git a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/LobbyUtils.h b/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/LobbyUtils.h
deleted file mode 100644
index 5d34c8a711a..00000000000
--- a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/LobbyUtils.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: LobbyUtils.h //////////////////////////////////////////////////////
-// Generals lobby utils
-// Author: Matthew D. Campbell, Sept 2002
-
-#pragma once
-
-#ifndef __LOBBYUTILS_H__
-#define __LOBBYUTILS_H__
-
-class GameWindow;
-
-GameWindow *GetGameListBox( void );
-GameWindow *GetGameInfoListBox( void );
-NameKeyType GetGameListBoxID( void );
-NameKeyType GetGameInfoListBoxID( void );
-void GrabWindowInfo( void );
-void ReleaseWindowInfo( void );
-void RefreshGameInfoListBox( GameWindow *mainWin, GameWindow *win );
-void RefreshGameListBoxes( void );
-void ToggleGameListType( void );
-
-enum GameSortType
-{
- GAMESORT_ALPHA_ASCENDING = 0,
- GAMESORT_ALPHA_DESCENDING,
- GAMESORT_PING_ASCENDING,
- GAMESORT_PING_DESCENDING,
- GAMESORT_MAX,
-};
-
-Bool HandleSortButton( NameKeyType sortButton );
-void PopulateLobbyPlayerListbox(void);
-
-#endif // __LOBBYUTILS_H__
diff --git a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/MainMenuUtils.h b/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/MainMenuUtils.h
deleted file mode 100644
index af283c8d085..00000000000
--- a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/MainMenuUtils.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: MainMenuUtils.h //////////////////////////////////////////////////////
-// Author: Matthew D. Campbell, Sept 2002
-// Description: GameSpy version check, patch download, etc utils
-///////////////////////////////////////////////////////////////////////////////
-
-#pragma once
-
-#ifndef __MAINMENUUTILS_H__
-#define __MAINMENUUTILS_H__
-
-void HTTPThinkWrapper( void );
-void StopAsyncDNSCheck( void );
-void StartPatchCheck( void );
-void CancelPatchCheckCallback( void );
-void StartDownloadingPatches( void );
-void HandleCanceledDownload( Bool resetDropDown = TRUE );
-
-enum OverallStatsPeriod
-{
- STATS_TODAY = 0,
- STATS_YESTERDAY,
- STATS_ALLTIME,
- STATS_LASTWEEK,
- STATS_MAX
-};
-
-struct OverallStats
-{
- OverallStats();
- Int wins[STATS_MAX];
- Int losses[STATS_MAX];
-};
-
-void CheckOverallStats( void );
-void HandleOverallStats( const OverallStats& USA, const OverallStats& China, const OverallStats& GLA );
-
-void CheckNumPlayersOnline( void );
-void HandleNumPlayersOnline( Int numPlayersOnline );
-
-#endif // __MAINMENUUTILS_H__
diff --git a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/PeerDefs.h b/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/PeerDefs.h
deleted file mode 100644
index 56d60fe831e..00000000000
--- a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/PeerDefs.h
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: PeerDefs.h //////////////////////////////////////////////////////
-// Generals GameSpy Peer (chat) definitions
-// Author: Matthew D. Campbell, June 2002
-
-#pragma once
-
-#ifndef __PEERDEFS_H__
-#define __PEERDEFS_H__
-
-#include "GameSpy/Peer/Peer.h"
-#include "GameSpy/GP/GP.h"
-
-#include "GameClient/Color.h"
-#include "Common/STLTypedefs.h"
-#include "GameNetwork/GameSpy/StagingRoomGameInfo.h"
-
-class GameWindow;
-class PSPlayerStats;
-
-typedef std::set IgnoreList;
-typedef std::map SavedIgnoreMap;
-
-enum RCItemType
-{
- ITEM_BUDDY,
- ITEM_REQUEST,
- ITEM_NONBUDDY,
- ITEM_NONE,
-};
-
-class GameSpyRCMenuData
-{
-public:
- AsciiString m_nick;
- GPProfile m_id;
- RCItemType m_itemType;
-};
-
-class BuddyInfo
-{
-public:
- GPProfile m_id;
- AsciiString m_name;
- AsciiString m_email;
- AsciiString m_countryCode;
- GPEnum m_status;
- UnicodeString m_statusString;
- UnicodeString m_locationString;
-};
-typedef std::map BuddyInfoMap;
-
-class BuddyMessage
-{
-public:
- UnsignedInt m_timestamp;
- GPProfile m_senderID;
- AsciiString m_senderNick;
- GPProfile m_recipientID;
- AsciiString m_recipientNick;
- UnicodeString m_message;
-};
-typedef std::list BuddyMessageList;
-
-class GameSpyGroupRoom
-{
-public:
- GameSpyGroupRoom() { m_name = AsciiString::TheEmptyString; m_translatedName = UnicodeString::TheEmptyString; m_groupID = m_numWaiting = m_maxWaiting = m_numGames = m_numPlaying = 0; }
- AsciiString m_name;
- UnicodeString m_translatedName;
- Int m_groupID;
- Int m_numWaiting;
- Int m_maxWaiting;
- Int m_numGames;
- Int m_numPlaying;
-};
-typedef std::map GroupRoomMap;
-
-class Transport;
-class NAT;
-
-typedef std::map StagingRoomMap;
-
-class PlayerInfo
-{
-public:
- PlayerInfo() { m_name = m_locale = AsciiString::TheEmptyString; m_wins = m_losses = m_rankPoints = m_side = m_preorder = m_profileID = m_flags = 0; }
- AsciiString m_name;
- AsciiString m_locale;
- Int m_wins;
- Int m_losses;
- Int m_profileID;
- Int m_flags;
- Int m_rankPoints;
- Int m_side;
- Int m_preorder;
- Bool isIgnored( void );
-};
-struct AsciiComparator
-{
- bool operator()(AsciiString s1, AsciiString s2) const;
-};
-
-
-typedef std::map PlayerInfoMap;
-
-enum GameSpyColors {
- GSCOLOR_DEFAULT = 0,
- GSCOLOR_CURRENTROOM,
- GSCOLOR_ROOM,
- GSCOLOR_GAME,
- GSCOLOR_GAME_FULL,
- GSCOLOR_GAME_CRCMISMATCH,
- GSCOLOR_PLAYER_NORMAL,
- GSCOLOR_PLAYER_OWNER,
- GSCOLOR_PLAYER_BUDDY,
- GSCOLOR_PLAYER_SELF,
- GSCOLOR_PLAYER_IGNORED,
- GSCOLOR_CHAT_NORMAL,
- GSCOLOR_CHAT_EMOTE,
- GSCOLOR_CHAT_OWNER,
- GSCOLOR_CHAT_OWNER_EMOTE,
- GSCOLOR_CHAT_PRIVATE,
- GSCOLOR_CHAT_PRIVATE_EMOTE,
- GSCOLOR_CHAT_PRIVATE_OWNER,
- GSCOLOR_CHAT_PRIVATE_OWNER_EMOTE,
- GSCOLOR_CHAT_BUDDY,
- GSCOLOR_CHAT_SELF,
- GSCOLOR_ACCEPT_TRUE,
- GSCOLOR_ACCEPT_FALSE,
- GSCOLOR_MAP_SELECTED,
- GSCOLOR_MAP_UNSELECTED,
- GSCOLOR_MOTD,
- GSCOLOR_MOTD_HEADING,
- GSCOLOR_MAX
-};
-
-extern Color GameSpyColor[GSCOLOR_MAX];
-
-enum GameSpyBuddyStatus {
- BUDDY_OFFLINE,
- BUDDY_ONLINE,
- BUDDY_LOBBY,
- BUDDY_STAGING,
- BUDDY_LOADING,
- BUDDY_PLAYING,
- BUDDY_MATCHING,
- BUDDY_MAX
-};
-
-// ---------------------------------------------------
-// this class holds info used in the main thread
-class GameSpyInfoInterface
-{
-public:
- virtual ~GameSpyInfoInterface() {};
- virtual void reset( void ) {};
- virtual void clearGroupRoomList( void ) = 0;
- virtual GroupRoomMap* getGroupRoomList( void ) = 0;
- virtual void addGroupRoom( GameSpyGroupRoom room ) = 0;
- virtual Bool gotGroupRoomList( void ) = 0;
- virtual void joinGroupRoom( Int groupID ) = 0;
- virtual void leaveGroupRoom( void ) = 0;
- virtual void joinBestGroupRoom( void ) = 0;
- virtual void setCurrentGroupRoom( Int groupID ) = 0;
- virtual Int getCurrentGroupRoom( void ) = 0;
- virtual void updatePlayerInfo( PlayerInfo pi, AsciiString oldNick = AsciiString::TheEmptyString ) = 0;
- virtual void playerLeftGroupRoom( AsciiString nick ) = 0;
- virtual PlayerInfoMap* getPlayerInfoMap( void ) = 0;
-
- virtual BuddyInfoMap* getBuddyMap( void ) = 0;
- virtual BuddyInfoMap* getBuddyRequestMap( void ) = 0;
- virtual BuddyMessageList* getBuddyMessages( void ) = 0;
- virtual Bool isBuddy( Int id ) = 0;
-
- virtual void setLocalName( AsciiString name ) = 0;
- virtual AsciiString getLocalName( void ) = 0;
- virtual void setLocalProfileID( Int profileID ) = 0;
- virtual Int getLocalProfileID( void ) = 0;
- virtual AsciiString getLocalEmail( void ) = 0;
- virtual void setLocalEmail( AsciiString email ) = 0;
- virtual AsciiString getLocalPassword( void ) = 0;
- virtual void setLocalPassword( AsciiString passwd ) = 0;
- virtual void setLocalBaseName( AsciiString name ) = 0;
- virtual AsciiString getLocalBaseName( void ) = 0;
-
- virtual void setCachedLocalPlayerStats( PSPlayerStats stats ) = 0;
- virtual PSPlayerStats getCachedLocalPlayerStats( void ) = 0;
-
- virtual void clearStagingRoomList( void ) = 0;
- virtual StagingRoomMap* getStagingRoomList( void ) = 0;
- virtual GameSpyStagingRoom* findStagingRoomByID( Int id ) = 0;
- virtual void addStagingRoom( GameSpyStagingRoom room ) = 0;
- virtual void updateStagingRoom( GameSpyStagingRoom room ) = 0;
- virtual void removeStagingRoom( GameSpyStagingRoom room ) = 0;
- virtual Bool hasStagingRoomListChanged( void ) = 0;
- virtual void leaveStagingRoom( void ) = 0;
- virtual void markAsStagingRoomHost( void ) = 0;
- virtual void markAsStagingRoomJoiner( Int game ) = 0;
- virtual void sawFullGameList( void ) = 0;
-
- virtual Bool amIHost( void ) = 0;
- virtual GameSpyStagingRoom* getCurrentStagingRoom( void ) = 0;
- virtual void setGameOptions( void ) = 0;
- virtual Int getCurrentStagingRoomID( void ) = 0;
-
- virtual void setDisallowAsianText( Bool val ) = 0;
- virtual void setDisallowNonAsianText( Bool val ) = 0;
- virtual Bool getDisallowAsianText( void ) = 0;
- virtual Bool getDisallowNonAsianText(void ) = 0;
-
- // chat
- virtual void registerTextWindow( GameWindow *win ) = 0;
- virtual void unregisterTextWindow( GameWindow *win ) = 0;
- virtual Int addText( UnicodeString message, Color c, GameWindow *win ) = 0;
- virtual void addChat( PlayerInfo p, UnicodeString msg, Bool isPublic, Bool isAction, GameWindow *win ) = 0;
- virtual void addChat( AsciiString nick, Int profileID, UnicodeString msg, Bool isPublic, Bool isAction, GameWindow *win ) = 0;
- virtual Bool sendChat( UnicodeString message, Bool isAction, GameWindow *playerListbox ) = 0;
-
- virtual void setMOTD( const AsciiString& motd ) = 0;
- virtual const AsciiString& getMOTD( void ) = 0;
-
- virtual void setConfig( const AsciiString& config ) = 0;
- virtual const AsciiString& getConfig( void ) = 0;
-
- virtual void setPingString( const AsciiString& ping ) = 0;
- virtual const AsciiString& getPingString( void ) = 0;
- virtual Int getPingValue( const AsciiString& otherPing ) = 0;
-
- static GameSpyInfoInterface* createNewGameSpyInfoInterface( void );
-
- virtual void addToSavedIgnoreList( Int profileID, AsciiString nick ) = 0;
- virtual void removeFromSavedIgnoreList( Int profileID ) = 0;
- virtual Bool isSavedIgnored( Int profileID ) = 0;
- virtual SavedIgnoreMap returnSavedIgnoreList( void ) = 0;
- virtual void loadSavedIgnoreList( void ) = 0;
-
- virtual IgnoreList returnIgnoreList( void ) = 0;
- virtual void addToIgnoreList( AsciiString nick ) = 0;
- virtual void removeFromIgnoreList( AsciiString nick ) = 0;
- virtual Bool isIgnored( AsciiString nick ) = 0;
-
- virtual void setLocalIPs(UnsignedInt internalIP, UnsignedInt externalIP) = 0;
- virtual UnsignedInt getInternalIP(void) = 0;
- virtual UnsignedInt getExternalIP(void) = 0;
-
- virtual Bool isDisconnectedAfterGameStart(Int *reason) const = 0;
- virtual void markAsDisconnectedAfterGameStart(Int reason) = 0;
-
- virtual Bool didPlayerPreorder( Int profileID ) const = 0;
- virtual void markPlayerAsPreorder( Int profileID ) = 0;
-
- virtual void setMaxMessagesPerUpdate( Int num ) = 0;
- virtual Int getMaxMessagesPerUpdate( void ) = 0;
-
- virtual Int getAdditionalDisconnects( void ) = 0;
- virtual void clearAdditionalDisconnects( void ) = 0;
- virtual void readAdditionalDisconnects( void ) = 0;
- virtual void updateAdditionalGameSpyDisconnections(Int count) = 0;
-};
-
-extern GameSpyInfoInterface *TheGameSpyInfo;
-
-void WOLDisplayGameOptions( void );
-void WOLDisplaySlotList( void );
-Bool GetLocalChatConnectionAddress(AsciiString serverName, UnsignedShort serverPort, UnsignedInt& localIP);
-void SetLobbyAttemptHostJoin(Bool start);
-void SendStatsToOtherPlayers(const GameInfo *game);
-
-class PSPlayerStats;
-void GetAdditionalDisconnectsFromUserFile(PSPlayerStats *stats);
-extern Int GetAdditionalDisconnectsFromUserFile(Int playerID);
-
-//-------------------------------------------------------------------------
-// These functions set up the globals and threads neccessary for our GameSpy impl.
-
-void SetUpGameSpy( const char *motdBuffer, const char *configBuffer );
-void TearDownGameSpy( void );
-
-#endif // __PEERDEFS_H__
diff --git a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/PeerDefsImplementation.h b/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/PeerDefsImplementation.h
deleted file mode 100644
index f086b48b93b..00000000000
--- a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/PeerDefsImplementation.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: PeerDefsImplementation.h //////////////////////////////////////////////////////
-// Generals GameSpy Peer (chat) implementation definitions
-// Author: Matthew D. Campbell, Sept 2002
-
-#pragma once
-
-#ifndef __PEERDEFSIMPLEMENTATION_H__
-#define __PEERDEFSIMPLEMENTATION_H__
-
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpy/PersistentStorageThread.h"
-
-
-class GameSpyInfo : public GameSpyInfoInterface
-{
-public:
- GameSpyInfo();
- virtual ~GameSpyInfo();
- virtual void reset( void );
- virtual void clearGroupRoomList( void ) { m_groupRooms.clear(); m_gotGroupRoomList = false; }
- virtual GroupRoomMap* getGroupRoomList( void ) { return &m_groupRooms; }
- virtual void addGroupRoom( GameSpyGroupRoom room );
- virtual Bool gotGroupRoomList( void ) { return m_gotGroupRoomList; }
- virtual void joinGroupRoom( Int groupID );
- virtual void leaveGroupRoom( void );
- virtual void joinBestGroupRoom( void );
- virtual void setCurrentGroupRoom( Int groupID ) { m_currentGroupRoomID = groupID; m_playerInfoMap.clear(); }
- virtual Int getCurrentGroupRoom( void ) { return m_currentGroupRoomID; }
- virtual void updatePlayerInfo( PlayerInfo pi, AsciiString oldNick = AsciiString::TheEmptyString );
- virtual void playerLeftGroupRoom( AsciiString nick );
- virtual PlayerInfoMap* getPlayerInfoMap( void ) { return &m_playerInfoMap; }
-
- virtual void setLocalName( AsciiString name ) { m_localName = name; }
- virtual AsciiString getLocalName( void ) { return m_localName; }
- virtual void setLocalProfileID( Int profileID ) { m_localProfileID = profileID; }
- virtual Int getLocalProfileID( void ) { return m_localProfileID; }
- virtual AsciiString getLocalEmail( void ) { return m_localEmail; }
- virtual void setLocalEmail( AsciiString email ) { m_localEmail = email; }
- virtual AsciiString getLocalPassword( void ){ return m_localPasswd; }
- virtual void setLocalPassword( AsciiString passwd ) { m_localPasswd = passwd; }
- virtual void setLocalBaseName( AsciiString name ) { m_localBaseName = name; }
- virtual AsciiString getLocalBaseName( void ){ return m_localBaseName; }
-
- virtual void setCachedLocalPlayerStats( PSPlayerStats stats ) {m_cachedLocalPlayerStats = stats; }
- virtual PSPlayerStats getCachedLocalPlayerStats( void ){ return m_cachedLocalPlayerStats; }
-
- virtual BuddyInfoMap* getBuddyMap( void ) { return &m_buddyMap; }
- virtual BuddyInfoMap* getBuddyRequestMap( void ) { return &m_buddyRequestMap; }
- virtual BuddyMessageList* getBuddyMessages( void ) { return &m_buddyMessages; }
- virtual Bool isBuddy( Int id );
-
- virtual void clearStagingRoomList( void );
- virtual StagingRoomMap* getStagingRoomList( void ) { return &m_stagingRooms; }
- virtual GameSpyStagingRoom* findStagingRoomByID( Int id );
- virtual void addStagingRoom( GameSpyStagingRoom room );
- virtual void updateStagingRoom( GameSpyStagingRoom room );
- virtual void removeStagingRoom( GameSpyStagingRoom room );
- virtual Bool hasStagingRoomListChanged( void );
- virtual void leaveStagingRoom( void );
- virtual void markAsStagingRoomHost( void );
- virtual void markAsStagingRoomJoiner( Int game );
- virtual Int getCurrentStagingRoomID( void ) { return m_localStagingRoomID; }
-
- virtual void sawFullGameList( void ) { m_sawFullGameList = TRUE; }
-
- virtual void setDisallowAsianText( Bool val );
- virtual void setDisallowNonAsianText( Bool val );
- virtual Bool getDisallowAsianText( void );
- virtual Bool getDisallowNonAsianText(void );
- // chat
- virtual void registerTextWindow( GameWindow *win );
- virtual void unregisterTextWindow( GameWindow *win );
- virtual Int addText( UnicodeString message, Color c, GameWindow *win );
- virtual void addChat( PlayerInfo p, UnicodeString msg, Bool isPublic, Bool isAction, GameWindow *win );
- virtual void addChat( AsciiString nick, Int profileID, UnicodeString msg, Bool isPublic, Bool isAction, GameWindow *win );
- virtual Bool sendChat( UnicodeString message, Bool isAction, GameWindow *playerListbox );
-
- virtual void setMOTD( const AsciiString& motd );
- virtual const AsciiString& getMOTD( void );
- virtual void setConfig( const AsciiString& config );
- virtual const AsciiString& getConfig( void );
-
- virtual void setPingString( const AsciiString& ping ) { m_pingString = ping; }
- virtual const AsciiString& getPingString( void ) { return m_pingString; }
- virtual Int getPingValue( const AsciiString& otherPing );
-
- virtual Bool amIHost( void );
- virtual GameSpyStagingRoom* getCurrentStagingRoom( void );
- virtual void setGameOptions( void );
-
- virtual void addToIgnoreList( AsciiString nick );
- virtual void removeFromIgnoreList( AsciiString nick );
- virtual Bool isIgnored( AsciiString nick );
- virtual IgnoreList returnIgnoreList( void );
-
- virtual void loadSavedIgnoreList( void );
- virtual SavedIgnoreMap returnSavedIgnoreList( void );
- virtual void addToSavedIgnoreList( Int profileID, AsciiString nick);
- virtual void removeFromSavedIgnoreList( Int profileID );
- virtual Bool isSavedIgnored( Int profileID );
- virtual void setLocalIPs(UnsignedInt internalIP, UnsignedInt externalIP);
- virtual UnsignedInt getInternalIP(void) { return m_internalIP; }
- virtual UnsignedInt getExternalIP(void) { return m_externalIP; }
-
- virtual Bool isDisconnectedAfterGameStart(Int *reason) const { if (reason) *reason = m_disconReason; return m_isDisconAfterGameStart; }
- virtual void markAsDisconnectedAfterGameStart(Int reason) { m_isDisconAfterGameStart = TRUE; m_disconReason = reason; }
-
- virtual Bool didPlayerPreorder( Int profileID ) const;
- virtual void markPlayerAsPreorder( Int profileID );
-
- virtual void setMaxMessagesPerUpdate( Int num );
- virtual Int getMaxMessagesPerUpdate( void );
-
- virtual Int getAdditionalDisconnects( void );
- virtual void clearAdditionalDisconnects( void );
- virtual void readAdditionalDisconnects( void );
- virtual void updateAdditionalGameSpyDisconnections(Int count);
-private:
- Bool m_sawFullGameList;
- Bool m_isDisconAfterGameStart;
- Int m_disconReason;
- AsciiString m_rawMotd;
- AsciiString m_rawConfig;
- AsciiString m_pingString;
- GroupRoomMap m_groupRooms;
- StagingRoomMap m_stagingRooms;
- Bool m_stagingRoomsDirty;
- BuddyInfoMap m_buddyMap;
- BuddyInfoMap m_buddyRequestMap;
- PlayerInfoMap m_playerInfoMap;
- BuddyMessageList m_buddyMessages;
- Int m_currentGroupRoomID;
- Bool m_gotGroupRoomList;
- AsciiString m_localName;
- Int m_localProfileID;
- AsciiString m_localPasswd;
- AsciiString m_localEmail;
- AsciiString m_localBaseName;
- PSPlayerStats m_cachedLocalPlayerStats;
- Bool m_disallowAsainText;
- Bool m_disallowNonAsianText;
- UnsignedInt m_internalIP, m_externalIP;
- Int m_maxMessagesPerUpdate;
-
- Int m_joinedStagingRoom; // if we join a staging room, this holds its ID (0 otherwise)
- Bool m_isHosting; // if we host, this is true, and
- GameSpyStagingRoom m_localStagingRoom; // this holds the GameInfo for it.
- Int m_localStagingRoomID;
-
- IgnoreList m_ignoreList;
- SavedIgnoreMap m_savedIgnoreMap;
-
- std::set m_textWindows;
-
- std::set m_preorderPlayers;
-
- Int m_additionalDisconnects;
-};
-
-#endif // __PEERDEFS_H__
diff --git a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/PeerThread.h b/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/PeerThread.h
deleted file mode 100644
index 99e7cf47b49..00000000000
--- a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/PeerThread.h
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: PeerThread.h //////////////////////////////////////////////////////
-// Generals GameSpy Peer-to-peer chat thread class interface
-// Author: Matthew D. Campbell, June 2002
-
-#pragma once
-
-#ifndef __PEERTHREAD_H__
-#define __PEERTHREAD_H__
-
-#include "GameSpy/Peer/Peer.h"
-#include "GameNetwork/NetworkDefs.h"
-
-enum SerialAuthResult
-{
- SERIAL_NONEXISTENT,
- SERIAL_AUTHFAILED,
- SERIAL_BANNED,
- SERIAL_OK
-};
-
-// this class encapsulates a request for the peer thread
-class PeerRequest
-{
-public:
- enum
- {
- PEERREQUEST_LOGIN, // attempt to login
- PEERREQUEST_LOGOUT, // log out if connected
- PEERREQUEST_MESSAGEPLAYER,
- PEERREQUEST_MESSAGEROOM,
- PEERREQUEST_JOINGROUPROOM,
- PEERREQUEST_LEAVEGROUPROOM,
- PEERREQUEST_STARTGAMELIST,
- PEERREQUEST_STOPGAMELIST,
- PEERREQUEST_CREATESTAGINGROOM,
- PEERREQUEST_SETGAMEOPTIONS,
- PEERREQUEST_JOINSTAGINGROOM,
- PEERREQUEST_LEAVESTAGINGROOM,
- PEERREQUEST_UTMPLAYER,
- PEERREQUEST_UTMROOM,
- PEERREQUEST_STARTGAME,
- PEERREQUEST_STARTQUICKMATCH,
- PEERREQUEST_WIDENQUICKMATCHSEARCH,
- PEERREQUEST_STOPQUICKMATCH,
- PEERREQUEST_PUSHSTATS,
- PEERREQUEST_GETEXTENDEDSTAGINGROOMINFO,
- PEERREQUEST_MAX
- } peerRequestType;
-
- std::string nick; // only used by login, but must be outside the union b/c of copy constructor
- std::wstring text; // can't be in a union
- std::string password;
- std::string email;
- std::string id;
-
- // gameopts
- std::string options; // full string for UTMs
- std::string ladderIP;
- std::string hostPingStr;
- std::string gameOptsMapName;
- std::string gameOptsPlayerNames[MAX_SLOTS];
-
- std::vector qmMaps;
-
- union
- {
- struct
- {
- Int profileID;
- } login;
-
- struct
- {
- Int id;
- } groupRoom;
-
- struct
- {
- Bool restrictGameList;
- } gameList;
-
- struct
- {
- Bool isAction;
- } message;
-
- struct
- {
- Int id;
- } stagingRoom;
-
- struct
- {
- UnsignedInt exeCRC;
- UnsignedInt iniCRC;
- UnsignedInt gameVersion;
- Bool allowObservers;
- UnsignedShort ladPort;
- UnsignedInt ladPassCRC;
- Bool restrictGameList;
- } stagingRoomCreation;
-
- struct
- {
- Int wins[MAX_SLOTS];
- Int losses[MAX_SLOTS];
- Int profileID[MAX_SLOTS];
- Int faction[MAX_SLOTS];
- Int color[MAX_SLOTS];
- Int numPlayers;
- Int maxPlayers;
- Int numObservers;
- } gameOptions;
-
- struct
- {
- Bool isStagingRoom;
- } UTM;
-
- struct
- {
- Int minPointPercentage, maxPointPercentage, points;
- Int widenTime;
- Int ladderID;
- UnsignedInt ladderPassCRC;
- Int maxPing;
- Int maxDiscons, discons;
- char pings[17]; // 8 servers (0-ff), 1 NULL
- Int numPlayers;
- Int botID;
- Int roomID;
- Int side;
- Int color;
- Int NAT;
- UnsignedInt exeCRC;
- UnsignedInt iniCRC;
- } QM;
-
- struct
- {
- Int locale;
- Int wins;
- Int losses;
- Int rankPoints;
- Int side;
- Bool preorder;
- } statsToPush;
-
- };
-};
-
-//-------------------------------------------------------------------------
-
-enum DisconnectReason
-{
- DISCONNECT_NICKTAKEN = 1,
- DISCONNECT_BADNICK,
- DISCONNECT_LOSTCON,
- DISCONNECT_COULDNOTCONNECT,
- DISCONNECT_GP_LOGIN_TIMEOUT,
- DISCONNECT_GP_LOGIN_BAD_NICK,
- DISCONNECT_GP_LOGIN_BAD_EMAIL,
- DISCONNECT_GP_LOGIN_BAD_PASSWORD,
- DISCONNECT_GP_LOGIN_BAD_PROFILE,
- DISCONNECT_GP_LOGIN_PROFILE_DELETED,
- DISCONNECT_GP_LOGIN_CONNECTION_FAILED,
- DISCONNECT_GP_LOGIN_SERVER_AUTH_FAILED,
- DISCONNECT_SERIAL_INVALID,
- DISCONNECT_SERIAL_NOT_PRESENT,
- DISCONNECT_SERIAL_BANNED,
- DISCONNECT_GP_NEWUSER_BAD_NICK,
- DISCONNECT_GP_NEWUSER_BAD_PASSWORD,
- DISCONNECT_GP_NEWPROFILE_BAD_NICK,
- DISCONNECT_GP_NEWPROFILE_BAD_OLD_NICK,
- DISCONNECT_MAX,
-};
-
-enum QMStatus
-{
- QM_IDLE,
- QM_JOININGQMCHANNEL,
- QM_LOOKINGFORBOT,
- QM_SENTINFO,
- QM_WORKING,
- QM_POOLSIZE,
- QM_WIDENINGSEARCH,
- QM_MATCHED,
- QM_INCHANNEL,
- QM_NEGOTIATINGFIREWALLS,
- QM_STARTINGGAME,
- QM_COULDNOTFINDBOT,
- QM_COULDNOTFINDCHANNEL,
- QM_COULDNOTNEGOTIATEFIREWALLS,
- QM_STOPPED,
-};
-
-// this class encapsulates an action the peer thread wants from the UI
-class PeerResponse
-{
-public:
- enum
- {
- PEERRESPONSE_LOGIN,
- PEERRESPONSE_DISCONNECT,
- PEERRESPONSE_MESSAGE,
- PEERRESPONSE_GROUPROOM,
- PEERRESPONSE_STAGINGROOM,
- PEERRESPONSE_STAGINGROOMLISTCOMPLETE,
- PEERRESPONSE_STAGINGROOMPLAYERINFO,
- PEERRESPONSE_JOINGROUPROOM,
- PEERRESPONSE_CREATESTAGINGROOM,
- PEERRESPONSE_JOINSTAGINGROOM,
- PEERRESPONSE_PLAYERJOIN,
- PEERRESPONSE_PLAYERLEFT,
- PEERRESPONSE_PLAYERCHANGEDNICK,
- PEERRESPONSE_PLAYERINFO,
- PEERRESPONSE_PLAYERCHANGEDFLAGS,
- PEERRESPONSE_ROOMUTM,
- PEERRESPONSE_PLAYERUTM,
- PEERRESPONSE_QUICKMATCHSTATUS,
- PEERRESPONSE_GAMESTART,
- PEERRESPONSE_FAILEDTOHOST,
- PEERRESPONSE_MAX
- } peerResponseType;
-
- std::string groupRoomName; // can't be in union
-
- std::string nick; // can't be in a union
- std::string oldNick; // can't be in a union
- std::wstring text; // can't be in a union
- std::string locale; // can't be in a union
-
- std::string stagingServerGameOptions; // full string from UTMs
-
- // game opts sent with PEERRESPONSE_STAGINGROOM
- std::wstring stagingServerName;
- std::string stagingServerPingString;
- std::string stagingServerLadderIP;
- std::string stagingRoomMapName;
-
- // game opts sent with PEERRESPONSE_STAGINGROOMPLAYERINFO
- std::string stagingRoomPlayerNames[MAX_SLOTS];
-
- std::string command;
- std::string commandOptions;
-
- union
- {
- struct
- {
- DisconnectReason reason;
- } discon;
-
- struct
- {
- Int id;
- Int numWaiting;
- Int maxWaiting;
- Int numGames;
- Int numPlaying;
- } groupRoom;
-
- struct
- {
- Int id;
- Bool ok;
- } joinGroupRoom;
-
- struct
- {
- Int result;
- } createStagingRoom;
-
- struct
- {
- Int id;
- Bool ok;
- Bool isHostPresent;
- Int result; // for failures
- } joinStagingRoom;
-
- struct
- {
- Bool isPrivate;
- Bool isAction;
- Int profileID;
- } message;
-
- struct
- {
- Int profileID;
- Int wins;
- Int losses;
- RoomType roomType;
- Int flags;
- UnsignedInt IP;
- Int rankPoints;
- Int side;
- Int preorder;
- UnsignedInt internalIP; // for us, on connection
- UnsignedInt externalIP; // for us, on connection
- } player;
-
- struct
- {
- Int id;
- Int action;
- Bool isStaging;
- Bool requiresPassword;
- Bool allowObservers;
- UnsignedInt version;
- UnsignedInt exeCRC;
- UnsignedInt iniCRC;
- UnsignedShort ladderPort;
- Int wins[MAX_SLOTS];
- Int losses[MAX_SLOTS];
- Int profileID[MAX_SLOTS];
- Int faction[MAX_SLOTS];
- Int color[MAX_SLOTS];
- Int numPlayers;
- Int numObservers;
- Int maxPlayers;
- Int percentComplete;
- } stagingRoom;
-
- struct
- {
- QMStatus status;
- Int poolSize;
- Int mapIdx; // when matched
- Int seed; // when matched
- UnsignedInt IP[MAX_SLOTS]; // when matched
- Int side[MAX_SLOTS]; // when matched
- Int color[MAX_SLOTS]; // when matched
- Int nat[MAX_SLOTS];
- } qmStatus;
- };
-};
-
-//-------------------------------------------------------------------------
-
-// this is the actual message queue used to pass messages between threads
-class GameSpyPeerMessageQueueInterface
-{
-public:
- virtual ~GameSpyPeerMessageQueueInterface() {}
- virtual void startThread( void ) = 0;
- virtual void endThread( void ) = 0;
- virtual Bool isThreadRunning( void ) = 0;
- virtual Bool isConnected( void ) = 0;
- virtual Bool isConnecting( void ) = 0;
-
- virtual void addRequest( const PeerRequest& req ) = 0;
- virtual Bool getRequest( PeerRequest& req ) = 0;
-
- virtual void addResponse( const PeerResponse& resp ) = 0;
- virtual Bool getResponse( PeerResponse& resp ) = 0;
-
- virtual SerialAuthResult getSerialAuthResult( void ) = 0;
-
- static GameSpyPeerMessageQueueInterface* createNewMessageQueue( void );
-};
-
-extern GameSpyPeerMessageQueueInterface *TheGameSpyPeerMessageQueue;
-
-#endif // __PEERTHREAD_H__
diff --git a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/PersistentStorageDefs.h b/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/PersistentStorageDefs.h
deleted file mode 100644
index 68b27ed94cb..00000000000
--- a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/PersistentStorageDefs.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: PersistentStorageDefs.h //////////////////////////////////////////////////////
-// Generals GameSpy Persistent Storage definitions
-// Author: Matthew D. Campbell, July 2002
-
-#pragma once
-
-#ifndef __PERSISTENTSTORAGEDEFS_H__
-#define __PERSISTENTSTORAGEDEFS_H__
-
-enum LocaleType
-{
- LOC_UNKNOWN = 0,
- LOC_MIN = 1,
- LOC_MAX = 37
-};
-
-void HandlePersistentStorageResponses(void);
-void UpdateLocalPlayerStats(void);
-
-void SetLookAtPlayer( Int id, AsciiString nick );
-void PopulatePlayerInfoWindows( AsciiString parentWindowName );
-
-#endif // __PERSISTENTSTORAGEDEFS_H__
diff --git a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/PersistentStorageThread.h b/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/PersistentStorageThread.h
deleted file mode 100644
index 0d500f1e24e..00000000000
--- a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/PersistentStorageThread.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: PersistentStorageThread.h //////////////////////////////////////////////////////
-// Generals GameSpy Persistent Storage thread class interface
-// Author: Matthew D. Campbell, July 2002
-
-#pragma once
-
-#ifndef __PERSISTENTSTORAGETHREAD_H__
-#define __PERSISTENTSTORAGETHREAD_H__
-
-#include "GameSpy/gstats/gpersist.h"
-
-#define MAX_BUDDY_CHAT_LEN 128
-
-typedef std::map PerGeneralMap;
-// this structure holds all info on a player that is stored online
-class PSPlayerStats
-{
-public:
- PSPlayerStats( void );
- PSPlayerStats( const PSPlayerStats& other );
- void reset(void);
-
- Int id;
- PerGeneralMap wins;
- PerGeneralMap losses;
- PerGeneralMap games;
- PerGeneralMap duration;
- PerGeneralMap unitsKilled;
- PerGeneralMap unitsLost;
- PerGeneralMap unitsBuilt;
- PerGeneralMap buildingsKilled;
- PerGeneralMap buildingsLost;
- PerGeneralMap buildingsBuilt;
- PerGeneralMap earnings;
- PerGeneralMap techCaptured;
- PerGeneralMap discons;
- PerGeneralMap desyncs;
- PerGeneralMap surrenders;
- PerGeneralMap gamesOf2p;
- PerGeneralMap gamesOf3p;
- PerGeneralMap gamesOf4p;
- PerGeneralMap gamesOf5p;
- PerGeneralMap gamesOf6p;
- PerGeneralMap gamesOf7p;
- PerGeneralMap gamesOf8p;
- PerGeneralMap customGames;
- PerGeneralMap QMGames;
- Int locale;
- Int gamesAsRandom;
- std::string options;
- std::string systemSpec;
- Real lastFPS;
- Int lastGeneral;
- Int gamesInRowWithLastGeneral;
- Int challengeMedals;
- Int battleHonors;
- Int QMwinsInARow;
- Int maxQMwinsInARow;
-
- Int winsInARow;
- Int maxWinsInARow;
- Int lossesInARow;
- Int maxLossesInARow;
- Int disconsInARow;
- Int maxDisconsInARow;
- Int desyncsInARow;
- Int maxDesyncsInARow;
-
- Int builtParticleCannon;
- Int builtNuke;
- Int builtSCUD;
-
- Int lastLadderPort;
- std::string lastLadderHost;
-
- void incorporate( const PSPlayerStats& other );
-};
-
-// this class encapsulates a request for the thread
-class PSRequest
-{
-public:
- PSRequest();
- enum
- {
- PSREQUEST_READPLAYERSTATS, // read stats for a player
- PSREQUEST_UPDATEPLAYERSTATS, // update stats on the server
- PSREQUEST_UPDATEPLAYERLOCALE, // update locale on the server
- PSREQUEST_READCDKEYSTATS, // read stats for a cdkey
- PSREQUEST_SENDGAMERESTOGAMESPY, // report game results to GameSpy
- PSREQUEST_MAX
- } requestType;
-
- // player stats for the *PLAYERSTATS
- PSPlayerStats player;
-
- // cdkey for READCDKEYSTATS;
- std::string cdkey;
-
- // our info for UPDATEPLAYERSTATS
- std::string nick;
- std::string password;
- std::string email;
- Bool addDiscon;
- Bool addDesync;
- Int lastHouse;
-
- // for GameRes
- std::string results;
-};
-
-//-------------------------------------------------------------------------
-
-// this class encapsulates a response from the thread
-class PSResponse
-{
-public:
- enum
- {
- PSRESPONSE_PLAYERSTATS,
- PSRESPONSE_COULDNOTCONNECT,
- PSRESPONSE_PREORDER,
- PSRESPONSE_MAX
- } responseType;
-
- // player stats for the *PLAYERSTATS
- PSPlayerStats player;
-
- // preorder flag
- Bool preorder;
-};
-
-//-------------------------------------------------------------------------
-
-// this is the actual message queue used to pass messages between threads
-class GameSpyPSMessageQueueInterface
-{
-public:
- virtual ~GameSpyPSMessageQueueInterface() {}
- virtual void startThread( void ) = 0;
- virtual void endThread( void ) = 0;
- virtual Bool isThreadRunning( void ) = 0;
-
- virtual void addRequest( const PSRequest& req ) = 0;
- virtual Bool getRequest( PSRequest& req ) = 0;
-
- virtual void addResponse( const PSResponse& resp ) = 0;
- virtual Bool getResponse( PSResponse& resp ) = 0;
-
- // called from the main thread
- virtual void trackPlayerStats( PSPlayerStats stats ) = 0;
- virtual PSPlayerStats findPlayerStatsByID( Int id ) = 0;
-
- static GameSpyPSMessageQueueInterface* createNewMessageQueue( void );
-
- static std::string formatPlayerKVPairs( PSPlayerStats stats );
- static PSPlayerStats parsePlayerKVPairs( std::string kvPairs );
-};
-
-extern GameSpyPSMessageQueueInterface *TheGameSpyPSMessageQueue;
-
-
-#endif // __PERSISTENTSTORAGETHREAD_H__
diff --git a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/PingThread.h b/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/PingThread.h
deleted file mode 100644
index 0ed12049189..00000000000
--- a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/PingThread.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: PingThread.h //////////////////////////////////////////////////////
-// Generals ping thread class interface
-// Author: Matthew D. Campbell, August 2002
-// Note: adapted from WOLAPI
-
-#pragma once
-
-#ifndef __PINGTHREAD_H__
-#define __PINGTHREAD_H__
-
-// this class encapsulates a request for the thread
-class PingRequest
-{
-public:
- std::string hostname;
- Int repetitions;
- Int timeout;
-};
-
-//-------------------------------------------------------------------------
-
-// this class encapsulates a response from the thread
-class PingResponse
-{
-public:
- std::string hostname;
- Int avgPing;
- Int repetitions;
-};
-
-//-------------------------------------------------------------------------
-
-// this is the actual message queue used to pass messages between threads
-class PingerInterface
-{
-public:
- virtual ~PingerInterface() {}
- virtual void startThreads( void ) = 0;
- virtual void endThreads( void ) = 0;
- virtual Bool areThreadsRunning( void ) = 0;
-
- virtual void addRequest( const PingRequest& req ) = 0;
- virtual Bool getRequest( PingRequest& resp ) = 0;
-
- virtual void addResponse( const PingResponse& resp ) = 0;
- virtual Bool getResponse( PingResponse& resp ) = 0;
-
- static PingerInterface* createNewPingerInterface( void );
-
- virtual Bool arePingsInProgress( void ) = 0;
- virtual Int getPing( AsciiString hostname ) = 0;
- virtual void clearPingMap( void ) = 0;
- virtual AsciiString getPingString( Int timeout ) = 0;
-};
-
-extern PingerInterface *ThePinger;
-
-
-#endif // __PINGTHREAD_H__
diff --git a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/StagingRoomGameInfo.h b/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/StagingRoomGameInfo.h
deleted file mode 100644
index a66e9a1e180..00000000000
--- a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/StagingRoomGameInfo.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: StagingRoomGameInfo.h //////////////////////////////////////////////////////
-// Generals GameSpy GameInfo
-// Author: Matthew D. Campbell, Sept 2002
-
-#pragma once
-
-#ifndef __STAGINGROOMGAMEINFO_H__
-#define __STAGINGROOMGAMEINFO_H__
-
-#include "GameNetwork/GameInfo.h"
-#include "GameNetwork/Transport.h"
-
-class GameSpyGameSlot : public GameSlot
-{
-public:
- GameSpyGameSlot();
- Int getProfileID( void ) const { return m_profileID; }
- void setProfileID( Int id ) { m_profileID = id; }
- AsciiString getLoginName( void ) const { return m_gameSpyLogin; }
- void setLoginName( AsciiString name ) { m_gameSpyLogin = name; }
- AsciiString getLocale( void ) const { return m_gameSpyLocale; }
- void setLocale( AsciiString name ) { m_gameSpyLocale = name; }
- Int getWins( void ) const { return m_wins; }
- Int getLosses( void ) const { return m_losses; }
- void setWins( Int wins ) { m_wins = wins; }
- void setLosses( Int losses ) { m_losses = losses; }
-
- Int getSlotRankPoints( void ) const { return m_rankPoints; }
- Int getFavoriteSide( void ) const { return m_favoriteSide; }
- void setSlotRankPoints( Int val ) { m_rankPoints = val; }
- void setFavoriteSide( Int val ) { m_favoriteSide = val; }
-
- void setPingString( AsciiString pingStr );
- inline AsciiString getPingString( void ) const { return m_pingStr; }
- inline Int getPingAsInt( void ) const { return m_pingInt; }
-
-protected:
- Int m_profileID;
- AsciiString m_gameSpyLogin;
- AsciiString m_gameSpyLocale;
-
- AsciiString m_pingStr;
- Int m_pingInt;
- Int m_wins, m_losses;
- Int m_rankPoints, m_favoriteSide;
-};
-
-/**
- * GameSpyStagingRoom class - maintains information about the GameSpy game and
- * the contents of its slot list throughout the game.
- */
-class GameSpyStagingRoom : public GameInfo
-{
-private:
- GameSpyGameSlot m_GameSpySlot[MAX_SLOTS]; ///< The GameSpy Games Slot List
- UnicodeString m_gameName;
- Int m_id;
- Transport *m_transport;
- AsciiString m_localName;
- Bool m_requiresPassword;
- Bool m_allowObservers;
- UnsignedInt m_version;
- UnsignedInt m_exeCRC;
- UnsignedInt m_iniCRC;
- Bool m_isQM;
-
- AsciiString m_ladderIP;
- AsciiString m_pingStr;
- Int m_pingInt;
- UnsignedShort m_ladderPort;
-
- Int m_reportedNumPlayers;
- Int m_reportedMaxPlayers;
- Int m_reportedNumObservers;
-
-public:
- GameSpyStagingRoom();
- virtual void reset( void );
-
- void cleanUpSlotPointers(void);
- inline void setID(Int id) { m_id = id; }
- inline Int getID( void ) const { return m_id; }
-
- inline void setHasPassword(Bool val) { m_requiresPassword = val; }
- inline Bool getHasPassword(void) const { return m_requiresPassword; }
- inline void setAllowObservers(Bool val) { m_allowObservers = val; }
- inline Bool getAllowObservers(void) const { return m_allowObservers; }
-
- inline void setVersion(UnsignedInt val) { m_version = val; }
- inline UnsignedInt getVersion(void) const { return m_version; }
- inline void setExeCRC(UnsignedInt val) { m_exeCRC = val; }
- inline UnsignedInt getExeCRC(void) const { return m_exeCRC; }
- inline void setIniCRC(UnsignedInt val) { m_iniCRC = val; }
- inline UnsignedInt getIniCRC(void) const { return m_iniCRC; }
-
- inline void setReportedNumPlayers(Int val) { m_reportedNumPlayers = val; }
- inline Int getReportedNumPlayers(void) const { return m_reportedNumPlayers; }
-
- inline void setReportedMaxPlayers(Int val) { m_reportedMaxPlayers = val; }
- inline Int getReportedMaxPlayers(void) const { return m_reportedMaxPlayers; }
-
- inline void setReportedNumObservers(Int val) { m_reportedNumObservers = val; }
- inline Int getReportedNumObservers(void) const { return m_reportedNumObservers; }
-
- inline void setLadderIP( AsciiString ladderIP ) { m_ladderIP = ladderIP; }
- inline AsciiString getLadderIP( void ) const { return m_ladderIP; }
- inline void setLadderPort( UnsignedShort ladderPort ) { m_ladderPort = ladderPort; }
- inline UnsignedShort getLadderPort( void ) const { return m_ladderPort; }
- void setPingString( AsciiString pingStr );
- inline AsciiString getPingString( void ) const { return m_pingStr; }
- inline Int getPingAsInt( void ) const { return m_pingInt; }
-
- virtual Bool amIHost( void ) const; ///< Convenience function - is the local player the game host?
-
- GameSpyGameSlot *getGameSpySlot( Int index );
-
- AsciiString generateGameSpyGameResultsPacket( void );
- AsciiString generateLadderGameResultsPacket( void );
- void markGameAsQM( void ) { m_isQM = TRUE; }
- Bool isQMGame( void ) { return m_isQM; }
-
- virtual void init(void);
- virtual void resetAccepted(void); ///< Reset the accepted flag on all players
-
- virtual void startGame(Int gameID); ///< Mark our game as started and record the game ID.
- void launchGame( void ); ///< NAT negotiation has finished - really start
- virtual Int getLocalSlotNum( void ) const; ///< Get the local slot number, or -1 if we're not present
-
- inline void setGameName( UnicodeString name ) { m_gameName = name; }
- inline UnicodeString getGameName( void ) const { return m_gameName; }
-
- inline void setLocalName( AsciiString name ) { m_localName = name; }
-};
-
-extern GameSpyStagingRoom *TheGameSpyGame;
-
-#endif // __STAGINGROOMGAMEINFO_H__
diff --git a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/ThreadUtils.h b/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/ThreadUtils.h
deleted file mode 100644
index be97c956eba..00000000000
--- a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/ThreadUtils.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: ThreadUtils.h //////////////////////////////////////////////////////
-// Generals GameSpy thread utils
-// Author: Matthew D. Campbell, July 2002
-
-#pragma once
-
-#ifndef __GAMESPY_THREADUTILS_H__
-#define __GAMESPY_THREADUTILS_H__
-
-std::wstring MultiByteToWideCharSingleLine( const char *orig );
-std::string WideCharStringToMultiByte( const WideChar *orig );
-
-#endif // __GAMESPY_THREADUTILS_H__
diff --git a/Generals/Code/GameEngine/Include/GameNetwork/GameSpyChat.h b/Generals/Code/GameEngine/Include/GameNetwork/GameSpyChat.h
deleted file mode 100644
index e68b6ad7be3..00000000000
--- a/Generals/Code/GameEngine/Include/GameNetwork/GameSpyChat.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: GameSpyChat.h //////////////////////////////////////////////////////
-// Generals GameSpy Chat
-// Author: Matthew D. Campbell, February 2002
-
-#pragma once
-
-#ifndef __GAMESPYCHAT_H__
-#define __GAMESPYCHAT_H__
-
-#include "GameSpy/Peer/Peer.h"
-
-class GameWindow;
-class WindowLayout;
-
-Bool GameSpySendChat(UnicodeString message, Bool isEmote, GameWindow *playerListbox = NULL);
-void GameSpyAddText( UnicodeString message, GameSpyColors color = GSCOLOR_DEFAULT );
-
-extern GameWindow *progressTextWindow; ///< Text box on the progress screen
-extern GameWindow *quickmatchTextWindow; ///< Text box on the quickmatch screen
-extern GameWindow *quickmatchTextWindow; ///< Text box on the quickmatch screen
-extern GameWindow *listboxLobbyChat; ///< Chat box on the custom lobby screen
-extern GameWindow *listboxLobbyPlayers; ///< Player box on the custom lobby screen
-extern GameWindow *listboxLobbyGames; ///< Game box on the custom lobby screen
-extern GameWindow *listboxLobbyChatChannels; ///< Chat channel box on the custom lobby screen
-extern GameWindow *listboxGameSetupChat; ///< Chat box on the custom game setup screen
-extern WindowLayout *WOLMapSelectLayout; ///< Map selection overlay
-
-void RoomMessageCallback(PEER peer, RoomType roomType,
- const char * nick, const char * message,
- MessageType messageType, void * param); ///< Called when a message arrives in a room.
-
-void PlayerMessageCallback(PEER peer, const char * nick,
- const char * message, MessageType messageType,
- void * param); ///< Called when a private message is received from another player.
-
-#endif // __GAMESPYCHAT_H__
diff --git a/Generals/Code/GameEngine/Include/GameNetwork/GameSpyGP.h b/Generals/Code/GameEngine/Include/GameNetwork/GameSpyGP.h
deleted file mode 100644
index d54c71a96fb..00000000000
--- a/Generals/Code/GameEngine/Include/GameNetwork/GameSpyGP.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: GameSpyGP.h //////////////////////////////////////////////////////
-// Generals GameSpy GP (Buddy)
-// Author: Matthew D. Campbell, March 2002
-
-#pragma once
-
-#ifndef __GAMESPYGP_H__
-#define __GAMESPYGP_H__
-
-#include "GameSpy/GP/GP.h"
-
-void GPRecvBuddyRequestCallback(GPConnection * connection, GPRecvBuddyRequestArg * arg, void * param);
-void GPRecvBuddyMessageCallback(GPConnection * pconnection, GPRecvBuddyMessageArg * arg, void * param);
-void GPRecvBuddyStatusCallback(GPConnection * connection, GPRecvBuddyStatusArg * arg, void * param);
-void GPErrorCallback(GPConnection * pconnection, GPErrorArg * arg, void * param);
-void GPConnectCallback(GPConnection * pconnection, GPConnectResponseArg * arg, void * param);
-void GameSpyUpdateBuddyOverlay(void);
-
-extern GPConnection *TheGPConnection;
-
-Bool IsGameSpyBuddy(GPProfile id);
-
-#endif // __GAMESPYGP_H__
diff --git a/Generals/Code/GameEngine/Include/GameNetwork/GameSpyGameInfo.h b/Generals/Code/GameEngine/Include/GameNetwork/GameSpyGameInfo.h
deleted file mode 100644
index 1673b8ba15a..00000000000
--- a/Generals/Code/GameEngine/Include/GameNetwork/GameSpyGameInfo.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: GameSpyGameInfo.h //////////////////////////////////////////////////////
-// Generals GameSpy game setup information
-// Author: Matthew D. Campbell, February 2002
-
-#pragma once
-
-#error this file is obsolete
-
-#ifndef __GAMESPYGAMEINFO_H__
-#define __GAMESPYGAMEINFO_H__
-
-#include "GameSpy/Peer/Peer.h"
-
-#include "GameNetwork/GameInfo.h"
-
-class Transport;
-class NAT;
-
-class GameSpyGameSlot : public GameSlot
-{
-public:
- GameSpyGameSlot();
- Int getProfileID( void ) { return m_profileID; }
- void setProfileID( Int id ) { m_profileID = id; }
- AsciiString getLoginName( void ) { return m_gameSpyLogin; }
- void setLoginName( AsciiString name ) { m_gameSpyLogin = name; }
- AsciiString getLocale( void ) { return m_gameSpyLocale; }
- void setLocale( AsciiString name ) { m_gameSpyLocale = name; }
-protected:
- Int m_profileID;
- AsciiString m_gameSpyLogin;
- AsciiString m_gameSpyLocale;
-};
-
-/**
- * GameSpyGameInfo class - maintains information about the GameSpy game and
- * the contents of its slot list throughout the game.
- */
-class GameSpyGameInfo : public GameInfo
-{
-private:
- GameSpyGameSlot m_GameSpySlot[MAX_SLOTS]; ///< The GameSpy Games Slot List
- SBServer m_server;
- Bool m_hasBeenQueried;
- Transport *m_transport;
- Bool m_isQM;
-
-public:
- GameSpyGameInfo();
-
- inline void setServer(SBServer server) { m_server = server; }
- inline SBServer getServer( void ) { return m_server; }
-
- AsciiString generateGameResultsPacket( void );
-
- virtual void init(void);
- virtual void resetAccepted(void); ///< Reset the accepted flag on all players
-
- void markGameAsQM( void ) { m_isQM = TRUE; }
- virtual void startGame(Int gameID); ///< Mark our game as started and record the game ID.
- virtual Int getLocalSlotNum( void ) const; ///< Get the local slot number, or -1 if we're not present
-
- void gotGOACall( void ); ///< Mark the game info as having been queried
-};
-
-extern GameSpyGameInfo *TheGameSpyGame;
-
-void WOLDisplayGameOptions( void );
-void WOLDisplaySlotList( void );
-void GameSpyStartGame( void );
-void GameSpyLaunchGame( void );
-Bool GetLocalChatConnectionAddress(AsciiString serverName, UnsignedShort serverPort, UnsignedInt& localIP);
-
-#endif // __LANGAMEINFO_H__
diff --git a/Generals/Code/GameEngine/Include/GameNetwork/GameSpyOverlay.h b/Generals/Code/GameEngine/Include/GameNetwork/GameSpyOverlay.h
deleted file mode 100644
index f2890111495..00000000000
--- a/Generals/Code/GameEngine/Include/GameNetwork/GameSpyOverlay.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: GamespyOverlay.h //////////////////////////////////////////////////////
-// Generals GameSpy overlay screens
-// Author: Matthew D. Campbell, March 2002
-
-#pragma once
-
-#ifndef __GAMESPYOVERLAY_H__
-#define __GAMESPYOVERLAY_H__
-
-#include "Common/NameKeyGenerator.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/Shell.h"
-#include "GameClient/KeyDefs.h"
-#include "GameClient/GameWindowManager.h"
-
-void ClearGSMessageBoxes( void ); ///< Tear down any GS message boxes (e.g. in case we have a new one to put up)
-void GSMessageBoxOk(UnicodeString titleString,UnicodeString bodyString, GameWinMsgBoxFunc okFunc = NULL); ///< Display a Message box with Ok button and track it
-void GSMessageBoxOkCancel(UnicodeString title, UnicodeString message, GameWinMsgBoxFunc okFunc, GameWinMsgBoxFunc cancelFunc); ///< Display a Message box with Ok/Cancel buttons and track it
-void GSMessageBoxYesNo(UnicodeString title, UnicodeString message, GameWinMsgBoxFunc yesFunc, GameWinMsgBoxFunc noFunc); ///< Display a Message box with Yes/No buttons and track it
-void RaiseGSMessageBox( void ); ///< Bring GS message box to the foreground (if we transition screens while a message box is up)
-
-enum GSOverlayType
-{
- GSOVERLAY_PLAYERINFO,
- GSOVERLAY_MAPSELECT,
- GSOVERLAY_BUDDY,
- GSOVERLAY_PAGE,
- GSOVERLAY_GAMEOPTIONS,
- GSOVERLAY_GAMEPASSWORD,
- GSOVERLAY_LADDERSELECT,
- GSOVERLAY_LOCALESELECT,
- GSOVERLAY_OPTIONS,
- GSOVERLAY_MAX
-};
-
-void GameSpyOpenOverlay( GSOverlayType );
-void GameSpyCloseOverlay( GSOverlayType );
-void GameSpyCloseAllOverlays( void );
-Bool GameSpyIsOverlayOpen( GSOverlayType );
-void GameSpyToggleOverlay( GSOverlayType );
-void GameSpyUpdateOverlays( void );
-void ReOpenPlayerInfo( void );
-void CheckReOpenPlayerInfo(void );
-#endif // __GAMESPYOVERLAY_H__
diff --git a/Generals/Code/GameEngine/Include/GameNetwork/GameSpyPersistentStorage.h b/Generals/Code/GameEngine/Include/GameNetwork/GameSpyPersistentStorage.h
deleted file mode 100644
index d16363b63ec..00000000000
--- a/Generals/Code/GameEngine/Include/GameNetwork/GameSpyPersistentStorage.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: GameSpyPersistentStorage.h //////////////////////////////////////////////////////
-// Generals GameSpy Persistent Storage
-// Author: Matthew D. Campbell, March 2002
-
-#pragma once
-
-#ifndef __GAMESPYPersistentStorage_H__
-#define __GAMESPYPersistentStorage_H__
-
-class GameSpyPlayerInfoInterface : public SubsystemInterface
-{
-public:
- virtual ~GameSpyPlayerInfoInterface() { };
-
- virtual void init( void ) = 0;
- virtual void reset( void ) = 0;
- virtual void update( void ) = 0;
-
- virtual void setLocale( AsciiString locale, Bool setOnServer = true ) = 0;
- virtual AsciiString getLocale( void ) = 0;
- virtual void setWins( Int wins, Bool setOnServer = true ) = 0;
- virtual Int getWins( void ) = 0;
- virtual void setLosses( Int losses, Bool setOnServer = true ) = 0;
- virtual Int getLosses( void ) = 0;
-
- virtual void readFromServer( void ) = 0;
-
- virtual void threadReadFromServer( void ) = 0;
- virtual void threadSetLocale( AsciiString val ) = 0;
- virtual void threadSetWins ( AsciiString val ) = 0;
- virtual void threadSetLosses( AsciiString val ) = 0;
-};
-
-GameSpyPlayerInfoInterface *createGameSpyPlayerInfo( void );
-
-extern GameSpyPlayerInfoInterface *TheGameSpyPlayerInfo;
-
-#endif // __GAMESPYPersistentStorage_H__
diff --git a/Generals/Code/GameEngine/Include/GameNetwork/GameSpyThread.h b/Generals/Code/GameEngine/Include/GameNetwork/GameSpyThread.h
deleted file mode 100644
index 2a06a2ddeb5..00000000000
--- a/Generals/Code/GameEngine/Include/GameNetwork/GameSpyThread.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: GameSpyThread.h //////////////////////////////////////////////////////
-// Generals GameSpy thread class
-// Author: Matthew D. Campbell, March 2002
-
-#pragma once
-
-#ifndef __GAMESPYTHREAD_H__
-#define __GAMESPYTHREAD_H__
-
-#include "mutex.h"
-#include "thread.h"
-
-class GameSpyThreadClass : public ThreadClass
-{
-
-public:
- GameSpyThreadClass::GameSpyThreadClass() : ThreadClass() { m_doLogin = false; m_readStats = false; m_updateWins = false; m_updateLosses = false; m_updateLocale = false; m_showLocaleSelect = false; m_nextShellScreen.clear(); }
- void queueLogin(AsciiString nick, AsciiString pass, AsciiString email) { m_nick = nick; m_pass = pass; m_email = email; m_doLogin = true; }
- void queueReadPersistentStatsFromServer( void ) { m_readStats = true; }
- void queueUpdateLocale( AsciiString locale ) { m_locale = locale; m_updateLocale = true; }
- void queueUpdateWins ( AsciiString wins ) { m_wins = wins; m_updateWins = true; }
- void queueUpdateLosses( AsciiString losses ) { m_losses = losses; m_updateLosses = true; }
-
- void Thread_Function();
-
- AsciiString getNextShellScreen( void );
- Bool showLocaleSelect( void );
-
- void setNextShellScreen( AsciiString nextShellScreen );
- void setShowLocaleSelect( Bool val );
-
-private:
- AsciiString m_nick, m_pass, m_email;
- Bool m_doLogin, m_readStats, m_updateWins, m_updateLosses, m_updateLocale;
- AsciiString m_locale, m_wins, m_losses;
- AsciiString m_nextShellScreen;
- Bool m_showLocaleSelect;
-};
-
-extern GameSpyThreadClass *TheGameSpyThread;
-extern MutexClass TheGameSpyMutex;
-
-#endif // __GAMESPYTHREAD_H__
diff --git a/Generals/Code/GameEngine/Include/GameNetwork/NAT.h b/Generals/Code/GameEngine/Include/GameNetwork/NAT.h
deleted file mode 100644
index 802c3d68623..00000000000
--- a/Generals/Code/GameEngine/Include/GameNetwork/NAT.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: NAT.h /////////////////////////////////////////////////////////////////////////////////
-// Author: Bryan Cleveland April 2002
-// Desc: Resolves NAT'd IPs and port numbers for the other players in a game.
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-#pragma once
-
-#ifndef __NAT_H
-#define __NAT_H
-
-#include "Lib\BaseType.h"
-#include "GameNetwork/NetworkInterface.h"
-#include "GameNetwork/FirewallHelper.h"
-
-class Transport;
-class GameSlot;
-
-enum NATStateType {
- NATSTATE_IDLE,
- NATSTATE_DOCONNECTIONPATHS,
- NATSTATE_WAITFORSTATS,
- NATSTATE_DONE,
- NATSTATE_FAILED
-};
-
-enum NATConnectionState {
- NATCONNECTIONSTATE_NOSTATE,
- NATCONNECTIONSTATE_WAITINGTOBEGIN,
-// NATCONNECTIONSTATE_NETGEARDELAY,
- NATCONNECTIONSTATE_WAITINGFORMANGLERRESPONSE,
- NATCONNECTIONSTATE_WAITINGFORMANGLEDPORT,
- NATCONNECTIONSTATE_WAITINGFORRESPONSE,
- NATCONNECTIONSTATE_DONE,
- NATCONNECTIONSTATE_FAILED
-};
-
-struct ConnectionNodeType {
- FirewallHelperClass::tFirewallBehaviorType m_behavior; ///< the NAT/Firewall behavior of this node.
- UnsignedInt m_slotIndex; ///< the player list index of this node.
-};
-
-class NAT {
-public:
- NAT();
- virtual ~NAT();
-
- NATStateType update();
-
- void attachSlotList(GameSlot **slotList, Int localSlot, UnsignedInt localIP);
- void establishConnectionPaths();
-
- Int getSlotPort(Int slot);
- Transport * getTransport(); ///< return the newly created Transport layer that has all the connections and whatnot.
-
- // Notification messages from GameSpy
- void processGlobalMessage(Int slotNum, const char *options);
-
-protected:
- NATConnectionState connectionUpdate(); ///< the update function for the connections.
- void sendMangledSourcePort(); ///< starts the process to get the next mangled source port.
- void processManglerResponse(UnsignedShort mangledPort);
-
- Bool allConnectionsDoneThisRound();
- Bool allConnectionsDone();
-
- void generatePortNumbers(GameSlot **slotList, Int localSlot); ///< generate all of the slots' port numbers to be used.
-
- void doThisConnectionRound(); ///< compute who will connect with who for this round.
- void setConnectionState(Int nodeNumber, NATConnectionState state); ///< central point for changing a connection's state.
- void sendAProbe(UnsignedInt ip, UnsignedShort port, Int fromNode); ///< send a "PROBE" packet to this IP and port.
- void notifyTargetOfProbe(GameSlot *targetSlot);
- void notifyUsersOfConnectionDone(Int nodeIndex);
- void notifyUsersOfConnectionFailed(Int nodeIndex);
- void sendMangledPortNumberToTarget(UnsignedShort mangledPort, GameSlot *targetSlot);
-
- void probed(Int nodeNumber);
- void gotMangledPort(Int nodeNumber, UnsignedShort mangledPort);
- void gotInternalAddress(Int nodeNumber, UnsignedInt address);
- void connectionComplete(Int slotIndex);
- void connectionFailed(Int slotIndex);
-
- Transport *m_transport;
- GameSlot **m_slotList;
- NATStateType m_NATState;
- Int m_localNodeNumber; ///< The node number of the local player.
- Int m_targetNodeNumber; ///< The node number of the player we are connecting to this round.
- UnsignedInt m_localIP; ///< The IP of the local computer.
- UnsignedInt m_numNodes; ///< The number of players we have to connect together.
- UnsignedInt m_connectionRound; ///< The "round" of connections we are currently on.
-
- Int m_numRetries;
- Int m_maxNumRetriesAllowed;
-
- UnsignedShort m_packetID;
- UnsignedShort m_spareSocketPort;
- time_t m_manglerRetryTime;
- Int m_manglerRetries;
- UnsignedShort m_previousSourcePort;
-
- Bool m_beenProbed; ///< have I been notified that I've been probed this round?
-
- UnsignedInt m_manglerAddress;
-
- time_t m_timeTillNextSend; ///< The number of milliseconds till we send to the other guy's port again.
- NATConnectionState m_connectionStates[MAX_SLOTS]; ///< connection states for this round for all the nodes.
-
- ConnectionNodeType m_connectionNodes[MAX_SLOTS]; ///< info regarding the nodes that are being connected.
-
- UnsignedShort m_sourcePorts[MAX_SLOTS]; ///< the source ports that the other players communicate to us on.
-
- Bool m_myConnections[MAX_SLOTS]; ///< keeps track of all the nodes I've connected to. For keepalive.
- time_t m_nextKeepaliveTime; ///< the next time we will send out our keepalive packets.
-
- static Int m_connectionPairs[MAX_SLOTS-1][MAX_SLOTS-1][MAX_SLOTS];
- Int m_connectionPairIndex;
-
- UnsignedShort m_startingPortNumber; ///< the starting port number for this game. The slots all get port numbers with their port numbers based on this number.
- ///< this is done so that games that are played right after each other with the same players in the same
- ///< slot order will not use the old source port allocation scheme in case their NAT
- ///< hasn't timed out that connection.
-
- time_t m_nextPortSendTime; ///< Last time we sent our mangled port number to our target this round.
-
- time_t m_timeoutTime; ///< the time at which we will time out waiting for the other player's port number.
- time_t m_roundTimeout; ///< the time at which we will time out this connection round.
-
- static Int m_timeBetweenRetries; // 1 second between retries sounds good to me.
- static time_t m_manglerRetryTimeInterval; // sounds good to me.
- static Int m_maxAllowedManglerRetries; // works for me.
- static time_t m_keepaliveInterval; // 15 seconds between keepalive packets seems good.
- static time_t m_timeToWaitForPort; // wait for ten seconds for the other player's port number.
- static time_t m_timeForRoundTimeout; // wait for at most ten seconds for each connection round to finish.
-
-};
-
-extern NAT *TheNAT;
-
-#endif // #ifndef __NAT_H
\ No newline at end of file
diff --git a/Generals/Code/GameEngine/Source/Common/GameEngine.cpp b/Generals/Code/GameEngine/Source/Common/GameEngine.cpp
index e90e63ea727..88634fe34b9 100644
--- a/Generals/Code/GameEngine/Source/Common/GameEngine.cpp
+++ b/Generals/Code/GameEngine/Source/Common/GameEngine.cpp
@@ -101,9 +101,6 @@
#include "GameNetwork/NetworkInterface.h"
#include "GameNetwork/LANAPI.h"
-#include "GameNetwork/GameSpy/GameResultsThread.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpy/PersistentStorageThread.h"
#include "Common/Player.h"
@@ -744,113 +741,6 @@ logging code that is usually called from another thread. I'm doing it here
because there's no way to guarantee the other thread will execute before we
exit the app.
*/
-void GameEngine::checkAbnormalQuitting(void)
-{
- if (TheRecorder->isMultiplayer() && TheGameLogic->isInInternetGame())
- { //Should not be quitting at this time, record it as a cheat.
-
- Int localID = TheGameSpyInfo->getLocalProfileID();
- PSPlayerStats stats = TheGameSpyPSMessageQueue->findPlayerStatsByID(localID);
-
- Player *player=ThePlayerList->getLocalPlayer();
-
- Int ptIdx;
- const PlayerTemplate *myTemplate = player->getPlayerTemplate();
- DEBUG_LOG(("myTemplate = %X(%s)\n", myTemplate, myTemplate->getName().str()));
- for (ptIdx = 0; ptIdx < ThePlayerTemplateStore->getPlayerTemplateCount(); ++ptIdx)
- {
- const PlayerTemplate *nthTemplate = ThePlayerTemplateStore->getNthPlayerTemplate(ptIdx);
- DEBUG_LOG(("nthTemplate = %X(%s)\n", nthTemplate, nthTemplate->getName().str()));
- if (nthTemplate == myTemplate)
- {
- break;
- }
- }
-
- PSRequest req;
-
- req.requestType = PSRequest::PSREQUEST_UPDATEPLAYERSTATS;
- req.email = TheGameSpyInfo->getLocalEmail().str();
- req.nick = TheGameSpyInfo->getLocalBaseName().str();
- req.password = TheGameSpyInfo->getLocalPassword().str();
- req.player = stats;
- req.addDesync = FALSE;
- req.addDiscon = TRUE;
- req.lastHouse = ptIdx;
-
- UserPreferences pref;
- AsciiString userPrefFilename;
- userPrefFilename.format("GeneralsOnline\\MiscPref%d.ini", stats.id);
- DEBUG_LOG(("using the file %s\n", userPrefFilename.str()));
- pref.load(userPrefFilename);
-
- Int addedInDesyncs2 = pref.getInt("0", 0);
- DEBUG_LOG(("addedInDesyncs2 = %d\n", addedInDesyncs2));
- if (addedInDesyncs2 < 0)
- addedInDesyncs2 = 10;
- Int addedInDesyncs3 = pref.getInt("1", 0);
- DEBUG_LOG(("addedInDesyncs3 = %d\n", addedInDesyncs3));
- if (addedInDesyncs3 < 0)
- addedInDesyncs3 = 10;
- Int addedInDesyncs4 = pref.getInt("2", 0);
- DEBUG_LOG(("addedInDesyncs4 = %d\n", addedInDesyncs4));
- if (addedInDesyncs4 < 0)
- addedInDesyncs4 = 10;
- Int addedInDiscons2 = pref.getInt("3", 0);
- DEBUG_LOG(("addedInDiscons2 = %d\n", addedInDiscons2));
- if (addedInDiscons2 < 0)
- addedInDiscons2 = 10;
- Int addedInDiscons3 = pref.getInt("4", 0);
- DEBUG_LOG(("addedInDiscons3 = %d\n", addedInDiscons3));
- if (addedInDiscons3 < 0)
- addedInDiscons3 = 10;
- Int addedInDiscons4 = pref.getInt("5", 0);
- DEBUG_LOG(("addedInDiscons4 = %d\n", addedInDiscons4));
- if (addedInDiscons4 < 0)
- addedInDiscons4 = 10;
-
- DEBUG_LOG(("req.addDesync=%d, req.addDiscon=%d, addedInDesync=%d,%d,%d, addedInDiscon=%d,%d,%d\n",
- req.addDesync, req.addDiscon, addedInDesyncs2, addedInDesyncs3, addedInDesyncs4,
- addedInDiscons2, addedInDiscons3, addedInDiscons4));
-
- if (req.addDesync || req.addDiscon)
- {
- AsciiString val;
- if (req.lastHouse == 2)
- {
- val.format("%d", addedInDesyncs2 + req.addDesync);
- pref["0"] = val;
- val.format("%d", addedInDiscons2 + req.addDiscon);
- pref["3"] = val;
- DEBUG_LOG(("house 2 req.addDesync || req.addDiscon: %d %d\n",
- addedInDesyncs2 + req.addDesync, addedInDiscons2 + req.addDiscon));
- }
- else if (req.lastHouse == 3)
- {
- val.format("%d", addedInDesyncs3 + req.addDesync);
- pref["1"] = val;
- val.format("%d", addedInDiscons3 + req.addDiscon);
- pref["4"] = val;
- DEBUG_LOG(("house 3 req.addDesync || req.addDiscon: %d %d\n",
- addedInDesyncs3 + req.addDesync, addedInDiscons3 + req.addDiscon));
- }
- else
- {
- val.format("%d", addedInDesyncs4 + req.addDesync);
- pref["2"] = val;
- val.format("%d", addedInDiscons4 + req.addDiscon);
- pref["5"] = val;
- DEBUG_LOG(("house 4 req.addDesync || req.addDiscon: %d %d\n",
- addedInDesyncs4 + req.addDesync, addedInDiscons4 + req.addDiscon));
- }
- pref.write();
- }
- }
-}
-
-//-------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------
#define CONVERT_EXEC1 "..\\Build\\nvdxt -list buildDDS.txt -dxt5 -full -outdir Art\\Textures > buildDDS.out"
void updateTGAtoDDS()
diff --git a/Generals/Code/GameEngine/Source/Common/Recorder.cpp b/Generals/Code/GameEngine/Source/Common/Recorder.cpp
index 4ca4750ace0..4805328b9da 100644
--- a/Generals/Code/GameEngine/Source/Common/Recorder.cpp
+++ b/Generals/Code/GameEngine/Source/Common/Recorder.cpp
@@ -38,7 +38,6 @@
#include "GameNetwork/LANAPICallbacks.h"
#include "GameNetwork/GameMessageParser.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
#include "GameNetwork/NetworkUtil.h"
#include "GameLogic/GameLogic.h"
#include "Common/RandomValue.h"
diff --git a/Generals/Code/GameEngine/Source/Common/UserPreferences.cpp b/Generals/Code/GameEngine/Source/Common/UserPreferences.cpp
index c2702fc144e..6075f652534 100644
--- a/Generals/Code/GameEngine/Source/Common/UserPreferences.cpp
+++ b/Generals/Code/GameEngine/Source/Common/UserPreferences.cpp
@@ -48,7 +48,6 @@
#include "Common/QuotedPrintable.h"
#include "Common/MultiplayerSettings.h"
#include "GameClient/MapUtil.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
#ifdef _INTERNAL
// for occasional debugging...
diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/DownloadMenu.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/DownloadMenu.cpp
deleted file mode 100644
index 3a77f3b253c..00000000000
--- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/DownloadMenu.cpp
+++ /dev/null
@@ -1,436 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: DownloadMenu.cpp /////////////////////////////////////////////////////////
-//-----------------------------------------------------------------------------
-//
-// Electronic Arts Pacific.
-//
-// Confidential Information
-// Copyright (C) 2002 - All Rights Reserved
-//
-//-----------------------------------------------------------------------------
-//
-// Project: RTS3
-//
-// File name: DownloadMenu.cpp
-//
-// Created: Matthew D. Campbell, July 2002
-//
-// Desc: the Patch Download window control
-//
-//-----------------------------------------------------------------------------
-///////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/GameEngine.h"
-#include "Common/NameKeyGenerator.h"
-#include "GameClient/GUICallbacks.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/GadgetStaticText.h"
-#include "GameClient/GadgetProgressBar.h"
-#include "GameClient/GameText.h"
-#include "GameClient/MessageBox.h"
-
-#include "GameLogic/GameLogic.h"
-
-#include "GameNetwork/DownloadManager.h"
-#include "GameNetwork/GameSpy/MainMenuUtils.h"
-
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-static NameKeyType buttonCancelID = NAMEKEY_INVALID;
-static NameKeyType staticTextSizeID = NAMEKEY_INVALID;
-static NameKeyType staticTextTimeID = NAMEKEY_INVALID;
-static NameKeyType staticTextFileID = NAMEKEY_INVALID;
-static NameKeyType staticTextStatusID = NAMEKEY_INVALID;
-static NameKeyType progressBarMunkeeID = NAMEKEY_INVALID;
-
-static GameWindow * staticTextSize = NULL;
-static GameWindow * staticTextTime = NULL;
-static GameWindow * staticTextFile = NULL;
-static GameWindow * staticTextStatus = NULL;
-static GameWindow * progressBarMunkee = NULL;
-
-static GameWindow *parent = NULL;
-
-static void closeDownloadWindow( void )
-{
- DEBUG_ASSERTCRASH(parent, ("No Parent"));
- if (!parent)
- return;
-
- WindowLayout *menuLayout = parent->winGetLayout();
- menuLayout->runShutdown();
- menuLayout->destroyWindows();
- menuLayout->deleteInstance();
- menuLayout = NULL;
-
- GameWindow *mainWin = TheWindowManager->winGetWindowFromId( NULL, NAMEKEY("MainMenu.wnd:MainMenuParent") );
- if (mainWin)
- TheWindowManager->winSetFocus( mainWin );
-}
-
-static void errorCallback( void )
-{
- HandleCanceledDownload();
- closeDownloadWindow();
-}
-
-static void successQuitCallback( void )
-{
- TheGameEngine->setQuitting( TRUE );
- closeDownloadWindow();
-
- // Clean up game data. No crashy-crash for you!
- if (TheGameLogic->isInGame())
- TheMessageStream->appendMessage( GameMessage::MSG_CLEAR_GAME_DATA );
-}
-
-static void successNoQuitCallback( void )
-{
- HandleCanceledDownload();
- closeDownloadWindow();
-}
-
-class DownloadManagerMunkee : public DownloadManager
-{
-public:
- DownloadManagerMunkee() {m_shouldQuitOnSuccess = true; m_shouldQuitOnSuccess = false;}
- virtual HRESULT OnError( Int error );
- virtual HRESULT OnEnd();
- virtual HRESULT OnProgressUpdate( Int bytesread, Int totalsize, Int timetaken, Int timeleft );
- virtual HRESULT OnStatusUpdate( Int status );
- virtual HRESULT downloadFile( AsciiString server, AsciiString username, AsciiString password, AsciiString file, AsciiString localfile, AsciiString regkey, Bool tryResume );
-
-private:
- Bool m_shouldQuitOnSuccess;
-};
-
-HRESULT DownloadManagerMunkee::downloadFile( AsciiString server, AsciiString username, AsciiString password, AsciiString file, AsciiString localfile, AsciiString regkey, Bool tryResume )
-{
- // see if we'll need to restart
- if (strstr(localfile.str(), "patches\\") != NULL)
- {
- m_shouldQuitOnSuccess = true;
- }
-
- if (staticTextFile)
- {
- AsciiString bob = file;
-
- // just get the filename, not the pathname
- const char *tmp = bob.reverseFind('/');
- if (tmp)
- bob = tmp+1;
- tmp = bob.reverseFind('\\');
- if (tmp)
- bob = tmp+1;
-
- UnicodeString fileString;
- fileString.translate(bob);
- GadgetStaticTextSetText(staticTextFile, fileString);
- }
-
- password.format("-%s", password.str());
- return DownloadManager::downloadFile( server, username, password, file, localfile, regkey, tryResume );
-}
-HRESULT DownloadManagerMunkee::OnError( Int error )
-{
- HRESULT ret = DownloadManager::OnError( error );
-
- MessageBoxOk(TheGameText->fetch("GUI:DownloadErrorTitle"), getErrorString(), errorCallback);
- return ret;
-}
-HRESULT DownloadManagerMunkee::OnEnd()
-{
- HRESULT ret = DownloadManager::OnEnd();
-
- if (isFileQueuedForDownload())
- {
- return downloadNextQueuedFile();
- }
- if (m_shouldQuitOnSuccess)
- MessageBoxOk(TheGameText->fetch("GUI:DownloadSuccessTitle"), TheGameText->fetch("GUI:DownloadSuccessMustQuit"), successQuitCallback);
- else
- MessageBoxOk(TheGameText->fetch("GUI:DownloadSuccessTitle"), TheGameText->fetch("GUI:DownloadSuccess"), successNoQuitCallback);
- return ret;
-}
-
-static time_t lastUpdate = 0;
-static Int timeLeft = 0;
-HRESULT DownloadManagerMunkee::OnProgressUpdate( Int bytesread, Int totalsize, Int timetaken, Int timeleft )
-{
- HRESULT ret = DownloadManager::OnProgressUpdate( bytesread, totalsize, timetaken, timeleft );
-
- if (progressBarMunkee)
- {
- Int percent = bytesread * 100 / totalsize;
- GadgetProgressBarSetProgress( progressBarMunkee, percent );
- }
-
- if (staticTextSize)
- {
- UnicodeString sizeString;
- sizeString.format(TheGameText->fetch("GUI:DownloadBytesRatio"), bytesread, totalsize);
- GadgetStaticTextSetText(staticTextSize, sizeString);
- }
- timeLeft = timeleft;
- if (staticTextTime && GadgetStaticTextGetText(staticTextTime).isEmpty()) // only update immediately the first time
- {
- lastUpdate = time(NULL);
- UnicodeString timeString;
- if (timeleft)
- {
- DEBUG_ASSERTCRASH(timeleft > 0, ("Time left is negative!"));
- timeleft = max(1, timeleft);
- Int takenHour, takenMin, takenSec;
- takenHour = timeleft / 60 / 60;
- takenMin = timeleft / 60;
- takenSec = timeleft % 60;
- timeString.format(TheGameText->fetch("GUI:DownloadTimeLeft"), takenHour, takenMin, takenSec);
- }
- else
- {
- timeString = TheGameText->fetch("GUI:DownloadUnknownTime");
- }
- GadgetStaticTextSetText(staticTextTime, timeString);
- }
- return ret;
-}
-
-HRESULT DownloadManagerMunkee::OnStatusUpdate( Int status )
-{
- HRESULT ret = DownloadManager::OnStatusUpdate( status );
-
- if (staticTextStatus)
- {
- GadgetStaticTextSetText(staticTextStatus, getStatusString());
- }
- return ret;
-}
-
-// PUBLIC FUNCTIONS ///////////////////////////////////////////////////////////////////////////////
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the menu */
-//-------------------------------------------------------------------------------------------------
-void DownloadMenuInit( WindowLayout *layout, void *userData )
-{
-
- //set keyboard focus to main parent and set modal
- NameKeyType parentID = TheNameKeyGenerator->nameToKey("DownloadMenu.wnd:ParentDownload");
- parent = TheWindowManager->winGetWindowFromId( NULL, parentID );
-
- // get ids for our children controls
- buttonCancelID = TheNameKeyGenerator->nameToKey( "DownloadMenu.wnd:ButtonCancel" );
- staticTextSizeID = TheNameKeyGenerator->nameToKey( "DownloadMenu.wnd:StaticTextSize" );
- staticTextTimeID = TheNameKeyGenerator->nameToKey( "DownloadMenu.wnd:StaticTextTime" );
- staticTextFileID = TheNameKeyGenerator->nameToKey( "DownloadMenu.wnd:StaticTextFile" );
- staticTextStatusID = TheNameKeyGenerator->nameToKey( "DownloadMenu.wnd:StaticTextStatus" );
- progressBarMunkeeID = TheNameKeyGenerator->nameToKey( "DownloadMenu.wnd:ProgressBarMunkee" );
-
- staticTextSize = TheWindowManager->winGetWindowFromId( parent, staticTextSizeID );
- staticTextTime = TheWindowManager->winGetWindowFromId( parent, staticTextTimeID );
- staticTextFile = TheWindowManager->winGetWindowFromId( parent, staticTextFileID );
- staticTextStatus = TheWindowManager->winGetWindowFromId( parent, staticTextStatusID );
- progressBarMunkee = TheWindowManager->winGetWindowFromId( parent, progressBarMunkeeID );
-
- DEBUG_ASSERTCRASH(!TheDownloadManager, ("Download manager already exists"));
- if (TheDownloadManager)
- {
- delete TheDownloadManager;
- }
- TheDownloadManager = NEW DownloadManagerMunkee;
-
-} // end DownloadMenuInit
-
-//-------------------------------------------------------------------------------------------------
-/** menu shutdown method */
-//-------------------------------------------------------------------------------------------------
-void DownloadMenuShutdown( WindowLayout *layout, void *userData )
-{
- DEBUG_ASSERTCRASH(TheDownloadManager, ("No download manager"));
- if (TheDownloadManager)
- {
- delete TheDownloadManager;
- TheDownloadManager = NULL;
- }
-
- staticTextSize = NULL;
- staticTextTime = NULL;
- staticTextFile = NULL;
- staticTextStatus = NULL;
- progressBarMunkee = NULL;
- parent = NULL;
-
-} // end DownloadMenuShutdown
-
-//-------------------------------------------------------------------------------------------------
-/** menu update method */
-//-------------------------------------------------------------------------------------------------
-void DownloadMenuUpdate( WindowLayout *layout, void *userData )
-{
- if (staticTextTime && !GadgetStaticTextGetText(staticTextTime).isEmpty())
- {
- time_t now = time(NULL);
- if (now <= lastUpdate)
- return;
-
- lastUpdate = now;
-
- UnicodeString timeString;
- if (timeLeft)
- {
- DEBUG_ASSERTCRASH(timeLeft > 0, ("Time left is negative!"));
- timeLeft = max(1, timeLeft);
- Int takenHour, takenMin, takenSec;
- takenHour = timeLeft / 60 / 60;
- takenMin = timeLeft / 60;
- takenSec = timeLeft % 60;
- timeString.format(TheGameText->fetch("GUI:DownloadTimeLeft"), takenHour, takenMin, takenSec);
- }
- else
- {
- timeString = TheGameText->fetch("GUI:DownloadUnknownTime");
- }
- GadgetStaticTextSetText(staticTextTime, timeString);
- }
-
-} // end DownloadMenuUpdate
-
-//-------------------------------------------------------------------------------------------------
-/** menu input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType DownloadMenuInput( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
-
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
- UnsignedByte key = mData1;
- UnsignedByte state = mData2;
-
- switch( key )
- {
-
- // ----------------------------------------------------------------------------------------
- case KEY_ESC:
- {
-
- //
- // send a simulated selected event to the parent window of the
- // back/exit button
- //
- if( BitTest( state, KEY_STATE_UP ) )
- {
- AsciiString buttonName( "DownloadMenu.wnd:ButtonCancel" );
- NameKeyType buttonID = TheNameKeyGenerator->nameToKey( buttonName );
- GameWindow *button = TheWindowManager->winGetWindowFromId( window, buttonID );
-
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)button, buttonID );
-
- } // end if
-
- // don't let key fall through anywhere else
- return MSG_HANDLED;
-
- } // end escape
-
- } // end switch( key )
-
- } // end char
-
- } // end switch( msg )
-
- return MSG_IGNORED;
-
-} // end DownloadMenuInput
-
-//-------------------------------------------------------------------------------------------------
-/** menu window system callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType DownloadMenuSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
-
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CREATE:
- {
-
- break;
-
- } // end create
- //---------------------------------------------------------------------------------------------
- case GWM_DESTROY:
- {
-
- break;
-
- } // end case
-
- //----------------------------------------------------------------------------------------------
- case GWM_INPUT_FOCUS:
- {
-
- // if we're givin the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
-
- break;
-
- } // end input
- //---------------------------------------------------------------------------------------------
- case GBM_SELECTED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if( controlID == buttonCancelID )
- {
- HandleCanceledDownload();
- closeDownloadWindow();
- } // end if
-
- break;
-
- } // end selected
-
- default:
- return MSG_IGNORED;
-
- } // end switch
-
- return MSG_HANDLED;
-
-} // end DownloadMenuSystem
\ No newline at end of file
diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/MainMenu.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/MainMenu.cpp
index f188e0d4e11..072c197cf3d 100644
--- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/MainMenu.cpp
+++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/MainMenu.cpp
@@ -30,8 +30,6 @@
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-#include "GameSpy/ghttp/ghttp.h"
-
#include "Lib/BaseType.h"
#include "Common/GameEngine.h"
#include "Common/GameState.h"
@@ -60,15 +58,10 @@
#include "GameClient/HotKey.h"
#include "GameLogic/GameLogic.h"
#include "GameLogic/ScriptEngine.h"
-#include "GameNetwork/GameSpyOverlay.h"
#include "GameClient/GameWindowTransitions.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpy/PeerThread.h"
-#include "GameNetwork/GameSpy/BuddyThread.h"
#include "GameNetwork/DownloadManager.h"
-#include "GameNetwork/GameSpy/MainMenuUtils.h"
//Added By Saad
//for accessing the InGameUI
@@ -452,7 +445,9 @@ void MainMenuInit( WindowLayout *layout, void *userData )
buttonSinglePlayer = TheWindowManager->winGetWindowFromId( parentMainMenu, buttonSinglePlayerID );
buttonMultiPlayer = TheWindowManager->winGetWindowFromId( parentMainMenu, buttonMultiPlayerID );
buttonSkirmish = TheWindowManager->winGetWindowFromId( parentMainMenu, skirmishID );
- buttonOnline = TheWindowManager->winGetWindowFromId( parentMainMenu, onlineID );
+ buttonOnline = TheWindowManager->winGetWindowFromId( parentMainMenu, onlineID );
+ if (buttonOnline)
+ buttonOnline->winHide(TRUE);
buttonNetwork = TheWindowManager->winGetWindowFromId( parentMainMenu, networkID );
buttonOptions = TheWindowManager->winGetWindowFromId( parentMainMenu, optionsID );
buttonExit = TheWindowManager->winGetWindowFromId( parentMainMenu, exitID );
@@ -565,12 +560,6 @@ void MainMenuInit( WindowLayout *layout, void *userData )
//getUpdate->winEnable( FALSE );
}
/**/
-
- if (TheGameSpyPeerMessageQueue && !TheGameSpyPeerMessageQueue->isConnected())
- {
- DEBUG_LOG(("Tearing down GameSpy from MainMenuInit()\n"));
- TearDownGameSpy();
- }
if (TheMapCache)
TheMapCache->updateCache();
@@ -891,7 +880,6 @@ void MainMenuUpdate( WindowLayout *layout, void *userData )
}
HTTPThinkWrapper();
- GameSpyUpdateOverlays();
// if(localAnimateWindowManager)
// localAnimateWindowManager->update();
// if(localAnimateWindowManager && pendingDropDown != DROPDOWN_NONE && localAnimateWindowManager->isFinished())
@@ -1021,15 +1009,12 @@ WindowMsgHandledType MainMenuSystem( GameWindow *window, UnsignedInt msg,
} // end case
//---------------------------------------------------------------------------------------------
- case GWM_DESTROY:
- {
- ghttpCleanup();
- DEBUG_LOG(("Tearing down GameSpy from MainMenuSystem(GWM_DESTROY)\n"));
- TearDownGameSpy();
- StopAsyncDNSCheck(); // kill off the async DNS check thread in case it is still running
- break;
+ case GWM_DESTROY:
+ {
+ StopAsyncDNSCheck(); // kill off the async DNS check thread in case it is still running
+ break;
- } // end case
+ } // end case
// --------------------------------------------------------------------------------------------
case GWM_INPUT_FOCUS:
@@ -1046,13 +1031,9 @@ WindowMsgHandledType MainMenuSystem( GameWindow *window, UnsignedInt msg,
//---------------------------------------------------------------------------------------------
case GBM_MOUSE_ENTERING:
{
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- if(controlID == onlineID)
- {
- TheScriptEngine->signalUIInteract(TheShellHookNames[SHELL_SCRIPT_HOOK_MAIN_MENU_ONLINE_HIGHLIGHTED]);
- }
- else if(controlID == networkID)
+GameWindow *control = (GameWindow *)mData1;
+Int controlID = control->winGetWindowId();
+if(controlID == networkID)
{
TheScriptEngine->signalUIInteract(TheShellHookNames[SHELL_SCRIPT_HOOK_MAIN_MENU_NETWORK_HIGHLIGHTED]);
}
@@ -1155,11 +1136,7 @@ WindowMsgHandledType MainMenuSystem( GameWindow *window, UnsignedInt msg,
GameWindow *control = (GameWindow *)mData1;
Int controlID = control->winGetWindowId();
- if(controlID == onlineID)
- {
- TheScriptEngine->signalUIInteract(TheShellHookNames[SHELL_SCRIPT_HOOK_MAIN_MENU_ONLINE_UNHIGHLIGHTED]);
- }
- else if(controlID == networkID)
+if(controlID == networkID)
{
TheScriptEngine->signalUIInteract(TheShellHookNames[SHELL_SCRIPT_HOOK_MAIN_MENU_NETWORK_UNHIGHLIGHTED]);
}
@@ -1382,20 +1359,6 @@ WindowMsgHandledType MainMenuSystem( GameWindow *window, UnsignedInt msg,
TheShell->push( AsciiString("Menus/SkirmishGameOptionsMenu.wnd") );
TheScriptEngine->signalUIInteract(TheShellHookNames[SHELL_SCRIPT_HOOK_MAIN_MENU_SKIRMISH_SELECTED]);
}
- else if( controlID == onlineID )
- {
- if(dontAllowTransitions)
- break;
- dontAllowTransitions = TRUE;
- buttonPushed = TRUE;
- dropDownWindows[DROPDOWN_MULTIPLAYER]->winHide(FALSE);
- TheTransitionHandler->reverse("MainMenuMultiPlayerMenuTransitionToNext");
-
- StartPatchCheck();
-// localAnimateWindowManager->reverseAnimateWindow();
- dropDown = DROPDOWN_NONE;
-
- } // end else if
else if( controlID == networkID )
{
if(dontAllowTransitions)
diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/NetworkDirectConnect.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/NetworkDirectConnect.cpp
deleted file mode 100644
index d8d69a75b79..00000000000
--- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/NetworkDirectConnect.cpp
+++ /dev/null
@@ -1,537 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////////////
-// FILE: NetworkDirectConnect.cpp
-// Author: Bryan Cleveland, November 2001
-// Description: Lan Lobby Menu
-///////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "GameSpy/peer/peer.h"
-
-#include "Common/QuotedPrintable.h"
-#include "Common/UserPreferences.h"
-#include "GameClient/AnimateWindowManager.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/GameText.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/GadgetComboBox.h"
-#include "GameClient/GadgetTextEntry.h"
-#include "GameClient/GadgetStaticText.h"
-#include "GameClient/Shell.h"
-#include "GameClient/GameWindowTransitions.h"
-
-#include "GameNetwork/IPEnumeration.h"
-#include "GameNetwork/LANAPI.h"
-#include "GameNetwork/LANAPICallbacks.h"
-
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-
-// window ids ------------------------------------------------------------------------------
-
-// Window Pointers ------------------------------------------------------------------------
-
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-
-extern Bool LANbuttonPushed;
-extern Bool LANisShuttingDown;
-
-static Bool isShuttingDown = false;
-static Bool buttonPushed = false;
-
-static NameKeyType buttonBackID = NAMEKEY_INVALID;
-static NameKeyType buttonHostID = NAMEKEY_INVALID;
-static NameKeyType buttonJoinID = NAMEKEY_INVALID;
-static NameKeyType editPlayerNameID = NAMEKEY_INVALID;
-static NameKeyType comboboxRemoteIPID = NAMEKEY_INVALID;
-static NameKeyType staticLocalIPID = NAMEKEY_INVALID;
-
-static GameWindow *buttonBack = NULL;
-static GameWindow *buttonHost = NULL;
-static GameWindow *buttonJoin = NULL;
-static GameWindow *editPlayerName = NULL;
-static GameWindow *comboboxRemoteIP = NULL;
-static GameWindow *staticLocalIP = NULL;
-
-void PopulateRemoteIPComboBox()
-{
- LANPreferences userprefs;
- GadgetComboBoxReset(comboboxRemoteIP);
-
- Int numRemoteIPs = userprefs.getNumRemoteIPs();
- Color white = GameMakeColor(255,255,255,255);
-
- for (Int i = 0; i < numRemoteIPs; ++i)
- {
- UnicodeString entry;
- entry = userprefs.getRemoteIPEntry(i);
- GadgetComboBoxAddEntry(comboboxRemoteIP, entry, white);
- }
-
- if (numRemoteIPs > 0)
- {
- GadgetComboBoxSetSelectedPos(comboboxRemoteIP, 0, TRUE);
- }
- userprefs.write();
-}
-
-void UpdateRemoteIPList()
-{
- Int n1[4], n2[4];
- LANPreferences prefs;
- Int numEntries = GadgetComboBoxGetLength(comboboxRemoteIP);
- Int currentSelection = -1;
- GadgetComboBoxGetSelectedPos(comboboxRemoteIP, ¤tSelection);
- UnicodeString unisel = GadgetComboBoxGetText(comboboxRemoteIP);
- AsciiString sel;
- sel.translate(unisel);
-
-// UnicodeString newEntry = prefs.getRemoteIPEntry(0);
- UnicodeString newEntry = unisel;
- UnicodeString newIP;
- newEntry.nextToken(&newIP, UnicodeString(L":"));
- Int numFields = swscanf(newIP.str(), L"%d.%d.%d.%d", &(n1[0]), &(n1[1]), &(n1[2]), &(n1[3]));
-
- if (numFields != 4) {
- // this is not a properly formatted IP, don't change a thing.
- return;
- }
-
- prefs["RemoteIP0"] = sel;
-
- Int currentINIEntry = 1;
-
- for (Int i = 0; i < numEntries; ++i)
- {
- if (i != currentSelection)
- {
- GadgetComboBoxSetSelectedPos(comboboxRemoteIP, i, FALSE);
- UnicodeString uni;
- uni = GadgetComboBoxGetText(comboboxRemoteIP);
- AsciiString ascii;
- ascii.translate(uni);
-
- // prevent more than one copy of an IP address from being put in the list.
- if (currentSelection == -1)
- {
- UnicodeString oldEntry = uni;
- UnicodeString oldIP;
- oldEntry.nextToken(&oldIP, UnicodeString(L":"));
-
- swscanf(oldIP.str(), L"%d.%d.%d.%d", &(n2[0]), &(n2[1]), &(n2[2]), &(n2[3]));
-
- Bool isEqual = TRUE;
- for (Int i = 0; (i < 4) && (isEqual == TRUE); ++i) {
- if (n1[i] != n2[i]) {
- isEqual = FALSE;
- }
- }
- // check to see if this is a duplicate or if this is not a properly formatted IP address.
- if (isEqual == TRUE)
- {
- --numEntries;
- continue;
- }
- }
- AsciiString temp;
- temp.format("RemoteIP%d", currentINIEntry);
- ++currentINIEntry;
- prefs[temp.str()] = ascii;
- }
- }
-
- if (currentSelection == -1)
- {
- ++numEntries;
- }
-
- AsciiString numRemoteIPs;
- numRemoteIPs.format("%d", numEntries);
-
- prefs["NumRemoteIPs"] = numRemoteIPs;
-
- prefs.write();
-}
-
-void HostDirectConnectGame()
-{
- // Init LAN API Singleton
- DEBUG_ASSERTCRASH(TheLAN != NULL, ("TheLAN is NULL!"));
- if (!TheLAN)
- {
- TheLAN = NEW LANAPI();
- }
-
- UnsignedInt localIP = TheLAN->GetLocalIP();
- UnicodeString localIPString;
- localIPString.format(L"%d.%d.%d.%d", localIP >> 24, (localIP & 0xff0000) >> 16, (localIP & 0xff00) >> 8, localIP & 0xff);
-
- UnicodeString name;
- name = GadgetTextEntryGetText(editPlayerName);
-
- LANPreferences prefs;
- prefs["UserName"] = UnicodeStringToQuotedPrintable(name);
- prefs.write();
-
- while (name.getLength() > g_lanPlayerNameLength)
- name.removeLastChar();
- TheLAN->RequestSetName(name);
- TheLAN->RequestGameCreate(localIPString, TRUE);
-}
-
-void JoinDirectConnectGame()
-{
- // Init LAN API Singleton
-
- if (!TheLAN)
- {
- TheLAN = NEW LANAPI();
- }
-
- UnsignedInt ipaddress = 0;
- UnicodeString ipunistring = GadgetComboBoxGetText(comboboxRemoteIP);
- AsciiString asciientry;
- asciientry.translate(ipunistring);
-
- AsciiString ipstring;
- asciientry.nextToken(&ipstring, "(");
-
- char ipstr[16];
- strcpy(ipstr, ipstring.str());
-
- Int ip1, ip2, ip3, ip4;
- sscanf(ipstr, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
-
- DEBUG_LOG(("JoinDirectConnectGame - joining at %d.%d.%d.%d\n", ip1, ip2, ip3, ip4));
-
- ipaddress = (ip1 << 24) + (ip2 << 16) + (ip3 << 8) + ip4;
-// ipaddress = htonl(ipaddress);
-
- UnicodeString name;
- name = GadgetTextEntryGetText(editPlayerName);
-
- LANPreferences prefs;
- prefs["UserName"] = UnicodeStringToQuotedPrintable(name);
- prefs.write();
-
- UpdateRemoteIPList();
- PopulateRemoteIPComboBox();
-
- while (name.getLength() > g_lanPlayerNameLength)
- name.removeLastChar();
- TheLAN->RequestSetName(name);
-
- TheLAN->RequestGameJoinDirectConnect(ipaddress);
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the WOL Welcome Menu */
-//-------------------------------------------------------------------------------------------------
-void NetworkDirectConnectInit( WindowLayout *layout, void *userData )
-{
- LANbuttonPushed = false;
- LANisShuttingDown = false;
-
- if (TheLAN == NULL)
- {
- TheLAN = NEW LANAPI();
- TheLAN->init();
- }
- TheLAN->reset();
-
- buttonPushed = false;
- isShuttingDown = false;
- TheShell->showShellMap(TRUE);
- buttonBackID = TheNameKeyGenerator->nameToKey( AsciiString( "NetworkDirectConnect.wnd:ButtonBack" ) );
- buttonHostID = TheNameKeyGenerator->nameToKey( AsciiString( "NetworkDirectConnect.wnd:ButtonHost" ) );
- buttonJoinID = TheNameKeyGenerator->nameToKey( AsciiString( "NetworkDirectConnect.wnd:ButtonJoin" ) );
- editPlayerNameID = TheNameKeyGenerator->nameToKey( AsciiString( "NetworkDirectConnect.wnd:EditPlayerName" ) );
- comboboxRemoteIPID = TheNameKeyGenerator->nameToKey( AsciiString( "NetworkDirectConnect.wnd:ComboboxRemoteIP" ) );
- staticLocalIPID = TheNameKeyGenerator->nameToKey( AsciiString( "NetworkDirectConnect.wnd:StaticLocalIP" ) );
-
- buttonBack = TheWindowManager->winGetWindowFromId( NULL, buttonBackID);
- buttonHost = TheWindowManager->winGetWindowFromId( NULL, buttonHostID);
- buttonJoin = TheWindowManager->winGetWindowFromId( NULL, buttonJoinID);
- editPlayerName = TheWindowManager->winGetWindowFromId( NULL, editPlayerNameID);
- comboboxRemoteIP = TheWindowManager->winGetWindowFromId( NULL, comboboxRemoteIPID);
- staticLocalIP = TheWindowManager->winGetWindowFromId( NULL, staticLocalIPID);
-
-// // animate controls
-// TheShell->registerWithAnimateManager(buttonBack, WIN_ANIMATION_SLIDE_LEFT, TRUE, 800);
-// TheShell->registerWithAnimateManager(buttonHost, WIN_ANIMATION_SLIDE_LEFT, TRUE, 600);
-// TheShell->registerWithAnimateManager(buttonJoin, WIN_ANIMATION_SLIDE_LEFT, TRUE, 200);
-//
- LANPreferences userprefs;
- UnicodeString name;
- name = userprefs.getUserName();
-
- if (name.getLength() == 0)
- {
- name = TheGameText->fetch("GUI:Player");
- }
-
- GadgetTextEntrySetText(editPlayerName, name);
-
- PopulateRemoteIPComboBox();
-
- UnicodeString ipstr;
-
- delete TheLAN;
- TheLAN = NULL;
-
- if (TheLAN == NULL) {
-// DEBUG_ASSERTCRASH(TheLAN != NULL, ("TheLAN is null initializing the direct connect screen."));
- TheLAN = NEW LANAPI();
-
- OptionPreferences prefs;
- UnsignedInt IP = prefs.getOnlineIPAddress();
-
- IPEnumeration IPs;
-
-// if (!IP)
-// {
- EnumeratedIP *IPlist = IPs.getAddresses();
- DEBUG_ASSERTCRASH(IPlist, ("No IP addresses found!"));
- if (!IPlist)
- {
- /// @todo: display error and exit lan lobby if no IPs are found
- }
-
- Bool foundIP = FALSE;
- EnumeratedIP *tempIP = IPlist;
- while ((tempIP != NULL) && (foundIP == FALSE)) {
- if (IP == tempIP->getIP()) {
- foundIP = TRUE;
- }
- tempIP = tempIP->getNext();
- }
-
- if (foundIP == FALSE) {
- // The IP that we had no longer exists, we need to pick a new one.
- IP = IPlist->getIP();
- }
-
-// IP = IPlist->getIP();
-// }
- TheLAN->init();
- TheLAN->SetLocalIP(IP);
- }
-
- UnsignedInt ip = TheLAN->GetLocalIP();
- ipstr.format(L"%d.%d.%d.%d", ip >> 24, (ip & 0xff0000) >> 16, (ip & 0xff00) >> 8, ip & 0xff);
- GadgetStaticTextSetText(staticLocalIP, ipstr);
-
- TheLAN->RequestLobbyLeave(true);
- layout->hide(FALSE);
- layout->bringForward();
- TheTransitionHandler->setGroup("NetworkDirectConnectFade");
-
-
-} // NetworkDirectConnectInit
-
-//-------------------------------------------------------------------------------------------------
-/** This is called when a shutdown is complete for this menu */
-//-------------------------------------------------------------------------------------------------
-static void shutdownComplete( WindowLayout *layout )
-{
-
- isShuttingDown = false;
-
- // hide the layout
- layout->hide( TRUE );
-
- // our shutdown is complete
- TheShell->shutdownComplete( layout );
-
-} // end if
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Welcome Menu shutdown method */
-//-------------------------------------------------------------------------------------------------
-void NetworkDirectConnectShutdown( WindowLayout *layout, void *userData )
-{
- isShuttingDown = true;
-
- // if we are shutting down for an immediate pop, skip the animations
- Bool popImmediate = *(Bool *)userData;
- if( popImmediate )
- {
-
- shutdownComplete( layout );
- return;
-
- } //end if
-
- TheShell->reverseAnimatewindow();
-
- TheTransitionHandler->reverse("NetworkDirectConnectFade");
-} // NetworkDirectConnectShutdown
-
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Welcome Menu update method */
-//-------------------------------------------------------------------------------------------------
-void NetworkDirectConnectUpdate( WindowLayout * layout, void *userData)
-{
- // We'll only be successful if we've requested to
- if(isShuttingDown && TheShell->isAnimFinished() && TheTransitionHandler->isFinished())
- shutdownComplete(layout);
-}// NetworkDirectConnectUpdate
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Welcome Menu input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType NetworkDirectConnectInput( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
- UnsignedByte key = mData1;
- UnsignedByte state = mData2;
- if (buttonPushed)
- break;
-
- switch( key )
- {
-
- // ----------------------------------------------------------------------------------------
- case KEY_ESC:
- {
-
- //
- // send a simulated selected event to the parent window of the
- // back/exit button
- //
- if( BitTest( state, KEY_STATE_UP ) )
- {
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)buttonBack, buttonBackID );
-
- } // end if
-
- // don't let key fall through anywhere else
- return MSG_HANDLED;
-
- } // end escape
-
- } // end switch( key )
-
- } // end char
-
- } // end switch( msg )
-
- return MSG_IGNORED;
-}// NetworkDirectConnectInput
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Welcome Menu window system callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType NetworkDirectConnectSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- UnicodeString txtInput;
-
- switch( msg )
- {
-
-
- case GWM_CREATE:
- {
-
- break;
- } // case GWM_DESTROY:
-
- case GWM_DESTROY:
- {
- break;
- } // case GWM_DESTROY:
-
- case GWM_INPUT_FOCUS:
- {
- // if we're givin the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
-
- return MSG_HANDLED;
- }//case GWM_INPUT_FOCUS:
-
- case GBM_SELECTED:
- {
- if (buttonPushed)
- break;
-
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if ( controlID == buttonBackID )
- {
- UnicodeString name;
- name = GadgetTextEntryGetText(editPlayerName);
-
- LANPreferences prefs;
- prefs["UserName"] = UnicodeStringToQuotedPrintable(name);
- prefs.write();
-
- while (name.getLength() > g_lanPlayerNameLength)
- name.removeLastChar();
- TheLAN->RequestSetName(name);
-
- buttonPushed = true;
- LANbuttonPushed = true;
- TheShell->pop();
- } //if ( controlID == buttonBack )
- else if (controlID == buttonHostID)
- {
- HostDirectConnectGame();
- }
- else if (controlID == buttonJoinID)
- {
- JoinDirectConnectGame();
- }
- break;
- }// case GBM_SELECTED:
-
- case GEM_EDIT_DONE:
- {
- break;
- }
- default:
- return MSG_IGNORED;
-
- }//Switch
-
- return MSG_HANDLED;
-}// NetworkDirectConnectSystem
diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp
index da7081488e8..6411147a8d6 100644
--- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp
+++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp
@@ -30,8 +30,6 @@
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-#include "GameSpy/ghttp/ghttp.h"
-
#include "Common/AudioAffect.h"
#include "Common/AudioSettings.h"
#include "Common/GameAudio.h"
@@ -63,8 +61,6 @@
#include "GameClient/GUICallbacks.h"
#include "GameNetwork/FirewallHelper.h"
#include "GameNetwork/IPEnumeration.h"
-#include "GameNetwork/GameSpyOverlay.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
#include "GameLogic/GameLogic.h"
#include "GameLogic/ScriptEngine.h"
#include "WWDownload/Registry.h"
@@ -82,9 +78,6 @@
#endif
-static NameKeyType comboBoxOnlineIPID = NAMEKEY_INVALID;
-static GameWindow * comboBoxOnlineIP = NULL;
-
static NameKeyType comboBoxLANIPID = NAMEKEY_INVALID;
static GameWindow * comboBoxLANIP = NULL;
@@ -763,7 +756,7 @@ static void setDefaults( void )
//-------------------------------------------------------------------------------------------------
// Resolution
//Find index of 800x600 mode.
- if ((TheGameLogic->isInGame() == FALSE) || (TheGameLogic->isInShellGame() == TRUE) && !TheGameSpyInfo) {
+ if ((TheGameLogic->isInGame() == FALSE) || (TheGameLogic->isInShellGame() == TRUE)) {
Int numResolutions = TheDisplay->getDisplayModeCount();
Int defaultResIndex=0;
for( Int i = 0; i < numResolutions; ++i )
@@ -1073,13 +1066,6 @@ static void saveOptions( void )
TheWritableGlobalData->m_defaultIP = ip;
pref->setLANIPAddress(ip);
}
- GadgetComboBoxGetSelectedPos(comboBoxOnlineIP, &index);
- if (index>=0)
- {
- ip = (UnsignedInt)GadgetComboBoxGetItemData(comboBoxOnlineIP, index);
- pref->setOnlineIPAddress(ip);
- }
-
//-------------------------------------------------------------------------------------------------
// HTTP Proxy
GameWindow *textEntryHTTPProxy = TheWindowManager->winGetWindowFromId(NULL, NAMEKEY("OptionsMenu.wnd:TextEntryHTTPProxy"));
@@ -1089,7 +1075,6 @@ static void saveOptions( void )
AsciiString aStr;
aStr.translate(uStr);
SetStringInRegistry("", "Proxy", aStr.str());
- ghttpSetProxy(aStr.str());
}
//-------------------------------------------------------------------------------------------------
@@ -1287,8 +1272,10 @@ void OptionsMenuInit( WindowLayout *layout, void *userData )
comboBoxLANIPID = TheNameKeyGenerator->nameToKey( AsciiString( "OptionsMenu.wnd:ComboBoxIP" ) );
comboBoxLANIP = TheWindowManager->winGetWindowFromId( NULL, comboBoxLANIPID);
- comboBoxOnlineIPID = TheNameKeyGenerator->nameToKey( AsciiString( "OptionsMenu.wnd:ComboBoxOnlineIP" ) );
- comboBoxOnlineIP = TheWindowManager->winGetWindowFromId( NULL, comboBoxOnlineIPID);
+ NameKeyType comboBoxOnlineIPID = TheNameKeyGenerator->nameToKey( AsciiString( "OptionsMenu.wnd:ComboBoxOnlineIP" ) );
+ if ( GameWindow *comboBoxOnlineIP = TheWindowManager->winGetWindowFromId( NULL, comboBoxOnlineIPID ) )
+ comboBoxOnlineIP->winHide( TRUE );
+
checkAlternateMouseID = TheNameKeyGenerator->nameToKey( AsciiString( "OptionsMenu.wnd:CheckAlternateMouse" ) );
checkAlternateMouse = TheWindowManager->winGetWindowFromId( NULL, checkAlternateMouseID);
sliderScrollSpeedID = TheNameKeyGenerator->nameToKey( AsciiString( "OptionsMenu.wnd:SliderScrollSpeed" ) );
@@ -1447,53 +1434,16 @@ void OptionsMenuInit( WindowLayout *layout, void *userData )
{
GadgetComboBoxSetSelectedPos(comboBoxLANIP, selectedIndex);
}
- else
- {
- GadgetComboBoxSetSelectedPos(comboBoxLANIP, 0);
- if (IPs.getAddresses())
- {
- pref->setLANIPAddress(IPs.getAddresses()->getIPstring());
- }
- }
+ else
+ {
+ GadgetComboBoxSetSelectedPos(comboBoxLANIP, 0);
+ if (IPs.getAddresses())
+ {
+ pref->setLANIPAddress(IPs.getAddresses()->getIPstring());
+ }
+ }
- // And now the GameSpy one
- if (comboBoxOnlineIP)
- {
- UnsignedInt selectedIP = pref->getOnlineIPAddress();
- UnicodeString str;
- IPEnumeration IPs;
- EnumeratedIP *IPlist = IPs.getAddresses();
- Int index;
- Int selectedIndex = -1;
- Int count = 0;
- GadgetComboBoxReset(comboBoxOnlineIP);
- while (IPlist)
- {
- count++;
- str.translate(IPlist->getIPstring());
- index = GadgetComboBoxAddEntry(comboBoxOnlineIP, str, color);
- GadgetComboBoxSetItemData(comboBoxOnlineIP, index, (void *)(IPlist->getIP()));
- if (selectedIP == IPlist->getIP())
- {
- selectedIndex = index;
- }
- IPlist = IPlist->getNext();
- }
- if (selectedIndex >= 0)
- {
- GadgetComboBoxSetSelectedPos(comboBoxOnlineIP, selectedIndex);
- }
- else
- {
- GadgetComboBoxSetSelectedPos(comboBoxOnlineIP, 0);
- if (IPs.getAddresses())
- {
- pref->setOnlineIPAddress(IPs.getAddresses()->getIPstring());
- }
- }
- }
-
- // HTTP Proxy
+ // HTTP Proxy
GameWindow *textEntryHTTPProxy = TheWindowManager->winGetWindowFromId(NULL, NAMEKEY("OptionsMenu.wnd:TextEntryHTTPProxy"));
if (textEntryHTTPProxy)
{
@@ -1728,12 +1678,10 @@ void OptionsMenuInit( WindowLayout *layout, void *userData )
GameWindow *parent = TheWindowManager->winGetWindowFromId( NULL, parentID );
TheWindowManager->winSetFocus( parent );
- if( (TheGameLogic->isInGame() && TheGameLogic->getGameMode() != GAME_SHELL) || TheGameSpyInfo )
+ if( (TheGameLogic->isInGame() && TheGameLogic->getGameMode() != GAME_SHELL) )
{
// disable controls that you can't change the options for in game
comboBoxLANIP->winEnable(FALSE);
- if (comboBoxOnlineIP)
- comboBoxOnlineIP->winEnable(FALSE);
checkSendDelay->winEnable(FALSE);
buttonFirewallRefresh->winEnable(FALSE);
@@ -1928,15 +1876,8 @@ WindowMsgHandledType OptionsMenuSystem( GameWindow *window, UnsignedInt msg,
pref = NULL;
}
- comboBoxLANIP = NULL;
- comboBoxOnlineIP = NULL;
-
- if(GameSpyIsOverlayOpen(GSOVERLAY_OPTIONS))
- GameSpyCloseOverlay(GSOVERLAY_OPTIONS);
- else
- {
- DestroyOptionsLayout();
- }
+comboBoxLANIP = NULL;
+DestroyOptionsLayout();
} // end if
else if (controlID == buttonAccept )
@@ -1950,23 +1891,15 @@ WindowMsgHandledType OptionsMenuSystem( GameWindow *window, UnsignedInt msg,
pref = NULL;
}
- comboBoxLANIP = NULL;
- comboBoxOnlineIP = NULL;
-
- if(!TheGameLogic->isInGame() || TheGameLogic->isInShellGame())
- destroyQuitMenu(); // if we're in a game, the change res then enter the same kind of game, we nee the quit menu to be gone.
-
+comboBoxLANIP = NULL;
+if(!TheGameLogic->isInGame() || TheGameLogic->isInShellGame())
+destroyQuitMenu(); // if we're in a game, the change res then enter the same kind of game, we nee the quit menu to be gone.
- if(GameSpyIsOverlayOpen(GSOVERLAY_OPTIONS))
- GameSpyCloseOverlay(GSOVERLAY_OPTIONS);
- else
- {
- DestroyOptionsLayout();
- if (dispChanged)
- {
- DoResolutionDialog();
- }
- }
+DestroyOptionsLayout();
+if (dispChanged)
+{
+DoResolutionDialog();
+}
}
else if (controlID == buttonDefaults )
diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/PopupLadderSelect.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/PopupLadderSelect.cpp
deleted file mode 100644
index b66b8b717e1..00000000000
--- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/PopupLadderSelect.cpp
+++ /dev/null
@@ -1,682 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: PopupLadderSelect.cpp ////////////////////////////////////////////////
-//-----------------------------------------------------------------------------
-//
-// Electronic Arts Pacific.
-//
-// Confidential Information
-// Copyright (C) 2002 - All Rights Reserved
-//
-//-----------------------------------------------------------------------------
-//
-// created: August 2002
-//
-// Filename: PopupLadderSelect.cpp
-//
-// author: Matthew D. Campbell
-//
-// purpose: Contains the Callbacks for the Ladder Select Popup
-//
-//-----------------------------------------------------------------------------
-///////////////////////////////////////////////////////////////////////////////
-
-//-----------------------------------------------------------------------------
-// SYSTEM INCLUDES ////////////////////////////////////////////////////////////
-//-----------------------------------------------------------------------------
-
-//-----------------------------------------------------------------------------
-// USER INCLUDES //////////////////////////////////////////////////////////////
-//-----------------------------------------------------------------------------
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/GlobalData.h"
-#include "Common/Encrypt.h"
-#include "Common/NameKeyGenerator.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/GameText.h"
-#include "GameClient/KeyDefs.h"
-#include "GameClient/MapUtil.h"
-#include "GameClient/GadgetListBox.h"
-#include "GameClient/GadgetStaticText.h"
-#include "GameClient/GadgetTextEntry.h"
-#include "GameNetwork/GameSpy/LadderDefs.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-//#include "GameNetwork/GameSpy/PeerThread.h"
-#include "GameNetwork/GameSpyOverlay.h"
-
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-
-//-----------------------------------------------------------------------------
-// DEFINES ////////////////////////////////////////////////////////////////////
-//-----------------------------------------------------------------------------
-
-static NameKeyType parentID = NAMEKEY_INVALID;
-static NameKeyType listboxLadderSelectID = NAMEKEY_INVALID;
-static NameKeyType listboxLadderDetailsID = NAMEKEY_INVALID;
-static NameKeyType staticTextLadderNameID = NAMEKEY_INVALID;
-static NameKeyType buttonOkID = NAMEKEY_INVALID;
-static NameKeyType buttonCancelID = NAMEKEY_INVALID;
-
-static GameWindow *parent = NULL;
-static GameWindow *listboxLadderSelect = NULL;
-static GameWindow *listboxLadderDetails = NULL;
-static GameWindow *staticTextLadderName = NULL;
-static GameWindow *buttonOk = NULL;
-static GameWindow *buttonCancel = NULL;
-
-// password entry popup
-static NameKeyType passwordParentID = NAMEKEY_INVALID;
-static NameKeyType buttonPasswordOkID = NAMEKEY_INVALID;
-static NameKeyType buttonPasswordCancelID = NAMEKEY_INVALID;
-static NameKeyType textEntryPasswordID = NAMEKEY_INVALID;
-static GameWindow *passwordParent = NULL;
-static GameWindow *textEntryPassword = NULL;
-
-// incorrect password popup
-static NameKeyType badPasswordParentID = NAMEKEY_INVALID;
-static NameKeyType buttonBadPasswordOkID = NAMEKEY_INVALID;
-static GameWindow *badPasswordParent = NULL;
-
-static void updateLadderDetails( Int ladderID, GameWindow *staticTextLadderName, GameWindow *listboxLadderDetails );
-
-void PopulateQMLadderComboBox( void );
-void PopulateCustomLadderComboBox( void );
-
-void PopulateQMLadderListBox( GameWindow *win );
-void PopulateCustomLadderListBox( GameWindow *win );
-
-void HandleQMLadderSelection(Int ladderID);
-void HandleCustomLadderSelection(Int ladderID);
-
-void CustomMatchHideHostPopup(Bool hide);
-
-static void populateLadderComboBox( void )
-{
- // only one of these will do any work...
- PopulateQMLadderComboBox();
- PopulateCustomLadderComboBox();
-}
-
-static void populateLadderListBox( void )
-{
- // only one of these will do any work...
- PopulateQMLadderListBox(listboxLadderSelect);
- PopulateCustomLadderListBox(listboxLadderSelect);
-
- Int selIndex, selID;
- GadgetListBoxGetSelected(listboxLadderSelect, &selIndex);
- if (selIndex < 0)
- return;
- selID = (Int)GadgetListBoxGetItemData(listboxLadderSelect, selIndex);
- if (!selID)
- return;
- updateLadderDetails(selID, staticTextLadderName, listboxLadderDetails);
-}
-
-static void handleLadderSelection( Int ladderID )
-{
- // only one of these will do any work...
- HandleQMLadderSelection(ladderID);
- HandleCustomLadderSelection(ladderID);
-}
-
-
-enum PasswordMode
-{
- PASS_NONE,
- PASS_ENTRY,
- PASS_ERROR
-};
-
-static PasswordMode s_currentMode = PASS_NONE;
-static void setPasswordMode(PasswordMode mode)
-{
- s_currentMode = mode;
- switch(mode)
- {
- case PASS_NONE:
- if (passwordParent)
- passwordParent->winHide(TRUE);
- if (badPasswordParent)
- badPasswordParent->winHide(TRUE);
- if (buttonOk)
- buttonOk->winEnable(TRUE);
- if (buttonCancel)
- buttonCancel->winEnable(TRUE);
- if (textEntryPassword)
- textEntryPassword->winEnable(FALSE);
- if (listboxLadderSelect)
- listboxLadderSelect->winEnable(TRUE);
- TheWindowManager->winSetFocus(listboxLadderSelect);
- break;
- case PASS_ENTRY:
- if (passwordParent)
- passwordParent->winHide(FALSE);
- if (badPasswordParent)
- badPasswordParent->winHide(TRUE);
- if (buttonOk)
- buttonOk->winEnable(FALSE);
- if (buttonCancel)
- buttonCancel->winEnable(FALSE);
- if (textEntryPassword)
- {
- textEntryPassword->winEnable(TRUE);
- GadgetTextEntrySetText(textEntryPassword, UnicodeString::TheEmptyString);
- }
- if (listboxLadderSelect)
- listboxLadderSelect->winEnable(FALSE);
- TheWindowManager->winSetFocus(textEntryPassword);
- break;
- case PASS_ERROR:
- if (passwordParent)
- passwordParent->winHide(TRUE);
- if (badPasswordParent)
- badPasswordParent->winHide(FALSE);
- if (buttonOk)
- buttonOk->winEnable(FALSE);
- if (buttonCancel)
- buttonCancel->winEnable(FALSE);
- if (textEntryPassword)
- textEntryPassword->winEnable(FALSE);
- if (listboxLadderSelect)
- listboxLadderSelect->winEnable(FALSE);
- TheWindowManager->winSetFocus(parent);
- break;
- }
-}
-
-//-----------------------------------------------------------------------------
-// PUBLIC FUNCTIONS ///////////////////////////////////////////////////////////
-//-----------------------------------------------------------------------------
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the menu */
-//-------------------------------------------------------------------------------------------------
-void PopupLadderSelectInit( WindowLayout *layout, void *userData )
-{
- parentID = NAMEKEY("PopupLadderSelect.wnd:Parent");
- parent = TheWindowManager->winGetWindowFromId(NULL, parentID);
-
- listboxLadderSelectID = NAMEKEY("PopupLadderSelect.wnd:ListBoxLadderSelect");
- listboxLadderSelect = TheWindowManager->winGetWindowFromId(parent, listboxLadderSelectID);
-
- listboxLadderDetailsID = NAMEKEY("PopupLadderSelect.wnd:ListBoxLadderDetails");
- listboxLadderDetails = TheWindowManager->winGetWindowFromId(parent, listboxLadderDetailsID);
-
- staticTextLadderNameID = NAMEKEY("PopupLadderSelect.wnd:StaticTextLadderName");
- staticTextLadderName = TheWindowManager->winGetWindowFromId(parent, staticTextLadderNameID);
-
- buttonOkID = NAMEKEY("PopupLadderSelect.wnd:ButtonOk");
- buttonCancelID = NAMEKEY("PopupLadderSelect.wnd:ButtonCancel");
-
- buttonOk = TheWindowManager->winGetWindowFromId(parent, buttonOkID);
- buttonCancel = TheWindowManager->winGetWindowFromId(parent, buttonCancelID);
-
- TheWindowManager->winSetFocus( parent );
- TheWindowManager->winSetModal( parent );
-
- // password entry popup
- passwordParentID = NAMEKEY("PopupLadderSelect.wnd:PasswordParent");
- passwordParent = TheWindowManager->winGetWindowFromId(parent, passwordParentID);
- buttonPasswordOkID = NAMEKEY("PopupLadderSelect.wnd:ButtonPasswordOk");
- buttonPasswordCancelID = NAMEKEY("PopupLadderSelect.wnd:ButtonPasswordCancel");
- textEntryPasswordID = NAMEKEY("PopupLadderSelect.wnd:PasswordEntry");
- textEntryPassword = TheWindowManager->winGetWindowFromId(parent, textEntryPasswordID);
-
- // bad password popup
- badPasswordParentID = NAMEKEY("PopupLadderSelect.wnd:BadPasswordParent");
- badPasswordParent = TheWindowManager->winGetWindowFromId(parent, badPasswordParentID);
- buttonBadPasswordOkID = NAMEKEY("PopupLadderSelect.wnd:ButtonBadPasswordOk");
-
- setPasswordMode(PASS_NONE);
-
- CustomMatchHideHostPopup(TRUE);
-
- // populate list box (based on whether we're in custom or quickmatch)
- populateLadderListBox();
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType PopupLadderSelectInput( GameWindow *window, UnsignedInt msg, WindowMsgData mData1, WindowMsgData mData2 )
-{
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
- UnsignedByte key = mData1;
- UnsignedByte state = mData2;
-// if (buttonPushed)
-// break;
-
- switch( key )
- {
-
- // ----------------------------------------------------------------------------------------
- case KEY_ESC:
- {
-
- //
- // send a simulated selected event to the parent window of the
- // back/exit button
- //
- if( BitTest( state, KEY_STATE_UP ) )
- {
- switch (s_currentMode)
- {
- case PASS_NONE:
- // re-select whatever was chosen before
- populateLadderComboBox();
- GameSpyCloseOverlay(GSOVERLAY_LADDERSELECT);
- break;
- case PASS_ENTRY:
- case PASS_ERROR:
- setPasswordMode(PASS_NONE);
- break;
- }
-
- } // end if
-
- // don't let key fall through anywhere else
- return MSG_HANDLED;
-
- } // end escape
-
- } // end switch( key )
-
- } // end char
-
- } // end switch( msg )
-
- return MSG_IGNORED;
-
-}
-
-static Int ladderIndex = 0;
-void ladderSelectedCallback(void)
-{
- handleLadderSelection( ladderIndex );
-
- // update combo box
- populateLadderComboBox();
-
- // tear down overlay
- GameSpyCloseOverlay( GSOVERLAY_LADDERSELECT );
-}
-
-//-------------------------------------------------------------------------------------------------
-/** System callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType PopupLadderSelectSystem( GameWindow *window, UnsignedInt msg, WindowMsgData mData1, WindowMsgData mData2 )
-{
- switch( msg )
- {
- // --------------------------------------------------------------------------------------------
- case GWM_CREATE:
- {
- break;
- } // end create
- //---------------------------------------------------------------------------------------------
- case GWM_DESTROY:
- {
- parent = NULL;
- listboxLadderSelect = NULL;
- listboxLadderDetails = NULL;
- CustomMatchHideHostPopup(FALSE);
- break;
- } // end case
-
- //----------------------------------------------------------------------------------------------
- case GWM_INPUT_FOCUS:
- {
- // if we're given the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
- break;
- } // end input
- //----------------------------------------------------------------------------------------------
- case GBM_SELECTED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- if (controlID == buttonOkID)
- {
- // save selection
- Int selectPos = -1;
- GadgetListBoxGetSelected( listboxLadderSelect, &selectPos );
- if (selectPos < 0)
- break;
-
- ladderIndex = (Int)GadgetListBoxGetItemData( listboxLadderSelect, selectPos, 0 );
- const LadderInfo *li = TheLadderList->findLadderByIndex( ladderIndex );
- if (li && li->cryptedPassword.isNotEmpty())
- {
- // need password asking
- setPasswordMode(PASS_ENTRY);
- }
- else
- {
- ladderSelectedCallback();
- }
- }
- else if (controlID == buttonCancelID)
- {
- // reset what had been
- populateLadderComboBox();
-
- // tear down overlay
- GameSpyCloseOverlay( GSOVERLAY_LADDERSELECT );
- }
- else if (controlID == buttonPasswordOkID)
- {
- const LadderInfo *li = TheLadderList->findLadderByIndex( ladderIndex );
- if (!li || li->cryptedPassword.isEmpty())
- {
- // eh? something's not right. just pretend they typed something wrong...
- setPasswordMode(PASS_ERROR);
- break;
- }
-
- AsciiString pass;
- pass.translate(GadgetTextEntryGetText(textEntryPassword));
- if ( pass.isNotEmpty() ) // password ok
- {
- AsciiString cryptPass = EncryptString(pass.str());
- DEBUG_LOG(("pass is %s, crypted pass is %s, comparing to %s\n",
- pass.str(), cryptPass.str(), li->cryptedPassword.str()));
- if (cryptPass == li->cryptedPassword)
- ladderSelectedCallback();
- else
- setPasswordMode(PASS_ERROR);
- }
- else
- {
- setPasswordMode(PASS_ERROR);
- }
- }
- else if (controlID == buttonPasswordCancelID)
- {
- setPasswordMode(PASS_NONE);
- }
- else if (controlID == buttonBadPasswordOkID)
- {
- setPasswordMode(PASS_NONE);
- }
- break;
- } // end input
-
- //---------------------------------------------------------------------------------------------
- case GLM_SELECTED:
- {
- Int selIndex, selID;
- GadgetListBoxGetSelected(listboxLadderSelect, &selIndex);
- if (selIndex < 0)
- break;
-
- selID = (Int)GadgetListBoxGetItemData(listboxLadderSelect, selIndex);
- if (!selID)
- break;
-
- updateLadderDetails(selID, staticTextLadderName, listboxLadderDetails);
- break;
- } // end GLM_DOUBLE_CLICKED
-
- //---------------------------------------------------------------------------------------------
- case GLM_DOUBLE_CLICKED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- Int selectPos = (Int)mData2;
- GadgetListBoxSetSelected(control, &selectPos);
-
- if( controlID == listboxLadderSelectID )
- {
- TheWindowManager->winSendSystemMsg( parent, GBM_SELECTED,
- (WindowMsgData)buttonOk, buttonOk->winGetWindowId() );
- }
- break;
- }
-
- //---------------------------------------------------------------------------------------------
- case GEM_EDIT_DONE:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- if (controlID == textEntryPasswordID)
- {
- TheWindowManager->winSendSystemMsg( parent, GBM_SELECTED,
- (WindowMsgData)(TheWindowManager->winGetWindowFromId(passwordParent, buttonPasswordOkID)), buttonPasswordOkID );
- }
- break;
- }
-
- default:
- return MSG_IGNORED;
-
- } // end switch
-
- return MSG_HANDLED;
-
-}
-
-
-//-----------------------------------------------------------------------------
-// PRIVATE FUNCTIONS //////////////////////////////////////////////////////////
-//-----------------------------------------------------------------------------
-
-static void updateLadderDetails( Int selID, GameWindow *staticTextLadderName, GameWindow *listboxLadderDetails )
-{
- if (!staticTextLadderName || !listboxLadderDetails)
- return;
-
- GadgetStaticTextSetText(staticTextLadderName, UnicodeString::TheEmptyString);
- GadgetListBoxReset(listboxLadderDetails);
-
- const LadderInfo *info = TheLadderList->findLadderByIndex(selID);
- if (!info)
- return;
-
- UnicodeString line;
- Color color = GameMakeColor( 255, 255, 255, 255 );
- Color captionColor = GameMakeColor( 0, 255, 255, 255 );
-
- // name
- line.format(TheGameText->fetch("GUI:LadderNameAndSize"), info->name.str(), info->playersPerTeam, info->playersPerTeam);
- GadgetStaticTextSetText(staticTextLadderName, line);
-
- // location
- if (!info->location.isEmpty())
- GadgetListBoxAddEntryText(listboxLadderDetails, info->location, captionColor, -1);
-
- // homepage
- line.format(TheGameText->fetch("GUI:LadderURL"), info->homepageURL.str());
- GadgetListBoxAddEntryText(listboxLadderDetails, line, captionColor, -1);
-
- // description
- if (!info->description.isEmpty())
- GadgetListBoxAddEntryText(listboxLadderDetails, info->description, color, -1);
-
- // requires password?
- if (info->cryptedPassword.isNotEmpty())
- {
- GadgetListBoxAddEntryText(listboxLadderDetails, TheGameText->fetch("GUI:LadderHasPassword"), captionColor, -1);
- }
-
- // wins limits
- if (info->minWins)
- {
- line.format(TheGameText->fetch("GUI:LadderMinWins"), info->minWins);
- GadgetListBoxAddEntryText(listboxLadderDetails, line, captionColor, -1);
- }
- if (info->maxWins)
- {
- line.format(TheGameText->fetch("GUI:LadderMaxWins"), info->maxWins);
- GadgetListBoxAddEntryText(listboxLadderDetails, line, captionColor, -1);
- }
-
- // random factions?
- if (info->randomFactions)
- {
- GadgetListBoxAddEntryText(listboxLadderDetails, TheGameText->fetch("GUI:LadderRandomFactions"), captionColor, -1);
- }
- else
- {
- GadgetListBoxAddEntryText(listboxLadderDetails, TheGameText->fetch("GUI:LadderFactions"), captionColor, -1);
- }
-
- // factions
- AsciiStringList validFactions = info->validFactions;
- for (AsciiStringListIterator it = validFactions.begin(); it != validFactions.end(); ++it)
- {
- AsciiString marker;
- marker.format("INI:Faction%s", it->str());
- GadgetListBoxAddEntryText(listboxLadderDetails, TheGameText->fetch(marker), color, -1);
- }
-
- // random maps?
- if (info->randomMaps)
- {
- GadgetListBoxAddEntryText(listboxLadderDetails, TheGameText->fetch("GUI:LadderRandomMaps"), captionColor, -1);
- }
- else
- {
- GadgetListBoxAddEntryText(listboxLadderDetails, TheGameText->fetch("GUI:LadderMaps"), captionColor, -1);
- }
-
- // maps
- AsciiStringList validMaps = info->validMaps;
- for (it = validMaps.begin(); it != validMaps.end(); ++it)
- {
- const MapMetaData *md = TheMapCache->findMap(*it);
- if (md)
- {
- GadgetListBoxAddEntryText(listboxLadderDetails, md->m_displayName, color, -1);
- }
- }
-}
-
-static void closeRightClickMenu(GameWindow *win)
-{
-
- if(win)
- {
- WindowLayout *winLay = win->winGetLayout();
- if(!winLay)
- return;
- winLay->destroyWindows();
- winLay->deleteInstance();
- winLay = NULL;
-
- }
-}
-void RCGameDetailsMenuInit( WindowLayout *layout, void *userData )
-{
-}
-
-WindowMsgHandledType RCGameDetailsMenuSystem( GameWindow *window, UnsignedInt msg, WindowMsgData mData1, WindowMsgData mData2 )
-{
-
- static NameKeyType ladderInfoID = NAMEKEY_INVALID;
- static NameKeyType buttonOkID = NAMEKEY_INVALID;
- switch( msg )
- {
-
- case GWM_CREATE:
- {
- ladderInfoID = NAMEKEY("RCGameDetailsMenu.wnd:ButtonLadderDetails");
- buttonOkID = NAMEKEY("PopupLadderDetails.wnd:ButtonOk");
- break;
- } // case GWM_DESTROY:
-
- case GGM_CLOSE:
- {
- closeRightClickMenu(window);
- //rcMenu = NULL;
- break;
- }
-
- case GWM_DESTROY:
- {
- break;
- } // case GWM_DESTROY:
-
- case GBM_SELECTED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- Int selectedID = (Int)window->winGetUserData();
- if(!selectedID)
- break;
- closeRightClickMenu(window);
-
- if (controlID == ladderInfoID)
- {
- StagingRoomMap *srm = TheGameSpyInfo->getStagingRoomList();
- StagingRoomMap::iterator srmIt = srm->find(selectedID);
- if (srmIt != srm->end())
- {
- GameSpyStagingRoom *theRoom = srmIt->second;
- if (!theRoom)
- break;
- const LadderInfo *linfo = TheLadderList->findLadder(theRoom->getLadderIP(), theRoom->getLadderPort());
- if (linfo)
- {
- WindowLayout *rcLayout = TheWindowManager->winCreateLayout(AsciiString("Menus/PopupLadderDetails.wnd"));
- if (!rcLayout)
- break;
-
- GameWindow *rcMenu = rcLayout->getFirstWindow();
- rcMenu->winGetLayout()->runInit();
- rcMenu->winBringToTop();
- rcMenu->winHide(FALSE);
-
- rcMenu->winSetUserData((void *)selectedID);
- TheWindowManager->winSetLoneWindow(rcMenu);
-
- GameWindow *st = TheWindowManager->winGetWindowFromId(NULL,
- NAMEKEY("PopupLadderDetails.wnd:StaticTextLadderName"));
- GameWindow *lb = TheWindowManager->winGetWindowFromId(NULL,
- NAMEKEY("PopupLadderDetails.wnd:ListBoxLadderDetails"));
- updateLadderDetails(selectedID, st, lb);
- }
- }
- }
- break;
- }
- default:
- return MSG_IGNORED;
-
- }//Switch
- return MSG_HANDLED;
-}
diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLBuddyOverlay.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLBuddyOverlay.cpp
deleted file mode 100644
index 55db148badc..00000000000
--- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLBuddyOverlay.cpp
+++ /dev/null
@@ -1,1453 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////////////
-// FILE: WOLBuddyOverlay.cpp
-// Author: Chris Huybregts, November 2001
-// Description: Lan Lobby Menu
-///////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/AudioEventRTS.h"
-#include "Common/PlayerList.h"
-#include "Common/Player.h"
-#include "GameClient/GameText.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/Shell.h"
-#include "GameClient/KeyDefs.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/GadgetListBox.h"
-#include "GameClient/GadgetPushButton.h"
-#include "GameClient/GadgetStaticText.h"
-#include "GameClient/GadgetTextEntry.h"
-#include "GameClient/GadgetRadioButton.h"
-#include "GameClient/Display.h"
-#include "GameNetwork/GameSpyOverlay.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpy/BuddyDefs.h"
-#include "GameNetwork/GameSpy/BuddyThread.h"
-#include "GameNetwork/GameSpy/LobbyUtils.h"
-#include "GameNetwork/GameSpy/PersistentStorageDefs.h"
-#include "GameNetwork/GameSpy/PersistentStorageThread.h"
-#include "GameNetwork/GameSpy/ThreadUtils.h"
-
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-
-// window ids ------------------------------------------------------------------------------
-static NameKeyType parentID = NAMEKEY_INVALID;
-static NameKeyType buttonHideID = NAMEKEY_INVALID;
-static NameKeyType buttonAddBuddyID = NAMEKEY_INVALID;
-static NameKeyType buttonDeleteBuddyID = NAMEKEY_INVALID;
-static NameKeyType textEntryID = NAMEKEY_INVALID;
-static NameKeyType listboxBuddyID = NAMEKEY_INVALID;
-static NameKeyType listboxChatID = NAMEKEY_INVALID;
-static NameKeyType buttonAcceptBuddyID = NAMEKEY_INVALID;
-static NameKeyType buttonDenyBuddyID = NAMEKEY_INVALID;
-static NameKeyType radioButtonBuddiesID = NAMEKEY_INVALID;
-static NameKeyType radioButtonIgnoreID = NAMEKEY_INVALID;
-static NameKeyType parentBuddiesID = NAMEKEY_INVALID;
-static NameKeyType parentIgnoreID = NAMEKEY_INVALID;
-static NameKeyType listboxIgnoreID = NAMEKEY_INVALID;
-static NameKeyType buttonNotificationID = NAMEKEY_INVALID;
-
-
-// Window Pointers ------------------------------------------------------------------------
-static GameWindow *parent = NULL;
-static GameWindow *buttonHide = NULL;
-static GameWindow *buttonAddBuddy = NULL;
-static GameWindow *buttonDeleteBuddy = NULL;
-static GameWindow *textEntry = NULL;
-static GameWindow *listboxBuddy = NULL;
-static GameWindow *listboxChat = NULL;
-static GameWindow *buttonAcceptBuddy = NULL;
-static GameWindow *buttonDenyBuddy = NULL;
-static GameWindow *radioButtonBuddies = NULL;
-static GameWindow *radioButtonIgnore = NULL;
-static GameWindow *parentBuddies = NULL;
-static GameWindow *parentIgnore = NULL;
-static GameWindow *listboxIgnore = NULL;
-
-static Bool isOverlayActive = false;
-void insertChat( BuddyMessage msg );
-// RightClick pointers ---------------------------------------------------------------------
-static GameWindow *rcMenu = NULL;
-static WindowLayout *noticeLayout = NULL;
-static UnsignedInt noticeExpires = 0;
-enum { NOTIFICATION_EXPIRES = 3000 };
-
-void setUnignoreText( WindowLayout *layout, AsciiString nick, GPProfile id);
-void refreshIgnoreList( void );
-void showNotificationBox( AsciiString nick, UnicodeString message);
-void deleteNotificationBox( void );
-static Bool lastNotificationWasStatus = FALSE;
-static Int numOnlineInNotification = 0;
-
-class BuddyControls
-{
-public:
- BuddyControls(void );
- GameWindow *listboxChat;
- NameKeyType listboxChatID;
-
- GameWindow *listboxBuddies;
- NameKeyType listboxBuddiesID;
-
- GameWindow *textEntryEdit;
- NameKeyType textEntryEditID;
- Bool isInit;
-};
-
-static BuddyControls buddyControls;
-BuddyControls::BuddyControls( void )
-{
- listboxChat = NULL;
- listboxChatID = NAMEKEY_INVALID;
- listboxBuddies = NULL;
- listboxBuddiesID = NAMEKEY_INVALID;
- textEntryEdit = NULL;
- textEntryEditID = NAMEKEY_INVALID;
- isInit = FALSE;
-}
-// At this point I don't give a damn about how good this way is. I'm doing it anyway.
-enum
-{
- BUDDY_RESETALL_CRAP = -1,
- BUDDY_WINDOW_BUDDIES = 0,
- BUDDY_WINDOW_DIPLOMACY,
- BUDDY_WINDOW_WELCOME_SCREEN,
-};
-
-void InitBuddyControls(Int type)
-{
- if(!TheGameSpyInfo)
- {
- buddyControls.textEntryEditID = NAMEKEY_INVALID;
- buddyControls.textEntryEdit = NULL;
- buddyControls.listboxBuddiesID = NAMEKEY_INVALID;
- buddyControls.listboxChatID = NAMEKEY_INVALID;
- buddyControls.listboxBuddies = NULL;
- buddyControls.listboxChat = NULL;
- buddyControls.isInit = FALSE;
- return;
- }
- switch (type) {
- case BUDDY_RESETALL_CRAP:
- buddyControls.textEntryEditID = NAMEKEY_INVALID;
- buddyControls.textEntryEdit = NULL;
- buddyControls.listboxBuddiesID = NAMEKEY_INVALID;
- buddyControls.listboxChatID = NAMEKEY_INVALID;
- buddyControls.listboxBuddies = NULL;
- buddyControls.listboxChat = NULL;
- buddyControls.isInit = FALSE;
- break;
- case BUDDY_WINDOW_BUDDIES:
- buddyControls.textEntryEditID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:TextEntryChat" ) );
- buddyControls.textEntryEdit = TheWindowManager->winGetWindowFromId(NULL, buddyControls.textEntryEditID);
- buddyControls.listboxBuddiesID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:ListboxBuddies" ) );
- buddyControls.listboxChatID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:ListboxBuddyChat" ) );
- buddyControls.listboxBuddies = TheWindowManager->winGetWindowFromId( NULL, buddyControls.listboxBuddiesID );
- buddyControls.listboxChat = TheWindowManager->winGetWindowFromId( NULL, buddyControls.listboxChatID);
- GadgetTextEntrySetText(buddyControls.textEntryEdit, UnicodeString.TheEmptyString);
- buddyControls.isInit = TRUE;
- break;
- case BUDDY_WINDOW_DIPLOMACY:
- buddyControls.textEntryEditID = TheNameKeyGenerator->nameToKey( AsciiString( "Diplomacy.wnd:TextEntryChat" ) );
- buddyControls.textEntryEdit = TheWindowManager->winGetWindowFromId(NULL, buddyControls.textEntryEditID);
- buddyControls.listboxBuddiesID = TheNameKeyGenerator->nameToKey( AsciiString( "Diplomacy.wnd:ListboxBuddies" ) );
- buddyControls.listboxChatID = TheNameKeyGenerator->nameToKey( AsciiString( "Diplomacy.wnd:ListboxBuddyChat" ) );
- buddyControls.listboxBuddies = TheWindowManager->winGetWindowFromId( NULL, buddyControls.listboxBuddiesID );
- buddyControls.listboxChat = TheWindowManager->winGetWindowFromId( NULL, buddyControls.listboxChatID);
- GadgetTextEntrySetText(buddyControls.textEntryEdit, UnicodeString.TheEmptyString);
- buddyControls.isInit = TRUE;
- break;
- case BUDDY_WINDOW_WELCOME_SCREEN:
- break;
- default:
- DEBUG_ASSERTCRASH(FALSE, ("Well, you really shouldn't have gotten here, if you really care about GUI Bugs, search for this string, you you don't care, call chris (who probably doesn't care either"));
- }
-
-}
-
-WindowMsgHandledType BuddyControlSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2)
-{
- if(!TheGameSpyInfo || TheGameSpyInfo->getLocalProfileID() == 0 || !buddyControls.isInit)
- {
- return MSG_IGNORED;
- }
-
- switch( msg )
- {
- case GLM_RIGHT_CLICKED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if( controlID == buddyControls.listboxBuddiesID )
- {
- RightClickStruct *rc = (RightClickStruct *)mData2;
- WindowLayout *rcLayout;
- if(rc->pos < 0)
- break;
-
- GPProfile profileID = (GPProfile)GadgetListBoxGetItemData(control, rc->pos, 0);
- RCItemType itemType = (RCItemType)(Int)GadgetListBoxGetItemData(control, rc->pos, 1);
- UnicodeString nick = GadgetListBoxGetText(control, rc->pos);
-
- GadgetListBoxSetSelected(control, rc->pos);
- if (itemType == ITEM_BUDDY)
- rcLayout = TheWindowManager->winCreateLayout(AsciiString("Menus/RCBuddiesMenu.wnd"));
- else if (itemType == ITEM_REQUEST)
- rcLayout = TheWindowManager->winCreateLayout(AsciiString("Menus/RCBuddyRequestMenu.wnd"));
- else
- rcLayout = TheWindowManager->winCreateLayout(AsciiString("Menus/RCNonBuddiesMenu.wnd"));
- rcMenu = rcLayout->getFirstWindow();
- rcMenu->winGetLayout()->runInit();
- rcMenu->winBringToTop();
- rcMenu->winHide(FALSE);
-
-
- ICoord2D rcSize, rcPos;
- rcMenu->winGetSize(&rcSize.x, &rcSize.y);
- rcPos.x = rc->mouseX;
- rcPos.y = rc->mouseY;
- if(rc->mouseX + rcSize.x > TheDisplay->getWidth())
- rcPos.x = TheDisplay->getWidth() - rcSize.x;
- if(rc->mouseY + rcSize.y > TheDisplay->getHeight())
- rcPos.y = TheDisplay->getHeight() - rcSize.y;
- rcMenu->winSetPosition(rcPos.x, rcPos.y);
-
-
- GameSpyRCMenuData *rcData = NEW GameSpyRCMenuData;
- rcData->m_id = profileID;
- rcData->m_nick.translate(nick);
- rcData->m_itemType = itemType;
- setUnignoreText(rcLayout, rcData->m_nick, rcData->m_id);
- rcMenu->winSetUserData((void *)rcData);
- TheWindowManager->winSetLoneWindow(rcMenu);
- }
- else
- return MSG_IGNORED;
- break;
- }
- case GEM_EDIT_DONE:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- if(controlID != buddyControls.textEntryEditID)
- return MSG_IGNORED;
-
- // see if someone's selected
- Int selected = -1;
- GadgetListBoxGetSelected(buddyControls.listboxBuddies, &selected);
- if (selected >= 0)
- {
- GPProfile selectedProfile = (GPProfile)GadgetListBoxGetItemData(buddyControls.listboxBuddies, selected);
- BuddyInfoMap *m = TheGameSpyInfo->getBuddyMap();
- BuddyInfoMap::iterator recipIt = m->find(selectedProfile);
- if (recipIt == m->end())
- break;
-
- DEBUG_LOG(("Trying to send a buddy message to %d.\n", selectedProfile));
- if (TheGameSpyGame && TheGameSpyGame->isInGame() && TheGameSpyGame->isGameInProgress() &&
- !ThePlayerList->getLocalPlayer()->isPlayerActive())
- {
- DEBUG_LOG(("I'm dead - gotta look for cheats.\n"));
- for (Int i=0; igetGameSpySlot(i)->getProfileID()));
- if (TheGameSpyGame->getGameSpySlot(i)->getProfileID() == selectedProfile)
- {
- // can't send to someone in our game if we're dead/observing. security breach and all that. no seances for you.
- if (buddyControls.listboxChat)
- {
- GadgetListBoxAddEntryText( buddyControls.listboxChat, TheGameText->fetch("Buddy:CantTalkToIngameBuddy"),
- GameSpyColor[GSCOLOR_DEFAULT], -1, -1 );
- }
- return MSG_HANDLED;
- }
- }
- }
-
- // read the user's input and clear the entry box
- UnicodeString txtInput;
- txtInput.set(GadgetTextEntryGetText( buddyControls.textEntryEdit ));
- GadgetTextEntrySetText(buddyControls.textEntryEdit, UnicodeString::TheEmptyString);
- txtInput.trim();
- if (!txtInput.isEmpty())
- {
- // Send the message
- BuddyRequest req;
- req.buddyRequestType = BuddyRequest::BUDDYREQUEST_MESSAGE;
- wcsncpy(req.arg.message.text, txtInput.str(), MAX_BUDDY_CHAT_LEN);
- req.arg.message.text[MAX_BUDDY_CHAT_LEN-1] = 0;
- req.arg.message.recipient = selectedProfile;
- TheGameSpyBuddyMessageQueue->addRequest(req);
-
- // save message for future incarnations of the buddy window
- BuddyMessageList *messages = TheGameSpyInfo->getBuddyMessages();
- BuddyMessage message;
- message.m_timestamp = time(NULL);
- message.m_senderID = TheGameSpyInfo->getLocalProfileID();
- message.m_senderNick = TheGameSpyInfo->getLocalBaseName();
- message.m_recipientID = selectedProfile;
- message.m_recipientNick = recipIt->second.m_name;
- message.m_message = UnicodeString(req.arg.message.text);
- messages->push_back(message);
-
- // put message on screen
- insertChat(message);
- }
- }
- else
- {
- // nobody selected. Prompt the user.
- if (buddyControls.listboxChat)
- {
- GadgetListBoxAddEntryText( buddyControls.listboxChat, TheGameText->fetch("Buddy:SelectBuddyToChat"),
- GameSpyColor[GSCOLOR_DEFAULT], -1, -1 );
- }
- }
- break;
- }
- default:
- return MSG_IGNORED;
- }
- return MSG_HANDLED;
-}
-
-
-static void insertChat( BuddyMessage msg )
-{
- if (buddyControls.listboxChat)
- {
- BuddyInfoMap *m = TheGameSpyInfo->getBuddyMap();
- BuddyInfoMap::iterator senderIt = m->find(msg.m_senderID);
- BuddyInfoMap::iterator recipientIt = m->find(msg.m_recipientID);
- Bool localSender = (msg.m_senderID == TheGameSpyInfo->getLocalProfileID());
- UnicodeString s;
- //UnicodeString timeStr = UnicodeString(_wctime( (const time_t *)&msg.m_timestamp ));
- UnicodeString timeStr;
- if (localSender /*&& recipientIt != m->end()*/)
- {
- s.format(L"[%hs -> %hs] %s", TheGameSpyInfo->getLocalBaseName().str(), msg.m_recipientNick.str(), msg.m_message.str());
- Int index = GadgetListBoxAddEntryText( buddyControls.listboxChat, s, GameSpyColor[GSCOLOR_PLAYER_SELF], -1, -1 );
- GadgetListBoxAddEntryText( buddyControls.listboxChat, timeStr, GameSpyColor[GSCOLOR_PLAYER_SELF], index, 1);
- }
- else if (!localSender /*&& senderIt != m->end()*/)
- {
- if (!msg.m_senderID)
- {
- s = msg.m_message;
- Int index = GadgetListBoxAddEntryText( buddyControls.listboxChat, s, GameSpyColor[GSCOLOR_DEFAULT], -1, -1 );
- GadgetListBoxAddEntryText( buddyControls.listboxChat, timeStr, GameSpyColor[GSCOLOR_DEFAULT], index, 1);
- }
- else
- {
- s.format(L"[%hs] %s", msg.m_senderNick.str(), msg.m_message.str());
- Int index = GadgetListBoxAddEntryText( buddyControls.listboxChat, s, GameSpyColor[GSCOLOR_PLAYER_BUDDY], -1, -1 );
- GadgetListBoxAddEntryText( buddyControls.listboxChat, timeStr, GameSpyColor[GSCOLOR_PLAYER_BUDDY], index, 1);
- }
- }
- }
-}
-
-void updateBuddyInfo( void )
-{
- if (!TheGameSpyBuddyMessageQueue->isConnected())
- {
- GadgetListBoxReset(buddyControls.listboxBuddies);
- return;
- }
-
- if (!buddyControls.isInit)
- return;
-
- int selected;
- GPProfile selectedProfile = 0;
- int visiblePos = GadgetListBoxGetTopVisibleEntry(buddyControls.listboxBuddies);
-
- GadgetListBoxGetSelected(buddyControls.listboxBuddies, &selected);
- if (selected >= 0)
- selectedProfile = (GPProfile)GadgetListBoxGetItemData(buddyControls.listboxBuddies, selected);
-
- selected = -1;
- GadgetListBoxReset(buddyControls.listboxBuddies);
-
- // Add buddies
- BuddyInfoMap *buddies = TheGameSpyInfo->getBuddyMap();
- BuddyInfoMap::iterator bIt;
- for (bIt = buddies->begin(); bIt != buddies->end(); ++bIt)
- {
- BuddyInfo info = bIt->second;
- GPProfile profileID = bIt->first;
-
- // insert name into box
- UnicodeString formatStr;
- formatStr.translate(info.m_name.str());//, info.m_status, info.m_statusString.str(), info.m_locationString.str());
- Color nameColor = (TheGameSpyInfo->isSavedIgnored(profileID)) ?
- GameSpyColor[GSCOLOR_PLAYER_IGNORED] : GameSpyColor[GSCOLOR_PLAYER_BUDDY];
- int index = GadgetListBoxAddEntryText(buddyControls.listboxBuddies, formatStr, nameColor, -1, -1);
-
- // insert status into box
- AsciiString marker;
- marker.format("Buddy:%ls", info.m_statusString.str());
- if (!info.m_statusString.compareNoCase(L"Offline") ||
- !info.m_statusString.compareNoCase(L"Online") ||
- !info.m_statusString.compareNoCase(L"Matching"))
- {
- formatStr = TheGameText->fetch(marker);
- }
- else if (!info.m_statusString.compareNoCase(L"Staging") ||
- !info.m_statusString.compareNoCase(L"Loading") ||
- !info.m_statusString.compareNoCase(L"Playing"))
- {
- formatStr.format(TheGameText->fetch(marker), info.m_locationString.str());
- }
- else if (!info.m_statusString.compareNoCase(L"Chatting"))
- {
- UnicodeString roomName;
- GroupRoomMap::iterator gIt = TheGameSpyInfo->getGroupRoomList()->find( _wtoi(info.m_locationString.str()) );
- if (gIt != TheGameSpyInfo->getGroupRoomList()->end())
- {
- AsciiString s;
- s.format("GUI:%s", gIt->second.m_name.str());
- roomName = TheGameText->fetch(s);
- }
- formatStr.format(TheGameText->fetch(marker), roomName.str());
- }
- else
- {
- formatStr = info.m_statusString;
- }
- GadgetListBoxAddEntryText(buddyControls.listboxBuddies, formatStr, GameSpyColor[GSCOLOR_DEFAULT], index, 1);
- GadgetListBoxSetItemData(buddyControls.listboxBuddies, (void *)(profileID), index, 0 );
- GadgetListBoxSetItemData(buddyControls.listboxBuddies, (void *)(ITEM_BUDDY), index, 1 );
-
- if (profileID == selectedProfile)
- selected = index;
- }
-
- // add requests
- buddies = TheGameSpyInfo->getBuddyRequestMap();
- for (bIt = buddies->begin(); bIt != buddies->end(); ++bIt)
- {
- BuddyInfo info = bIt->second;
- GPProfile profileID = bIt->first;
-
- // insert name into box
- UnicodeString formatStr;
- formatStr.translate(info.m_name.str());
- int index = GadgetListBoxAddEntryText(buddyControls.listboxBuddies, formatStr, GameSpyColor[GSCOLOR_DEFAULT], -1, -1);
- GadgetListBoxSetItemData(buddyControls.listboxBuddies, (void *)(profileID), index, 0 );
-
- // insert status into box
- formatStr = TheGameText->fetch("GUI:BuddyAddReq");
- GadgetListBoxAddEntryText(buddyControls.listboxBuddies, formatStr, GameSpyColor[GSCOLOR_DEFAULT], index, 1);
- GadgetListBoxSetItemData(buddyControls.listboxBuddies, (void *)(ITEM_REQUEST), index, 1 );
-
- if (profileID == selectedProfile)
- selected = index;
- }
-
-
- // select the same guy
- if (selected >= 0)
- {
- GadgetListBoxSetSelected(buddyControls.listboxBuddies, selected);
- }
-
- // view the same spot
- GadgetListBoxSetTopVisibleEntry(buddyControls.listboxBuddies, visiblePos);
-}
-
-void HandleBuddyResponses( void )
-{
- if (TheGameSpyBuddyMessageQueue)
- {
- BuddyResponse resp;
- if (TheGameSpyBuddyMessageQueue->getResponse( resp ))
- {
- switch (resp.buddyResponseType)
- {
- case BuddyResponse::BUDDYRESPONSE_LOGIN:
- {
- deleteNotificationBox();
- }
- break;
- case BuddyResponse::BUDDYRESPONSE_DISCONNECT:
- {
- lastNotificationWasStatus = FALSE;
- numOnlineInNotification = 0;
- showNotificationBox(AsciiString::TheEmptyString, TheGameText->fetch("Buddy:MessageDisconnected"));
- }
- break;
- case BuddyResponse::BUDDYRESPONSE_MESSAGE:
- {
- if ( !wcscmp(resp.arg.message.text, L"I have authorized your request to add me to your list") )
- break;
-
- if (TheGameSpyInfo->isSavedIgnored(resp.profile))
- {
- //DEBUG_CRASH(("Player is ignored!\n"));
- break; // no buddy messages from ignored people
- }
-
- // save message for future incarnations of the buddy window
- BuddyMessageList *messages = TheGameSpyInfo->getBuddyMessages();
- BuddyMessage message;
- message.m_timestamp = resp.arg.message.date;
- message.m_senderID = resp.profile;
- message.m_recipientID = TheGameSpyInfo->getLocalProfileID();
- message.m_recipientNick = TheGameSpyInfo->getLocalBaseName();
- message.m_message = resp.arg.message.text;
- // insert status into box
- BuddyInfoMap *m = TheGameSpyInfo->getBuddyMap();
- BuddyInfoMap::iterator senderIt = m->find(message.m_senderID);
- AsciiString nick;
- if (senderIt != m->end())
- nick = senderIt->second.m_name.str();
- else
- nick = resp.arg.message.nick;
- message.m_senderNick = nick;
- messages->push_back(message);
-
- DEBUG_LOG(("Inserting buddy chat from '%s'/'%s'\n", nick.str(), resp.arg.message.nick));
-
- // put message on screen
- insertChat(message);
-
- // play audio notification
- AudioEventRTS buddyMsgAudio("GUIMessageReceived");
- if( TheAudio )
- {
- TheAudio->addAudioEvent( &buddyMsgAudio );
- } // end if
-
- UnicodeString snippet = message.m_message;
- while (snippet.getLength() > 11)
- {
- snippet.removeLastChar();
- }
- UnicodeString s;
- s.format(TheGameText->fetch("Buddy:MessageNotification"), nick.str(), snippet.str());
- lastNotificationWasStatus = FALSE;
- numOnlineInNotification = 0;
- showNotificationBox(AsciiString::TheEmptyString, s);
- }
- break;
- case BuddyResponse::BUDDYRESPONSE_REQUEST:
- {
- // save request for future incarnations of the buddy window
- BuddyInfoMap *m = TheGameSpyInfo->getBuddyRequestMap();
- BuddyInfo info;
- info.m_countryCode = resp.arg.request.countrycode;
- info.m_email = resp.arg.request.email;
- info.m_name = resp.arg.request.nick;
- info.m_id = resp.profile;
- info.m_status = (GPEnum)0;
- info.m_statusString = resp.arg.request.text;
- (*m)[resp.profile] = info;
-
- // TODO: put request on screen
- updateBuddyInfo();
- // insert status into box
- lastNotificationWasStatus = FALSE;
- numOnlineInNotification = 0;
- showNotificationBox(info.m_name, TheGameText->fetch("Buddy:AddNotification"));
- }
- break;
- case BuddyResponse::BUDDYRESPONSE_STATUS:
- {
- BuddyInfoMap *m = TheGameSpyInfo->getBuddyMap();
- BuddyInfoMap::const_iterator bit = m->find(resp.profile);
- Bool seenPreviously = FALSE;
- GPEnum oldStatus = GP_OFFLINE;
- GPEnum newStatus = resp.arg.status.status;
- if (bit != m->end())
- {
- seenPreviously = TRUE;
- oldStatus = (*m)[resp.profile].m_status;
- }
- BuddyInfo info;
- info.m_countryCode = resp.arg.status.countrycode;
- info.m_email = resp.arg.status.email;
- info.m_name = resp.arg.status.nick;
- info.m_id = resp.profile;
- info.m_status = newStatus;
- info.m_statusString = UnicodeString(MultiByteToWideCharSingleLine(resp.arg.status.statusString).c_str());
- info.m_locationString = UnicodeString(MultiByteToWideCharSingleLine(resp.arg.status.location).c_str());
- (*m)[resp.profile] = info;
-
- updateBuddyInfo();
- PopulateLobbyPlayerListbox();
- RefreshGameListBoxes();
- if ( (newStatus == GP_OFFLINE && seenPreviously) ||
- (newStatus == GP_ONLINE && (oldStatus == GP_OFFLINE || !seenPreviously)) )
- //if (!info.m_statusString.compareNoCase(L"Offline") ||
- //!info.m_statusString.compareNoCase(L"Online"))
- {
- // insert status into box
- AsciiString marker;
- marker.format("Buddy:%lsNotification", info.m_statusString.str());
-
- lastNotificationWasStatus = TRUE;
- if (newStatus != GP_OFFLINE)
- ++numOnlineInNotification;
-
- showNotificationBox(info.m_name, TheGameText->fetch(marker));
- }
- else if( newStatus == GP_RECV_GAME_INVITE && !seenPreviously)
- {
- lastNotificationWasStatus = TRUE;
- if (newStatus != GP_OFFLINE)
- ++numOnlineInNotification;
-
- showNotificationBox(info.m_name, TheGameText->fetch("Buddy:OnlineNotification"));
- }
- }
- break;
- }
- }
- }
- else
- {
- DEBUG_CRASH(("No buddy message queue!\n"));
- }
- if(noticeLayout && timeGetTime() > noticeExpires)
- {
- deleteNotificationBox();
- }
-}
-
-void showNotificationBox( AsciiString nick, UnicodeString message)
-{
-// if(!GameSpyIsOverlayOpen(GSOVERLAY_BUDDY))
-// return;
- if( !noticeLayout )
- noticeLayout = TheWindowManager->winCreateLayout( "Menus/PopupBuddyListNotification.wnd" );
- noticeLayout->hide( FALSE );
- if (buttonNotificationID == NAMEKEY_INVALID)
- {
- buttonNotificationID = TheNameKeyGenerator->nameToKey("PopupBuddyListNotification.wnd:ButtonNotification");
- }
- GameWindow *win = TheWindowManager->winGetWindowFromId(NULL,buttonNotificationID);
- if(!win)
- {
- deleteNotificationBox();
- return;
- }
-
- if (lastNotificationWasStatus && numOnlineInNotification > 1)
- {
- message = TheGameText->fetch("Buddy:MultipleOnlineNotification");
- }
-
- if (nick.isNotEmpty())
- message.format(message, nick.str());
- GadgetButtonSetText(win, message);
- //GadgetStaticTextSetText(win, message);
- noticeExpires = timeGetTime() + NOTIFICATION_EXPIRES;
- noticeLayout->bringForward();
-
- AudioEventRTS buttonClick("GUICommunicatorIncoming");
-
- if( TheAudio )
- {
- TheAudio->addAudioEvent( &buttonClick );
- } // end if
-
-}
-
-void deleteNotificationBox( void )
-{
- lastNotificationWasStatus = FALSE;
- numOnlineInNotification = 0;
- if(noticeLayout)
- {
- noticeLayout->destroyWindows();
- noticeLayout->deleteInstance();
- noticeLayout = NULL;
- }
-}
-
-void PopulateOldBuddyMessages(void)
-{
- // show previous messages
- BuddyMessageList *messages = TheGameSpyInfo->getBuddyMessages();
- for (BuddyMessageList::iterator mIt = messages->begin(); mIt != messages->end(); ++mIt)
- {
- BuddyMessage message = *mIt;
- insertChat(message);
- }
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the WOL Buddy Overlay */
-//-------------------------------------------------------------------------------------------------
-void WOLBuddyOverlayInit( WindowLayout *layout, void *userData )
-{
- parentID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:BuddyMenuParent" ) );
- buttonHideID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:ButtonHide" ) );
- buttonAddBuddyID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:ButtonAdd" ) );
- buttonDeleteBuddyID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:ButtonDelete" ) );
- //textEntryID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:TextEntryChat" ) );
- //listboxBuddyID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:ListboxBuddies" ) );
- //listboxChatID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:ListboxBuddyChat" ) );
- buttonAcceptBuddyID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:ButtonYes" ) );
- buttonDenyBuddyID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:ButtonNo" ) );
- radioButtonBuddiesID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:RadioButtonBuddies" ) );
- radioButtonIgnoreID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:RadioButtonIgnore" ) );
- parentBuddiesID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:BuddiesParent" ) );
- parentIgnoreID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:IgnoreParent" ) );
- listboxIgnoreID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:ListboxIgnore" ) );
-
-
- parent = TheWindowManager->winGetWindowFromId( NULL, parentID );
- buttonHide = TheWindowManager->winGetWindowFromId( parent, buttonHideID);
- buttonAddBuddy = TheWindowManager->winGetWindowFromId( parent, buttonAddBuddyID);
- buttonDeleteBuddy = TheWindowManager->winGetWindowFromId( parent, buttonDeleteBuddyID);
- // textEntry = TheWindowManager->winGetWindowFromId( parent, textEntryID);
- //listboxBuddy = TheWindowManager->winGetWindowFromId( parent, listboxBuddyID);
- //listboxChat = TheWindowManager->winGetWindowFromId( parent, listboxChatID);
- buttonAcceptBuddy = TheWindowManager->winGetWindowFromId( parent, buttonAcceptBuddyID);
- buttonDenyBuddy = TheWindowManager->winGetWindowFromId( parent, buttonDenyBuddyID);
- radioButtonBuddies = TheWindowManager->winGetWindowFromId( parent, radioButtonBuddiesID);
- radioButtonIgnore = TheWindowManager->winGetWindowFromId( parent, radioButtonIgnoreID);
- parentBuddies = TheWindowManager->winGetWindowFromId( parent, parentBuddiesID);
- parentIgnore = TheWindowManager->winGetWindowFromId( parent, parentIgnoreID);
- listboxIgnore = TheWindowManager->winGetWindowFromId( parent, listboxIgnoreID);
-
- InitBuddyControls(BUDDY_WINDOW_BUDDIES);
-
- GadgetRadioSetSelection(radioButtonBuddies,FALSE);
- parentBuddies->winHide(FALSE);
- parentIgnore->winHide(TRUE);
-
- //GadgetTextEntrySetText(textEntry, UnicodeString.TheEmptyString);
-
- PopulateOldBuddyMessages();
-
- // Show Menu
- layout->hide( FALSE );
-
- // Set Keyboard to Main Parent
- TheWindowManager->winSetFocus( parent );
-
- isOverlayActive = true;
- updateBuddyInfo();
-
-} // WOLBuddyOverlayInit
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Buddy Overlay shutdown method */
-//-------------------------------------------------------------------------------------------------
-void WOLBuddyOverlayShutdown( WindowLayout *layout, void *userData )
-{
- listboxIgnore = NULL;
-
- // hide menu
- layout->hide( TRUE );
-
- // our shutdown is complete
- //TheShell->shutdownComplete( layout );
-
- isOverlayActive = false;
-
- InitBuddyControls(BUDDY_RESETALL_CRAP);
-
-} // WOLBuddyOverlayShutdown
-
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Buddy Overlay update method */
-//-------------------------------------------------------------------------------------------------
-void WOLBuddyOverlayUpdate( WindowLayout * layout, void *userData)
-{
- if (!TheGameSpyBuddyMessageQueue || !TheGameSpyBuddyMessageQueue->isConnected())
- GameSpyCloseOverlay(GSOVERLAY_BUDDY);
-}// WOLBuddyOverlayUpdate
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Buddy Overlay input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLBuddyOverlayInput( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
- UnsignedByte key = mData1;
- UnsignedByte state = mData2;
-
- switch( key )
- {
-
- // ----------------------------------------------------------------------------------------
- case KEY_ESC:
- {
-
- //
- // send a simulated selected event to the parent window of the
- // back/exit button
- //
- if( BitTest( state, KEY_STATE_UP ) )
- {
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)buttonHide, buttonHideID );
-
- } // end if
-
- // don't let key fall through anywhere else
- return MSG_HANDLED;
-
- } // end escape
-
- } // end switch( key )
-
- } // end char
-
- } // end switch( msg )
-
- return MSG_IGNORED;
-}// WOLBuddyOverlayInput
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Buddy Overlay window system callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLBuddyOverlaySystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- UnicodeString txtInput;
- if(BuddyControlSystem(window, msg, mData1, mData2) == MSG_HANDLED)
- {
- return MSG_HANDLED;
- }
- switch( msg )
- {
-
-
- case GWM_CREATE:
- {
-
- break;
- } // case GWM_DESTROY:
-
- case GWM_DESTROY:
- {
- break;
- } // case GWM_DESTROY:
-
- case GWM_INPUT_FOCUS:
- {
- // if we're givin the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
-
- return MSG_HANDLED;
- }//case GWM_INPUT_FOCUS:
- case GLM_RIGHT_CLICKED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if( controlID == listboxIgnoreID )
- {
- RightClickStruct *rc = (RightClickStruct *)mData2;
- WindowLayout *rcLayout;
- if(rc->pos < 0)
- break;
-
- Bool isBuddy = false, isRequest = false;
- GPProfile profileID = (GPProfile)GadgetListBoxGetItemData(control, rc->pos);
- UnicodeString nick = GadgetListBoxGetText(control, rc->pos);
- BuddyInfoMap *buddies = TheGameSpyInfo->getBuddyMap();
- BuddyInfoMap::iterator bIt;
- bIt = buddies->find(profileID);
- if (bIt != buddies->end())
- {
- isBuddy = true;
- }
- else
- {
- buddies = TheGameSpyInfo->getBuddyRequestMap();
- bIt = buddies->find(profileID);
- if (bIt != buddies->end())
- {
- isRequest = true;
- }
- else
- {
- // neither buddy nor request
- //break;
- }
- }
-
- GadgetListBoxSetSelected(control, rc->pos);
- if (isBuddy)
- rcLayout = TheWindowManager->winCreateLayout(AsciiString("Menus/RCBuddiesMenu.wnd"));
- else if (isRequest)
- rcLayout = TheWindowManager->winCreateLayout(AsciiString("Menus/RCBuddyRequestMenu.wnd"));
- else
- rcLayout = TheWindowManager->winCreateLayout(AsciiString("Menus/RCNonBuddiesMenu.wnd"));
- rcMenu = rcLayout->getFirstWindow();
- rcMenu->winGetLayout()->runInit();
- rcMenu->winBringToTop();
- rcMenu->winHide(FALSE);
-
-
-
- rcMenu->winSetPosition(rc->mouseX, rc->mouseY);
- GameSpyRCMenuData *rcData = NEW GameSpyRCMenuData;
- rcData->m_id = profileID;
- rcData->m_nick.translate(nick);
- rcData->m_itemType = (isBuddy)?ITEM_BUDDY:((isRequest)?ITEM_REQUEST:ITEM_NONBUDDY);
- setUnignoreText(rcLayout, rcData->m_nick, rcData->m_id);
- rcMenu->winSetUserData((void *)rcData);
- TheWindowManager->winSetLoneWindow(rcMenu);
- }
- break;
- }
- case GBM_SELECTED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if (controlID == buttonHideID)
- {
- GameSpyCloseOverlay( GSOVERLAY_BUDDY );
- }
- else if (controlID == radioButtonBuddiesID)
- {
- parentBuddies->winHide(FALSE);
- parentIgnore->winHide(TRUE);
- }
- else if (controlID == radioButtonIgnoreID)
- {
- parentBuddies->winHide(TRUE);
- parentIgnore->winHide(FALSE);
- refreshIgnoreList();
- }
- else if (controlID == buttonAddBuddyID)
- {
- /*
- UnicodeString uName = GadgetTextEntryGetText(textEntry);
- AsciiString aName;
- aName.translate(uName);
- if (!aName.isEmpty())
- {
- TheWOLBuddyList->requestBuddyAdd(aName);
- }
- GadgetTextEntrySetText(textEntry, UnicodeString::TheEmptyString);
- */
- }
- else if (controlID == buttonDeleteBuddyID)
- {
- /*
- int selected;
- AsciiString selectedName = AsciiString::TheEmptyString;
-
- GadgetListBoxGetSelected(listbox, &selected);
- if (selected >= 0)
- selectedName = TheNameKeyGenerator->keyToName((NameKeyType)(int)GadgetListBoxGetItemData(listbox, selected));
-
- if (!selectedName.isEmpty())
- {
- TheWOLBuddyList->requestBuddyDelete(selectedName);
- }
- */
- }
- break;
- }// case GBM_SELECTED:
- case GLM_DOUBLE_CLICKED:
- {
- /*
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- if( controlID == listboxBuddyID )
- {
- int rowSelected = mData2;
-
- if (rowSelected >= 0)
- {
- UnicodeString buddyName;
- GameWindow *listboxWindow = TheWindowManager->winGetWindowFromId( parent, listboxBuddyID );
-
- // get text of buddy name
- buddyName = GadgetListBoxGetText( listboxWindow, rowSelected,0 );
- GPProfile buddyID = (GPProfile)GadgetListBoxGetItemData( listboxWindow, rowSelected, 0 );
-
- Int index = -1;
- gpGetBuddyIndex(TheGPConnection, buddyID, &index);
- if (index >= 0)
- {
- GPBuddyStatus status;
- gpGetBuddyStatus(TheGPConnection, rowSelected, &status);
-
- UnicodeString string;
- string.format(L"To join %s in %hs:", buddyName.str(), status.locationString);
- GameSpyAddText(string, GSCOLOR_DEFAULT);
-
- if (status.status == GP_CHATTING)
- {
- AsciiString location = status.locationString;
- AsciiString val;
- location.nextToken(&val, "/");
- location.nextToken(&val, "/");
- location.nextToken(&val, "/");
-
- string.format(L" ???");
- if (!val.isEmpty())
- {
- Int groupRoom = atoi(val.str());
- if (TheGameSpyChat->getCurrentGroupRoomID() == groupRoom)
- {
- // already there
- string.format(L" nothing");
- GameSpyAddText(string, GSCOLOR_DEFAULT);
- }
- else
- {
- GroupRoomMap *rooms = TheGameSpyChat->getGroupRooms();
- if (rooms)
- {
- Bool needToJoin = true;
- GroupRoomMap::iterator it = rooms->find(groupRoom);
- if (it != rooms->end())
- {
- // he's in a different room
- if (TheGameSpyChat->getCurrentGroupRoomID())
- {
- string.format(L" leave group room");
- GameSpyAddText(string, GSCOLOR_DEFAULT);
-
- TheGameSpyChat->leaveRoom(GroupRoom);
- }
- else if (TheGameSpyGame->isInGame())
- {
- if (TheGameSpyGame->isGameInProgress())
- {
- string.format(L" can't leave game in progress");
- GameSpyAddText(string, GSCOLOR_DEFAULT);
- needToJoin = false;
- }
- else
- {
- string.format(L" leave game setup");
- GameSpyAddText(string, GSCOLOR_DEFAULT);
-
- TheGameSpyChat->leaveRoom(StagingRoom);
- TheGameSpyGame->leaveGame();
- }
- }
- if (needToJoin)
- {
- string.format(L" join lobby %d", groupRoom);
- TheGameSpyChat->joinGroupRoom(groupRoom);
- GameSpyAddText(string, GSCOLOR_DEFAULT);
- }
- }
- }
- }
- }
- }
- }
- else
- {
- DEBUG_CRASH(("No buddy associated with that ProfileID"));
- GameSpyUpdateBuddyOverlay();
- }
- }
- }
- */
- break;
- }
-
- default:
- return MSG_IGNORED;
-
- }//Switch
-
- return MSG_HANDLED;
-}// WOLBuddyOverlaySystem
-
-WindowMsgHandledType PopupBuddyNotificationSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- switch( msg )
- {
- case GWM_CREATE:
- {
- break;
- } // case GWM_DESTROY:
-
- case GWM_DESTROY:
- {
- break;
- } // case GWM_DESTROY:
-
- case GBM_SELECTED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if (controlID == buttonNotificationID)
- {
- GameSpyOpenOverlay( GSOVERLAY_BUDDY );
- }
- break;
- }
-
- default:
- return MSG_IGNORED;
-
- }//Switch
-
- return MSG_HANDLED;
-}// PopupBuddyNotificationSystem
-
-/*
-static NameKeyType buttonAcceptBuddyID = NAMEKEY_INVALID;
-static NameKeyType buttonDenyBuddyID = NAMEKEY_INVALID;
-*/
-static NameKeyType buttonAddID = NAMEKEY_INVALID;
-static NameKeyType buttonDeleteID = NAMEKEY_INVALID;
-static NameKeyType buttonPlayID = NAMEKEY_INVALID;
-static NameKeyType buttonIgnoreID = NAMEKEY_INVALID;
-static NameKeyType buttonStatsID = NAMEKEY_INVALID;
-// Window Pointers ------------------------------------------------------------------------
-//static GameWindow *rCparent = NULL;
-
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Buddy Overlay Right Click menu callbacks */
-//-------------------------------------------------------------------------------------------------
-void WOLBuddyOverlayRCMenuInit( WindowLayout *layout, void *userData )
-{
- AsciiString controlName;
- controlName.format("%s:ButtonAdd",layout->getFilename().str()+6);
- buttonAddID = TheNameKeyGenerator->nameToKey( controlName );
- controlName.format("%s:ButtonDelete",layout->getFilename().str()+6);
- buttonDeleteID = TheNameKeyGenerator->nameToKey( controlName );
- controlName.format("%s:ButtonPlay",layout->getFilename().str()+6);
- buttonPlayID = TheNameKeyGenerator->nameToKey( controlName );
- controlName.format("%s:ButtonIgnore",layout->getFilename().str()+6);
- buttonIgnoreID = TheNameKeyGenerator->nameToKey( controlName );
- controlName.format("%s:ButtonStats",layout->getFilename().str()+6);
- buttonStatsID = TheNameKeyGenerator->nameToKey( controlName );
-}
-static void closeRightClickMenu(GameWindow *win)
-{
-
- if(win)
- {
- WindowLayout *winLay = win->winGetLayout();
- if(!winLay)
- return;
- winLay->destroyWindows();
- winLay->deleteInstance();
- winLay = NULL;
-
- }
-}
-
-void RequestBuddyAdd(Int profileID, AsciiString nick)
-{
- // request to add a buddy
- BuddyRequest req;
- req.buddyRequestType = BuddyRequest::BUDDYREQUEST_ADDBUDDY;
- req.arg.addbuddy.id = profileID;
- UnicodeString buddyAddstr;
- buddyAddstr = TheGameText->fetch("GUI:BuddyAddReq");
- wcsncpy(req.arg.addbuddy.text, buddyAddstr.str(), MAX_BUDDY_CHAT_LEN);
- req.arg.addbuddy.text[MAX_BUDDY_CHAT_LEN-1] = 0;
- TheGameSpyBuddyMessageQueue->addRequest(req);
-
- UnicodeString s;
- Bool exists = TRUE;
- s.format(TheGameText->fetch("Buddy:InviteSent", &exists));
- if (!exists)
- {
- // no string yet. don't display.
- return;
- }
-
- // save message for future incarnations of the buddy window
- BuddyMessageList *messages = TheGameSpyInfo->getBuddyMessages();
- BuddyMessage message;
- message.m_timestamp = time(NULL);
- message.m_senderID = 0;
- message.m_senderNick = "";
- message.m_recipientID = TheGameSpyInfo->getLocalProfileID();
- message.m_recipientNick = TheGameSpyInfo->getLocalBaseName();
- message.m_message.format(TheGameText->fetch("Buddy:InviteSentToPlayer"), nick.str());
-
- // insert status into box
- messages->push_back(message);
-
- DEBUG_LOG(("Inserting buddy add request\n"));
-
- // put message on screen
- insertChat(message);
-
- // play audio notification
- AudioEventRTS buddyMsgAudio("GUIMessageReceived");
- if( TheAudio )
- {
- TheAudio->addAudioEvent( &buddyMsgAudio );
- } // end if
-
- lastNotificationWasStatus = FALSE;
- numOnlineInNotification = 0;
- showNotificationBox(AsciiString::TheEmptyString, s);
-}
-
-WindowMsgHandledType WOLBuddyOverlayRCMenuSystem( GameWindow *window, UnsignedInt msg, WindowMsgData mData1, WindowMsgData mData2 )
-{
-
- switch( msg )
- {
-
- case GWM_CREATE:
- {
-
- break;
- } // case GWM_DESTROY:
-
- case GWM_DESTROY:
- {
- rcMenu = NULL;
- break;
- } // case GWM_DESTROY:
-
- case GGM_CLOSE:
- {
- closeRightClickMenu(window);
- //rcMenu = NULL;
- break;
- }
-
-
- case GBM_SELECTED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- GameSpyRCMenuData *rcData = (GameSpyRCMenuData*)window->winGetUserData();
- if(!rcData)
- break;
- DEBUG_ASSERTCRASH(rcData, ("WOLBuddyOverlayRCMenuSystem GBM_SELECTED:: we're attempting to read the GameSpyRCMenuData from the window, but the data's not there"));
- GPProfile profileID = rcData->m_id;
- AsciiString nick = rcData->m_nick;
-
- Bool isBuddy = false, isRequest = false;
- Bool isGameSpyUser = profileID > 0;
- if (rcData->m_itemType == ITEM_BUDDY)
- isBuddy = TRUE;
- else if (rcData->m_itemType == ITEM_REQUEST)
- isRequest = TRUE;
-
- if(rcData)
- {
- delete rcData;
- rcData = NULL;
- }
- window->winSetUserData(NULL);
- //DEBUG_ASSERTCRASH(profileID > 0, ("Bad profile ID in user data!"));
-
- if( controlID == buttonAddID )
- {
- if(!isGameSpyUser)
- break;
- DEBUG_LOG(("ButtonAdd was pushed\n"));
- if (isRequest)
- {
- // ok the request
- BuddyRequest req;
- req.buddyRequestType = BuddyRequest::BUDDYREQUEST_OKADD;
- req.arg.profile.id = profileID;
- TheGameSpyBuddyMessageQueue->addRequest(req);
-
- BuddyInfoMap *m = TheGameSpyInfo->getBuddyRequestMap();
- m->erase( profileID );
-
- // DONT CHECK IN UNTIL MATT HAS REVIEWED
- // if the profile ID is not from a buddy and we're okaying his request, then
- // request to add him to our list automatically CLH 2-18-03
- if(!TheGameSpyInfo->isBuddy(profileID))
- {
- RequestBuddyAdd(profileID, nick);
- }
- updateBuddyInfo();
-
- }
- else if (!isBuddy)
- {
- RequestBuddyAdd(profileID, nick);
- }
- }
- else if( controlID == buttonDeleteID )
- {
- if(!isGameSpyUser)
- break;
- if (isBuddy)
- {
- // delete the buddy
- BuddyRequest req;
- req.buddyRequestType = BuddyRequest::BUDDYREQUEST_DELBUDDY;
- req.arg.profile.id = profileID;
- TheGameSpyBuddyMessageQueue->addRequest(req);
- }
- else
- {
- // delete the request
- BuddyRequest req;
- req.buddyRequestType = BuddyRequest::BUDDYREQUEST_DENYADD;
- req.arg.profile.id = profileID;
- TheGameSpyBuddyMessageQueue->addRequest(req);
- BuddyInfoMap *m = TheGameSpyInfo->getBuddyRequestMap();
- m->erase( profileID );
- }
- BuddyInfoMap *buddies = (isBuddy)?TheGameSpyInfo->getBuddyMap():TheGameSpyInfo->getBuddyRequestMap();
- buddies->erase(profileID);
- updateBuddyInfo();
- DEBUG_LOG(("ButtonDelete was pushed\n"));
- PopulateLobbyPlayerListbox();
- }
- else if( controlID == buttonPlayID )
- {
- DEBUG_LOG(("buttonPlayID was pushed\n"));
- }
- else if( controlID == buttonIgnoreID )
- {
- DEBUG_LOG(("%s is isGameSpyUser %d", nick.str(), isGameSpyUser));
- if( isGameSpyUser )
- {
- if(TheGameSpyInfo->isSavedIgnored(profileID))
- {
- TheGameSpyInfo->removeFromSavedIgnoreList(profileID);
- }
- else
- {
- TheGameSpyInfo->addToSavedIgnoreList(profileID, nick);
- }
- }
- else
- {
- if(TheGameSpyInfo->isIgnored(nick))
- {
- TheGameSpyInfo->removeFromIgnoreList(nick);
- }
- else
- {
- TheGameSpyInfo->addToIgnoreList(nick);
- }
- }
- updateBuddyInfo();
- refreshIgnoreList();
- // repopulate our player listboxes now
- PopulateLobbyPlayerListbox();
- }
- else if( controlID == buttonStatsID )
- {
- DEBUG_LOG(("buttonStatsID was pushed\n"));
- GameSpyCloseOverlay(GSOVERLAY_PLAYERINFO);
- SetLookAtPlayer(profileID,nick );
- GameSpyOpenOverlay(GSOVERLAY_PLAYERINFO);
- PSRequest req;
- req.requestType = PSRequest::PSREQUEST_READPLAYERSTATS;
- req.player.id = profileID;
- TheGameSpyPSMessageQueue->addRequest(req);
- }
- closeRightClickMenu(window);
- break;
- }
- default:
- return MSG_IGNORED;
-
- }//Switch
- return MSG_HANDLED;
-}
-
-
-void setUnignoreText( WindowLayout *layout, AsciiString nick, GPProfile id)
-{
- AsciiString controlName;
- controlName.format("%s:ButtonIgnore",layout->getFilename().str()+6);
- NameKeyType ID = TheNameKeyGenerator->nameToKey( controlName );
- GameWindow *win = TheWindowManager->winGetWindowFromId(layout->getFirstWindow(), ID);
- if(win)
- {
- if(TheGameSpyInfo->isSavedIgnored(id) || TheGameSpyInfo->isIgnored(nick))
- GadgetButtonSetText(win, TheGameText->fetch("GUI:Unignore"));
- }
-}
-
-void refreshIgnoreList( void )
-{
-
-
- SavedIgnoreMap tempMap;
- tempMap = TheGameSpyInfo->returnSavedIgnoreList();
- SavedIgnoreMap::iterator it = tempMap.begin();
- GadgetListBoxReset(listboxIgnore);
- while(it != tempMap.end())
- {
- UnicodeString name;
- name.translate(it->second);
- Int pos = GadgetListBoxAddEntryText(listboxIgnore, name, GameMakeColor(255,100,100,255),-1);
- GadgetListBoxSetItemData(listboxIgnore, (void *)it->first,pos );
- ++it;
- }
- IgnoreList tempList;
- tempList = TheGameSpyInfo->returnIgnoreList();
- IgnoreList::iterator iListIt = tempList.begin();
- while( iListIt != tempList.end())
- {
- AsciiString aName = *iListIt;
- UnicodeString name;
- name.translate(aName);
- Int pos = GadgetListBoxAddEntryText(listboxIgnore, name, GameMakeColor(255,100,100,255),-1);
- GadgetListBoxSetItemData(listboxIgnore, 0,pos );
- ++iListIt;
- }
-
-//
-// GPProfile profileID = 0;
-// PlayerInfoMap::iterator it = TheGameSpyInfo->getPlayerInfoMap()->find(aName);
-// if (it != TheGameSpyInfo->getPlayerInfoMap()->end())
-// profileID = it->second.m_profileID;
-
-}
diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLCustomScoreScreen.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLCustomScoreScreen.cpp
deleted file mode 100644
index d0bfe524d77..00000000000
--- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLCustomScoreScreen.cpp
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////////////
-// FILE: WOLCustomScoreScreen.cpp
-// Author: Matt Campbell, December 2001
-// Description: Custom match score screen
-///////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Lib/BaseType.h"
-#include "Common/GameEngine.h"
-#include "Common/NameKeyGenerator.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/Shell.h"
-#include "GameClient/KeyDefs.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/GadgetListBox.h"
-#include "GameClient/GadgetTextEntry.h"
-#include "Common/GlobalData.h"
-//#include "GameNetwork/WOL.h"
-//#include "GameNetwork/WOLmenus.h"
-
-
-
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-// window ids ------------------------------------------------------------------------------
-static NameKeyType parentWOLCustomScoreID = NAMEKEY_INVALID;
-static NameKeyType buttonDisconnectID = NAMEKEY_INVALID;
-static NameKeyType buttonLobbyID = NAMEKEY_INVALID;
-
-// Window Pointers ------------------------------------------------------------------------
-static GameWindow *parentWOLCustomScore = NULL;
-static GameWindow *buttonDisconnect = NULL;
-static GameWindow *buttonLobby = NULL;
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the WOL Status Menu */
-//-------------------------------------------------------------------------------------------------
-void WOLCustomScoreScreenInit( WindowLayout *layout, void *userData )
-{
- parentWOLCustomScoreID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLCustomScoreScreen.wnd:WOLCustomScoreScreenParent" ) );
- buttonDisconnectID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLCustomScoreScreen.wnd:ButtonDisconnect" ) );
- buttonLobbyID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLCustomScoreScreen.wnd:ButtonLobby" ) );
- parentWOLCustomScore = TheWindowManager->winGetWindowFromId( NULL, parentWOLCustomScoreID );
- buttonDisconnect = TheWindowManager->winGetWindowFromId( NULL, buttonDisconnectID);
- buttonLobby = TheWindowManager->winGetWindowFromId( NULL, buttonLobbyID);
-
- /*
- if (WOL::TheWOL->getState() == WOL::WOLAPI_FATAL_ERROR)
- {
- // We can get to the score screen even though we've been disconnected. Just hide
- // any buttons that lead back into WOL.
- buttonLobby->winHide( TRUE );
- }
- */
-
- // Show Menu
- layout->hide( FALSE );
-
- // Set Keyboard to Main Parent
- TheWindowManager->winSetFocus( parentWOLCustomScore );
-} // WOLCustomScoreScreenInit
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Status Menu shutdown method */
-//-------------------------------------------------------------------------------------------------
-void WOLCustomScoreScreenShutdown( WindowLayout *layout, void *userData )
-{
- // hide menu
- layout->hide( TRUE );
-
- // our shutdown is complete
- TheShell->shutdownComplete( layout );
-} // WOLCustomScoreScreenShutdown
-
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Status Menu update method */
-//-------------------------------------------------------------------------------------------------
-void WOLCustomScoreScreenUpdate( WindowLayout * layout, void *userData)
-{
- /*
- if (WOL::TheWOL)
- WOL::TheWOL->update();
- */
-}// WOLCustomScoreScreenUpdate
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Status Menu input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLCustomScoreScreenInput( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
- UnsignedByte key = mData1;
- UnsignedByte state = mData2;
-
- switch( key )
- {
-
- // ----------------------------------------------------------------------------------------
- case KEY_ESC:
- {
-
- //
- // send a simulated selected event to the parent window of the
- // back/exit button
- //
- if( BitTest( state, KEY_STATE_UP ) )
- {
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)buttonDisconnect, buttonDisconnectID );
-
- } // end if
-
- // don't let key fall through anywhere else
- return MSG_HANDLED;
-
- } // end escape
-
- } // end switch( key )
-
- } // end char
-
- } // end switch( msg )
-
- return MSG_IGNORED;
-}// WOLCustomScoreScreenInput
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Status Menu window system callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLCustomScoreScreenSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- UnicodeString txtInput;
-
- switch( msg )
- {
-
- case GWM_CREATE:
- {
-
- break;
- } // case GWM_DESTROY:
-
- case GWM_DESTROY:
- {
- break;
- } // case GWM_DESTROY:
-
- case GWM_INPUT_FOCUS:
- {
- // if we're given the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
-
- return MSG_HANDLED;
- }//case GWM_INPUT_FOCUS:
-
- case GBM_SELECTED:
- {
- /*
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if ( controlID == buttonDisconnectID )
- {
- if (WOL::TheWOL->setState( WOL::WOLAPI_FATAL_ERROR ))
- {
- WOL::TheWOL->addCommand( WOL::WOLCOMMAND_RESET ); // don't display an error, log out, or anything
- }
-
- } //if ( controlID == buttonDisconnect )
- else if ( controlID == buttonLobbyID )
- {
- if (WOL::TheWOL->getState() != WOL::WOLAPI_FATAL_ERROR)
- {
- WOL::TheWOL->setScreen(WOL::WOLAPI_MENU_CUSTOMLOBBY);
- WOL::TheWOL->setGameMode(WOL::WOLTYPE_CUSTOM);
- WOL::TheWOL->setState( WOL::WOLAPI_LOBBY );
- WOL::TheWOL->addCommand( WOL::WOLCOMMAND_REFRESH_CHANNELS );
- }
- else
- {
- }
- } //if ( controlID == buttonDisconnect )
- */
- break;
- }// case GBM_SELECTED:
-
- case GEM_EDIT_DONE:
- {
- break;
- }
- default:
- return MSG_IGNORED;
-
- }//Switch
-
- return MSG_HANDLED;
-}// WOLCustomScoreScreenSystem
diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp
deleted file mode 100644
index 81329e4f53a..00000000000
--- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp
+++ /dev/null
@@ -1,2689 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////////////
-// FILE: WOLGameSetupMenu.cpp
-// Author: Matt Campbell, December 2001
-// Description: WOL Game Options Menu
-///////////////////////////////////////////////////////////////////////////////////////
-
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/GameEngine.h"
-#include "Common/GameState.h"
-#include "GameClient/GameText.h"
-#include "Common/MultiplayerSettings.h"
-#include "Common/PlayerTemplate.h"
-#include "Common/CustomMatchPreferences.h"
-#include "GameClient/AnimateWindowManager.h"
-#include "GameClient/InGameUI.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Mouse.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/Shell.h"
-#include "GameClient/KeyDefs.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/GadgetComboBox.h"
-#include "GameClient/GadgetListBox.h"
-#include "GameClient/GadgetTextEntry.h"
-#include "GameClient/GadgetPushButton.h"
-#include "GameClient/GadgetStaticText.h"
-#include "GameClient/MapUtil.h"
-#include "GameClient/EstablishConnectionsMenu.h"
-#include "GameClient/GameWindowTransitions.h"
-
-#include "GameNetwork/GameSpy/BuddyDefs.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpy/PeerThread.h"
-#include "GameNetwork/GameSpy/PersistentStorageDefs.h"
-#include "GameNetwork/GameSpy/PersistentStorageThread.h"
-#include "GameNetwork/GameSpyOverlay.h"
-#include "GameNetwork/NAT.h"
-#include "GameNetwork/GUIUtil.h"
-#include "GameNetwork/GameSpy/GSConfig.h"
-
-void WOLDisplaySlotList( void );
-
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-
-extern std::list TheLobbyQueuedUTMs;
-extern void MapSelectorTooltip(GameWindow *window, WinInstanceData *instData, UnsignedInt mouse);
-
-
-#if defined(_DEBUG) || defined(_INTERNAL)
-extern Bool g_debugSlots;
-void slotListDebugLog(const char *fmt, ...)
-{
- static char buf[1024];
- va_list va;
- va_start( va, fmt );
- _vsnprintf(buf, 1024, fmt, va );
- va_end( va );
- buf[1023] = 0;
-
- DEBUG_LOG(("%s", buf));
- if (g_debugSlots)
- {
- UnicodeString msg;
- msg.translate(buf);
- TheGameSpyInfo->addText(msg, GameSpyColor[GSCOLOR_DEFAULT], NULL);
- }
-}
-#define SLOTLIST_DEBUG_LOG(x) slotListDebugLog x
-#else
-#define SLOTLIST_DEBUG_LOG(x) DEBUG_LOG(x)
-#endif
-
-void SendStatsToOtherPlayers(const GameInfo *game)
-{
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMPLAYER;
- req.UTM.isStagingRoom = TRUE;
- req.id = "STATS/";
- AsciiString fullStr;
- PSPlayerStats fullStats = TheGameSpyPSMessageQueue->findPlayerStatsByID(TheGameSpyInfo->getLocalProfileID());
- PSPlayerStats subStats;
- subStats.id = fullStats.id;
- subStats.wins = fullStats.wins;
- subStats.losses = fullStats.losses;
- subStats.discons = fullStats.discons;
- subStats.desyncs = fullStats.desyncs;
- subStats.games = fullStats.games;
- subStats.locale = fullStats.locale;
- subStats.gamesAsRandom = fullStats.gamesAsRandom;
- GetAdditionalDisconnectsFromUserFile(&subStats);
- fullStr.format("%d %s", TheGameSpyInfo->getLocalProfileID(), TheGameSpyPSMessageQueue->formatPlayerKVPairs( subStats ));
- req.options = fullStr.str();
-
- Int localIndex = game->getLocalSlotNum();
- for (Int i=0; igetConstSlot(i);
- if (slot->isHuman() && i != localIndex)
- {
- AsciiString hostName;
- hostName.translate(slot->getName());
- req.nick = hostName.str();
- DEBUG_LOG(("SendStatsToOtherPlayers() - sending to '%s', data of\n\t'%s'\n", hostName.str(), req.options.c_str()));
- TheGameSpyPeerMessageQueue->addRequest(req);
- }
- }
-}
-
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-static Bool isShuttingDown = false;
-static Bool buttonPushed = false;
-static char *nextScreen = NULL;
-static Bool raiseMessageBoxes = false;
-static Bool launchGameNext = FALSE;
-
-// window ids ------------------------------------------------------------------------------
-static NameKeyType parentWOLGameSetupID = NAMEKEY_INVALID;
-
-static NameKeyType comboBoxPlayerID[MAX_SLOTS] = { NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID };
-
-static NameKeyType staticTextPlayerID[MAX_SLOTS] = { NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID };
-
-static NameKeyType buttonAcceptID[MAX_SLOTS] = { NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID };
-
-static NameKeyType comboBoxColorID[MAX_SLOTS] = { NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID };
-
-static NameKeyType comboBoxPlayerTemplateID[MAX_SLOTS] = { NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID };
-
-static NameKeyType comboBoxTeamID[MAX_SLOTS] = { NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID };
-//static NameKeyType buttonStartPositionID[MAX_SLOTS] = { NAMEKEY_INVALID,NAMEKEY_INVALID,
-// NAMEKEY_INVALID,NAMEKEY_INVALID,
-// NAMEKEY_INVALID,NAMEKEY_INVALID,
-// NAMEKEY_INVALID,NAMEKEY_INVALID };
-
-static NameKeyType buttonMapStartPositionID[MAX_SLOTS] = { NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID };
-static NameKeyType genericPingWindowID[MAX_SLOTS] = { NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID };
-
-static NameKeyType textEntryChatID = NAMEKEY_INVALID;
-static NameKeyType textEntryMapDisplayID = NAMEKEY_INVALID;
-static NameKeyType buttonBackID = NAMEKEY_INVALID;
-static NameKeyType buttonStartID = NAMEKEY_INVALID;
-static NameKeyType buttonEmoteID = NAMEKEY_INVALID;
-static NameKeyType buttonSelectMapID = NAMEKEY_INVALID;
-static NameKeyType windowMapID = NAMEKEY_INVALID;
-
-static NameKeyType windowMapSelectMapID = NAMEKEY_INVALID;
-// Window Pointers ------------------------------------------------------------------------
-static GameWindow *parentWOLGameSetup = NULL;
-static GameWindow *buttonBack = NULL;
-static GameWindow *buttonStart = NULL;
-static GameWindow *buttonSelectMap = NULL;
-static GameWindow *buttonEmote = NULL;
-static GameWindow *textEntryChat = NULL;
-static GameWindow *textEntryMapDisplay = NULL;
-static GameWindow *windowMap = NULL;
-
-static GameWindow *comboBoxPlayer[MAX_SLOTS] = {NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL };
-static GameWindow *staticTextPlayer[MAX_SLOTS] = {NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL };
-static GameWindow *buttonAccept[MAX_SLOTS] = {NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL };
-
-static GameWindow *comboBoxColor[MAX_SLOTS] = {NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL };
-
-static GameWindow *comboBoxPlayerTemplate[MAX_SLOTS] = {NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL };
-
-static GameWindow *comboBoxTeam[MAX_SLOTS] = {NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL };
-
-//static GameWindow *buttonStartPosition[MAX_SLOTS] = {NULL,NULL,NULL,NULL,
-// NULL,NULL,NULL,NULL };
-//
-static GameWindow *buttonMapStartPosition[MAX_SLOTS] = {NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL };
-
-static GameWindow *genericPingWindow[MAX_SLOTS] = {NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL };
-
-static const Image *pingImages[3] = { NULL, NULL, NULL };
-
-WindowLayout *WOLMapSelectLayout = NULL;
-
-void PopBackToLobby( void )
-{
- // delete TheNAT, its no good for us anymore.
- delete TheNAT;
- TheNAT = NULL;
-
- if (TheGameSpyInfo) // this can be blown away by a disconnect on the map transfer screen
- {
- TheGameSpyInfo->getCurrentStagingRoom()->reset();
- TheGameSpyInfo->leaveStagingRoom();
- //TheGameSpyInfo->joinBestGroupRoom();
- }
-
- DEBUG_LOG(("PopBackToLobby() - parentWOLGameSetup is %X\n", parentWOLGameSetup));
- if (parentWOLGameSetup)
- {
- nextScreen = "Menus/WOLCustomLobby.wnd";
- TheShell->pop();
- }
-}
-
-void updateMapStartSpots( GameInfo *myGame, GameWindow *buttonMapStartPositions[], Bool onLoadScreen = FALSE );
-void positionStartSpots( GameInfo *myGame, GameWindow *buttonMapStartPositions[], GameWindow *mapWindow);
-void positionStartSpots(AsciiString mapName, GameWindow *buttonMapStartPositions[], GameWindow *mapWindow);
-void WOLPositionStartSpots( void )
-{
- GameWindow *win = windowMap;
-
- if (WOLMapSelectLayout != NULL) {
- win = TheWindowManager->winGetWindowFromId(NULL, windowMapSelectMapID);
-
- // get the controls.
- NameKeyType listboxMapID = TheNameKeyGenerator->nameToKey( AsciiString("WOLMapSelectMenu.wnd:ListboxMap") );
- GameWindow *listboxMap = TheWindowManager->winGetWindowFromId( NULL, listboxMapID );
-
- if (listboxMap != NULL) {
- Int selected;
- UnicodeString map;
-
- // get the selected index
- GadgetListBoxGetSelected( listboxMap, &selected );
-
- if( selected != -1 )
- {
-
- // get text of the map to load
- map = GadgetListBoxGetText( listboxMap, selected, 0 );
-
-
- // set the map name in the global data map name
- AsciiString asciiMap;
- const char *mapFname = (const char *)GadgetListBoxGetItemData( listboxMap, selected );
- DEBUG_ASSERTCRASH(mapFname, ("No map item data"));
- if (mapFname) {
- asciiMap = mapFname;
- } else {
- asciiMap.translate( map );
- }
-
- positionStartSpots(asciiMap, buttonMapStartPosition, win);
- }
- }
-
- } else {
- DEBUG_ASSERTCRASH(win != NULL, ("no map preview window"));
- positionStartSpots( TheGameSpyInfo->getCurrentStagingRoom(), buttonMapStartPosition, win);
- }
-}
-static void savePlayerInfo( void )
-{
- if (TheGameSpyGame)
- {
- Int slotNum = TheGameSpyGame->getLocalSlotNum();
- if (slotNum >= 0)
- {
- GameSpyGameSlot *slot = TheGameSpyGame->getGameSpySlot(slotNum);
- if (slot)
- {
- // save off some prefs
- CustomMatchPreferences pref;
- pref.setPreferredColor(slot->getColor());
- pref.setPreferredFaction(slot->getPlayerTemplate());
- if (TheGameSpyGame->amIHost())
- {
- pref.setPreferredMap(TheGameSpyGame->getMap());
- }
- pref.write();
- }
- }
- }
-}
-
-// Tooltips -------------------------------------------------------------------------------
-
-static void playerTooltip(GameWindow *window,
- WinInstanceData *instData,
- UnsignedInt mouse)
-{
- Int slotIdx = -1;
- for (Int i=0; isetCursorTooltip( UnicodeString::TheEmptyString, -1, NULL, 1.5f );
- return;
- }
-
- GameSpyStagingRoom *game = TheGameSpyInfo->getCurrentStagingRoom();
- if (!game)
- {
- TheMouse->setCursorTooltip( UnicodeString::TheEmptyString, -1, NULL, 1.5f );
- return;
- }
-
- GameSpyGameSlot *slot = game->getGameSpySlot(slotIdx);
- if (!slot || !slot->isHuman())
- {
- TheMouse->setCursorTooltip( UnicodeString::TheEmptyString, -1, NULL, 1.5f );
- return;
- }
-
- // for tooltip, we want:
- // * player name
- // * ping
- // * locale
- // * win/loss history
- // * discons/desyncs as one var
- // * favorite army
- // in that order. got it? good.
-
- UnicodeString uName = slot->getName();
-
- AsciiString aName;
- aName.translate(uName);
- PlayerInfoMap::iterator pmIt = TheGameSpyInfo->getPlayerInfoMap()->find(aName);
- if (pmIt == TheGameSpyInfo->getPlayerInfoMap()->end())
- {
- TheMouse->setCursorTooltip( uName, -1, NULL, 1.5f );
- return;
- }
- Int profileID = pmIt->second.m_profileID;
-
- PSPlayerStats stats = TheGameSpyPSMessageQueue->findPlayerStatsByID(profileID);
- if (stats.id == 0)
- {
- TheMouse->setCursorTooltip( uName, -1, NULL, 1.5f );
- return;
- }
-
- Bool isLocalPlayer = slot == game->getGameSpySlot(game->getLocalSlotNum());
-
- AsciiString localeIdentifier;
- localeIdentifier.format("WOL:Locale%2.2d", stats.locale);
- UnicodeString playerInfo;
- Int totalWins = 0, totalLosses = 0, totalDiscons = 0;
- PerGeneralMap::iterator it;
-
- for (it = stats.wins.begin(); it != stats.wins.end(); ++it)
- {
- totalWins += it->second;
- }
- for (it = stats.losses.begin(); it != stats.losses.end(); ++it)
- {
- totalLosses += it->second;
- }
- for (it = stats.discons.begin(); it != stats.discons.end(); ++it)
- {
- totalDiscons += it->second;
- }
- for (it = stats.desyncs.begin(); it != stats.desyncs.end(); ++it)
- {
- totalDiscons += it->second;
- }
- UnicodeString favoriteSide;
- Int numGames = 0;
- Int favorite = 0;
- for(it = stats.games.begin(); it != stats.games.end(); ++it)
- {
- if(it->second >= numGames)
- {
- numGames = it->second;
- favorite = it->first;
- }
- }
- if(numGames == 0)
- favoriteSide = TheGameText->fetch("GUI:None");
- else if( stats.gamesAsRandom >= numGames )
- favoriteSide = TheGameText->fetch("GUI:Random");
- else
- {
- const PlayerTemplate *fac = ThePlayerTemplateStore->getNthPlayerTemplate(favorite);
- if (fac)
- {
- AsciiString side;
- side.format("SIDE:%s", fac->getSide().str());
-
- favoriteSide = TheGameText->fetch(side);
- }
- }
-
- playerInfo.format(TheGameText->fetch("TOOLTIP:StagingPlayerInfo"),
- TheGameText->fetch(localeIdentifier).str(),
- slot->getPingAsInt(),
- totalWins, totalLosses, totalDiscons,
- favoriteSide.str());
-
- UnicodeString tooltip = UnicodeString::TheEmptyString;
- if (isLocalPlayer)
- {
- tooltip.format(TheGameText->fetch("TOOLTIP:LocalPlayer"), uName.str());
- }
- else
- {
- // not us
- if (TheGameSpyInfo->getBuddyMap()->find(profileID) != TheGameSpyInfo->getBuddyMap()->end())
- {
- // buddy
- tooltip.format(TheGameText->fetch("TOOLTIP:BuddyPlayer"), uName.str());
- }
- else
- {
- if (profileID)
- {
- // non-buddy profiled player
- tooltip.format(TheGameText->fetch("TOOLTIP:ProfiledPlayer"), uName.str());
- }
- else
- {
- // non-profiled player
- tooltip.format(TheGameText->fetch("TOOLTIP:GenericPlayer"), uName.str());
- }
- }
- }
-
- tooltip.concat(playerInfo);
-
- TheMouse->setCursorTooltip( tooltip, -1, NULL, 1.5f ); // the text and width are the only params used. the others are the default values.
-}
-
-void gameAcceptTooltip(GameWindow *window, WinInstanceData *instData, UnsignedInt mouse)
-{
- Int x, y;
- x = LOLONGTOSHORT(mouse);
- y = HILONGTOSHORT(mouse);
-
- Int winPosX, winPosY, winWidth, winHeight;
-
- window->winGetScreenPosition(&winPosX, &winPosY);
-
- window->winGetSize(&winWidth, &winHeight);
-
- if ((x > winPosX && x < (winPosX + winWidth)) && (y > winPosY && y < (winPosY + winHeight)))
- {
- TheMouse->setCursorTooltip(TheGameText->fetch("TOOLTIP:GameAcceptance"), -1, NULL);
- }
-}
-
-void pingTooltip(GameWindow *window, WinInstanceData *instData, UnsignedInt mouse)
-{
- Int x, y;
- x = LOLONGTOSHORT(mouse);
- y = HILONGTOSHORT(mouse);
-
-
- Int winPosX, winPosY, winWidth, winHeight;
-
- window->winGetScreenPosition(&winPosX, &winPosY);
-
- window->winGetSize(&winWidth, &winHeight);
-
- if ((x > winPosX && x < (winPosX + winWidth)) && (y > winPosY && y < (winPosY + winHeight)))
- {
- TheMouse->setCursorTooltip(TheGameText->fetch("TOOLTIP:ConnectionSpeed"), -1, NULL);
- }
-}
-
-//external declarations of the Gadgets the callbacks can use
-GameWindow *listboxGameSetupChat = NULL;
-NameKeyType listboxGameSetupChatID = NAMEKEY_INVALID;
-
-static void handleColorSelection(int index)
-{
- GameWindow *combo = comboBoxColor[index];
- Int color, selIndex;
- GadgetComboBoxGetSelectedPos(combo, &selIndex);
- color = (Int)GadgetComboBoxGetItemData(combo, selIndex);
-
- GameInfo *myGame = TheGameSpyInfo->getCurrentStagingRoom();
-
- if (myGame)
- {
- GameSlot * slot = myGame->getSlot(index);
- if (color == slot->getColor())
- return;
-
- if (color >= -1 && color < TheMultiplayerSettings->getNumColors())
- {
- Bool colorAvailable = TRUE;
- if(color != -1 )
- {
- for(Int i=0; i getSlot(i);
- if(color == checkSlot->getColor() && slot != checkSlot)
- {
- colorAvailable = FALSE;
- break;
- }
- }
- }
- if(!colorAvailable)
- return;
- }
-
- slot->setColor(color);
-
- if (TheGameSpyInfo->amIHost())
- {
- // send around a new slotlist
- TheGameSpyInfo->setGameOptions();
- WOLDisplaySlotList();
- }
- else
- {
- // request the color from the host
- if (!slot->isPlayer(TheGameSpyInfo->getLocalName()))
- return;
-
- AsciiString options;
- options.format("Color=%d", color);
- AsciiString hostName;
- hostName.translate(myGame->getSlot(0)->getName());
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMPLAYER;
- req.UTM.isStagingRoom = TRUE;
- req.id = "REQ/";
- req.nick = hostName.str();
- req.options = options.str();
- TheGameSpyPeerMessageQueue->addRequest(req);
- }
- }
-}
-
-static void handlePlayerTemplateSelection(int index)
-{
- GameWindow *combo = comboBoxPlayerTemplate[index];
- Int playerTemplate, selIndex;
- GadgetComboBoxGetSelectedPos(combo, &selIndex);
- playerTemplate = (Int)GadgetComboBoxGetItemData(combo, selIndex);
- GameInfo *myGame = TheGameSpyInfo->getCurrentStagingRoom();
-
- if (myGame)
- {
- GameSlot * slot = myGame->getSlot(index);
- if (playerTemplate == slot->getPlayerTemplate())
- return;
-
- Int oldTemplate = slot->getPlayerTemplate();
- slot->setPlayerTemplate(playerTemplate);
-
- if (oldTemplate == PLAYERTEMPLATE_OBSERVER)
- {
- // was observer, so populate color & team with all, and enable
- GadgetComboBoxSetSelectedPos(comboBoxColor[index], 0);
- GadgetComboBoxSetSelectedPos(comboBoxTeam[index], 0);
- slot->setStartPos(-1);
- }
- else if (playerTemplate == PLAYERTEMPLATE_OBSERVER)
- {
- // is becoming observer, so populate color & team with random only, and disable
- GadgetComboBoxSetSelectedPos(comboBoxColor[index], 0);
- GadgetComboBoxSetSelectedPos(comboBoxTeam[index], 0);
- slot->setStartPos(-1);
- }
-
-
- if (TheGameSpyInfo->amIHost())
- {
- // send around a new slotlist
- myGame->resetAccepted();
- TheGameSpyInfo->setGameOptions();
- WOLDisplaySlotList();
- }
- else
- {
- // request the playerTemplate from the host
- AsciiString options;
- options.format("PlayerTemplate=%d", playerTemplate);
- AsciiString hostName;
- hostName.translate(myGame->getSlot(0)->getName());
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMPLAYER;
- req.UTM.isStagingRoom = TRUE;
- req.id = "REQ/";
- req.nick = hostName.str();
- req.options = options.str();
- TheGameSpyPeerMessageQueue->addRequest(req);
- }
- }
-}
-
-
-static void handleStartPositionSelection(Int player, int startPos)
-{
- GameSpyStagingRoom *myGame = TheGameSpyInfo->getCurrentStagingRoom();
-
- if (myGame)
- {
- GameSpyGameSlot * slot = myGame->getGameSpySlot(player);
- if (!slot)
- return;
-
- if (startPos == slot->getStartPos())
- return;
- Bool skip = FALSE;
- if (startPos < 0)
- {
- skip = TRUE;
- }
-
- if(!skip)
- {
- Bool isAvailable = TRUE;
- for(Int i = 0; i < MAX_SLOTS; ++i)
- {
- if(i != player && myGame->getSlot(i)->getStartPos() == startPos)
- {
- isAvailable = FALSE;
- break;
- }
- }
- if( !isAvailable )
- return;
- }
- slot->setStartPos(startPos);
-
- if (myGame->amIHost())
- {
- // send around a new slotlist
- myGame->resetAccepted();
- TheGameSpyInfo->setGameOptions();
- WOLDisplaySlotList();
- }
- else
- {
- // request the color from the host
- if (AreSlotListUpdatesEnabled())
- {
- // request the playerTemplate from the host
- AsciiString options;
- options.format("StartPos=%d", slot->getStartPos());
- AsciiString hostName;
- hostName.translate(myGame->getSlot(0)->getName());
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMPLAYER;
- req.UTM.isStagingRoom = TRUE;
- req.id = "REQ/";
- req.nick = hostName.str();
- req.options = options.str();
- TheGameSpyPeerMessageQueue->addRequest(req);
-
- }
- }
- }
-}
-
-
-
-static void handleTeamSelection(int index)
-{
- GameWindow *combo = comboBoxTeam[index];
- Int team, selIndex;
- GadgetComboBoxGetSelectedPos(combo, &selIndex);
- team = (Int)GadgetComboBoxGetItemData(combo, selIndex);
- GameInfo *myGame = TheGameSpyInfo->getCurrentStagingRoom();
-
- if (myGame)
- {
- GameSlot * slot = myGame->getSlot(index);
- if (team == slot->getTeamNumber())
- return;
-
- slot->setTeamNumber(team);
-
- if (TheGameSpyInfo->amIHost())
- {
- // send around a new slotlist
- myGame->resetAccepted();
- TheGameSpyInfo->setGameOptions();
- WOLDisplaySlotList();
- }
- else
- {
- // request the team from the host
- AsciiString options;
- options.format("Team=%d", team);
- AsciiString hostName;
- hostName.translate(myGame->getSlot(0)->getName());
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMPLAYER;
- req.UTM.isStagingRoom = TRUE;
- req.id = "REQ/";
- req.nick = hostName.str();
- req.options = options.str();
- TheGameSpyPeerMessageQueue->addRequest(req);
- }
- }
-}
-
-
-static void StartPressed(void)
-{
- Bool isReady = TRUE;
- Bool allHaveMap = TRUE;
- Int playerCount = 0;
- Int humanCount = 0;
- GameSpyStagingRoom *myGame = TheGameSpyInfo->getCurrentStagingRoom();
- if (!myGame)
- return;
-
- // see if everyone's accepted and count the number of players in the game
- UnicodeString mapDisplayName;
- const MapMetaData *mapData = TheMapCache->findMap( myGame->getMap() );
- Bool willTransfer = TRUE;
- if (mapData)
- {
- mapDisplayName.format(L"%ls", mapData->m_displayName.str());
- willTransfer = !mapData->m_isOfficial;
- }
- else
- {
- mapDisplayName.format(L"%hs", myGame->getMap().str());
- willTransfer = WouldMapTransfer(myGame->getMap());
- }
- for( int i = 0; i < MAX_SLOTS; i++ )
- {
- if ((myGame->getSlot(i)->isAccepted() == FALSE) && (myGame->getSlot(i)->isHuman() == TRUE))
- {
- isReady = FALSE;
- if (!myGame->getSlot(i)->hasMap() && !willTransfer)
- {
- UnicodeString msg;
- msg.format(TheGameText->fetch("GUI:PlayerNoMap"), myGame->getSlot(i)->getName().str(), mapDisplayName.str());
- TheGameSpyInfo->addText(msg, GameSpyColor[GSCOLOR_DEFAULT], listboxGameSetupChat);
- allHaveMap = FALSE;
- }
- }
- if(myGame->getSlot(i)->isOccupied() && myGame->getSlot(i)->getPlayerTemplate() != PLAYERTEMPLATE_OBSERVER)
- {
- if (myGame->getSlot(i)->isHuman())
- humanCount++;
- playerCount++;
- }
- }
-
- // Check for too many players
- const MapMetaData *md = TheMapCache->findMap( myGame->getMap() );
- if (!md || md->m_numPlayers < playerCount)
- {
- if (myGame->amIHost())
- {
- UnicodeString text;
- text.format(TheGameText->fetch("LAN:TooManyPlayers"), (md)?md->m_numPlayers:0);
- TheGameSpyInfo->addText(text, GameSpyColor[GSCOLOR_DEFAULT], listboxGameSetupChat);
- }
- return;
- }
-
- // Check for observer + AI players
- if (TheGlobalData->m_netMinPlayers && !humanCount)
- {
- if (myGame->amIHost())
- {
- UnicodeString text = TheGameText->fetch("GUI:NeedHumanPlayers");
- TheGameSpyInfo->addText(text, GameSpyColor[GSCOLOR_DEFAULT], listboxGameSetupChat);
- }
- return;
- }
-
- // Check for too few players
- if (playerCount < TheGlobalData->m_netMinPlayers)
- {
- if (myGame->amIHost())
- {
- UnicodeString text;
- text.format(TheGameText->fetch("LAN:NeedMorePlayers"),playerCount);
- TheGameSpyInfo->addText(text, GameSpyColor[GSCOLOR_DEFAULT], listboxGameSetupChat);
- }
- return;
- }
-
- // Check for too few teams
- int numRandom = 0;
- std::set teams;
- for (i=0; igetSlot(i);
- if (slot && slot->isOccupied() && slot->getPlayerTemplate() != PLAYERTEMPLATE_OBSERVER)
- {
- if (slot->getTeamNumber() >= 0)
- {
- teams.insert(slot->getTeamNumber());
- }
- else
- {
- ++numRandom;
- }
- }
- }
- if (numRandom + teams.size() < TheGlobalData->m_netMinPlayers)
- {
- if (myGame->amIHost())
- {
- UnicodeString text;
- text.format(TheGameText->fetch("LAN:NeedMoreTeams"));
- TheGameSpyInfo->addText(text, GameSpyColor[GSCOLOR_DEFAULT], listboxGameSetupChat);
- }
- return;
- }
-
- if (numRandom + teams.size() < 2)
- {
- UnicodeString text;
- text.format(TheGameText->fetch("GUI:SandboxMode"));
- TheGameSpyInfo->addText(text, GameSpyColor[GSCOLOR_DEFAULT], listboxGameSetupChat);
- }
-
- if(isReady)
- {
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_STARTGAME;
- TheGameSpyPeerMessageQueue->addRequest(req);
-
- SendStatsToOtherPlayers(myGame);
-
- // we've started, there's no going back
- // i.e. disable the back button.
- buttonBack->winEnable(FALSE);
- GameWindow *buttonBuddy = TheWindowManager->winGetWindowFromId(NULL, NAMEKEY("GameSpyGameOptionsMenu.wnd:ButtonCommunicator"));
- if (buttonBuddy)
- buttonBuddy->winEnable(FALSE);
- GameSpyCloseOverlay(GSOVERLAY_BUDDY);
-
- *TheGameSpyGame = *myGame;
- TheGameSpyGame->startGame(0);
- }
- else if (allHaveMap)
- {
- TheGameSpyInfo->addText(TheGameText->fetch("GUI:NotifiedStartIntent"), GameSpyColor[GSCOLOR_DEFAULT], listboxGameSetupChat);
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMROOM;
- req.UTM.isStagingRoom = TRUE;
- req.id = "HWS/";
- req.options = "true";
- TheGameSpyPeerMessageQueue->addRequest(req);
- }
-
-}//void StartPressed(void)
-
-//-------------------------------------------------------------------------------------------------
-/** Update options on screen */
-//-------------------------------------------------------------------------------------------------
-void WOLDisplayGameOptions( void )
-{
- GameSpyStagingRoom *theGame = TheGameSpyInfo->getCurrentStagingRoom();
- if (!parentWOLGameSetup || !theGame)
- return;
-
- const GameSlot *localSlot = NULL;
- if (theGame->getLocalSlotNum() >= 0)
- localSlot = theGame->getConstSlot(theGame->getLocalSlotNum());
-
- const MapMetaData *md = TheMapCache->findMap(TheGameSpyInfo->getCurrentStagingRoom()->getMap());
- if (md && localSlot && localSlot->hasMap())
- {
- GadgetStaticTextSetText(textEntryMapDisplay, md->m_displayName);
- }
- else
- {
- AsciiString s = TheGameSpyInfo->getCurrentStagingRoom()->getMap();
- if (s.reverseFind('\\'))
- {
- s = s.reverseFind('\\') + 1;
- }
- UnicodeString mapDisplay;
- mapDisplay.translate(s);
- GadgetStaticTextSetText(textEntryMapDisplay, mapDisplay);
- }
- WOLPositionStartSpots();
- updateMapStartSpots(TheGameSpyInfo->getCurrentStagingRoom(), buttonMapStartPosition);
-}
-
-// -----------------------------------------------------------------------------------------
-// The Bad munkee slot list displaying function
-//-------------------------------------------------------------------------------------------------
-void WOLDisplaySlotList( void )
-{
- if (!parentWOLGameSetup || !TheGameSpyInfo->getCurrentStagingRoom())
- return;
-
- GameSpyStagingRoom *game = TheGameSpyInfo->getCurrentStagingRoom();
- if (!game->isInGame())
- return;
-
- DEBUG_ASSERTCRASH(!game->getConstSlot(0)->isOpen(), ("Open host!"));
-
- UpdateSlotList( game, comboBoxPlayer, comboBoxColor,
- comboBoxPlayerTemplate, comboBoxTeam, buttonAccept, buttonStart, buttonMapStartPosition );
-
- WOLDisplayGameOptions();
-
- for (Int i=0; igetGameSpySlot(i);
- if (slot && slot->isHuman())
- {
- if (i == game->getLocalSlotNum())
- {
- // set up my own ping...
- slot->setPingString(TheGameSpyInfo->getPingString());
- }
-
- if (genericPingWindow[i])
- {
- genericPingWindow[i]->winHide(FALSE);
- Int ping = slot->getPingAsInt();
- if (ping < TheGameSpyConfig->getPingCutoffGood())
- {
- genericPingWindow[i]->winSetEnabledImage(0, pingImages[0]);
- }
- else if (ping < TheGameSpyConfig->getPingCutoffBad())
- {
- genericPingWindow[i]->winSetEnabledImage(0, pingImages[1]);
- }
- else
- {
- genericPingWindow[i]->winSetEnabledImage(0, pingImages[2]);
- }
- }
- }
- else
- {
- if (genericPingWindow[i])
- genericPingWindow[i]->winHide(TRUE);
- }
- }
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the Gadgets Options Menu */
-//-------------------------------------------------------------------------------------------------
-void InitWOLGameGadgets( void )
-{
- GameSpyStagingRoom *theGameInfo = TheGameSpyInfo->getCurrentStagingRoom();
- pingImages[0] = TheMappedImageCollection->findImageByName("Ping03");
- pingImages[1] = TheMappedImageCollection->findImageByName("Ping02");
- pingImages[2] = TheMappedImageCollection->findImageByName("Ping01");
- DEBUG_ASSERTCRASH(pingImages[0], ("Can't find ping image!"));
- DEBUG_ASSERTCRASH(pingImages[1], ("Can't find ping image!"));
- DEBUG_ASSERTCRASH(pingImages[2], ("Can't find ping image!"));
-
- //Initialize the gadget IDs
- parentWOLGameSetupID = TheNameKeyGenerator->nameToKey( AsciiString( "GameSpyGameOptionsMenu.wnd:GameSpyGameOptionsMenuParent" ) );
- buttonBackID = TheNameKeyGenerator->nameToKey( AsciiString( "GameSpyGameOptionsMenu.wnd:ButtonBack" ) );
- buttonStartID = TheNameKeyGenerator->nameToKey( AsciiString( "GameSpyGameOptionsMenu.wnd:ButtonStart" ) );
- textEntryChatID = TheNameKeyGenerator->nameToKey( AsciiString( "GameSpyGameOptionsMenu.wnd:TextEntryChat" ) );
- textEntryMapDisplayID = TheNameKeyGenerator->nameToKey( AsciiString( "GameSpyGameOptionsMenu.wnd:TextEntryMapDisplay" ) );
- listboxGameSetupChatID = TheNameKeyGenerator->nameToKey( AsciiString( "GameSpyGameOptionsMenu.wnd:ListboxChatWindowGameSpyGameSetup" ) );
- buttonEmoteID = TheNameKeyGenerator->nameToKey( AsciiString( "GameSpyGameOptionsMenu.wnd:ButtonEmote" ) );
- buttonSelectMapID = TheNameKeyGenerator->nameToKey( AsciiString( "GameSpyGameOptionsMenu.wnd:ButtonSelectMap" ) );
- windowMapID = TheNameKeyGenerator->nameToKey( AsciiString( "GameSpyGameOptionsMenu.wnd:MapWindow" ) );
- windowMapSelectMapID = TheNameKeyGenerator->nameToKey(AsciiString("WOLMapSelectMenu.wnd:WinMapPreview"));
-
- NameKeyType staticTextTitleID = NAMEKEY("GameSpyGameOptionsMenu.wnd:StaticTextGameName");
-
- // Initialize the pointers to our gadgets
- parentWOLGameSetup = TheWindowManager->winGetWindowFromId( NULL, parentWOLGameSetupID );
- buttonEmote = TheWindowManager->winGetWindowFromId( parentWOLGameSetup,buttonEmoteID );
- buttonSelectMap = TheWindowManager->winGetWindowFromId( parentWOLGameSetup,buttonSelectMapID );
- buttonStart = TheWindowManager->winGetWindowFromId( parentWOLGameSetup,buttonStartID );
- buttonBack = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, buttonBackID);
- listboxGameSetupChat = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, listboxGameSetupChatID );
- textEntryChat = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, textEntryChatID );
- textEntryMapDisplay = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, textEntryMapDisplayID );
- windowMap = TheWindowManager->winGetWindowFromId( parentWOLGameSetup,windowMapID );
- DEBUG_ASSERTCRASH(windowMap, ("Could not find the parentWOLGameSetup.wnd:MapWindow" ));
-
- //Added By Sadullah Nader
- //Tooltip Function set
- windowMap->winSetTooltipFunc(MapSelectorTooltip);
- //
-
- GameWindow *staticTextTitle = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, staticTextTitleID );
- if (staticTextTitle)
- {
- GadgetStaticTextSetText(staticTextTitle, TheGameSpyGame->getGameName());
- }
-
- if (!theGameInfo)
- {
- DEBUG_CRASH(("No staging room!"));
- return;
- }
-
- for (Int i = 0; i < MAX_SLOTS; i++)
- {
- AsciiString tmpString;
- tmpString.format("GameSpyGameOptionsMenu.wnd:ComboBoxPlayer%d", i);
- comboBoxPlayerID[i] = TheNameKeyGenerator->nameToKey( tmpString );
- comboBoxPlayer[i] = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, comboBoxPlayerID[i] );
- GadgetComboBoxReset(comboBoxPlayer[i]);
- comboBoxPlayer[i]->winSetTooltipFunc(playerTooltip);
-
- tmpString.format("GameSpyGameOptionsMenu.wnd:StaticTextPlayer%d", i);
- staticTextPlayerID[i] = TheNameKeyGenerator->nameToKey( tmpString );
- staticTextPlayer[i] = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, staticTextPlayerID[i] );
- staticTextPlayer[i]->winSetTooltipFunc(playerTooltip);
- if (TheGameSpyInfo->amIHost())
- staticTextPlayer[i]->winHide(TRUE);
-
- if(i==0 && TheGameSpyInfo->amIHost())
- {
- UnicodeString uName;
- uName.translate(TheGameSpyInfo->getLocalName());
- GadgetComboBoxAddEntry(comboBoxPlayer[i],uName,GameSpyColor[GSCOLOR_PLAYER_OWNER]);
- GadgetComboBoxSetSelectedPos(comboBoxPlayer[0],0);
- }
- else
- {
- GadgetComboBoxAddEntry(comboBoxPlayer[i],TheGameText->fetch("GUI:Open"),GameSpyColor[GSCOLOR_PLAYER_NORMAL]);
- GadgetComboBoxAddEntry(comboBoxPlayer[i],TheGameText->fetch("GUI:Closed"),GameSpyColor[GSCOLOR_PLAYER_NORMAL]);
- GadgetComboBoxAddEntry(comboBoxPlayer[i],TheGameText->fetch("GUI:EasyAI"),GameSpyColor[GSCOLOR_PLAYER_NORMAL]);
- GadgetComboBoxAddEntry(comboBoxPlayer[i],TheGameText->fetch("GUI:MediumAI"),GameSpyColor[GSCOLOR_PLAYER_NORMAL]);
- GadgetComboBoxAddEntry(comboBoxPlayer[i],TheGameText->fetch("GUI:HardAI"),GameSpyColor[GSCOLOR_PLAYER_NORMAL]);
- GadgetComboBoxSetSelectedPos(comboBoxPlayer[i],0);
- }
-
- tmpString.format("GameSpyGameOptionsMenu.wnd:ComboBoxColor%d", i);
- comboBoxColorID[i] = TheNameKeyGenerator->nameToKey( tmpString );
- comboBoxColor[i] = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, comboBoxColorID[i] );
- DEBUG_ASSERTCRASH(comboBoxColor[i], ("Could not find the comboBoxColor[%d]",i ));
- PopulateColorComboBox(i, comboBoxColor, theGameInfo);
- GadgetComboBoxSetSelectedPos(comboBoxColor[i], 0);
-
- tmpString.format("GameSpyGameOptionsMenu.wnd:ComboBoxPlayerTemplate%d", i);
- comboBoxPlayerTemplateID[i] = TheNameKeyGenerator->nameToKey( tmpString );
- comboBoxPlayerTemplate[i] = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, comboBoxPlayerTemplateID[i] );
- DEBUG_ASSERTCRASH(comboBoxPlayerTemplate[i], ("Could not find the comboBoxPlayerTemplate[%d]",i ));
- PopulatePlayerTemplateComboBox(i, comboBoxPlayerTemplate, theGameInfo, theGameInfo->getAllowObservers());
-
- tmpString.format("GameSpyGameOptionsMenu.wnd:ComboBoxTeam%d", i);
- comboBoxTeamID[i] = TheNameKeyGenerator->nameToKey( tmpString );
- comboBoxTeam[i] = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, comboBoxTeamID[i] );
- DEBUG_ASSERTCRASH(comboBoxTeam[i], ("Could not find the comboBoxTeam[%d]",i ));
- PopulateTeamComboBox(i, comboBoxTeam, theGameInfo);
-
- tmpString.format("GameSpyGameOptionsMenu.wnd:ButtonAccept%d", i);
- buttonAcceptID[i] = TheNameKeyGenerator->nameToKey( tmpString );
- buttonAccept[i] = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, buttonAcceptID[i] );
- DEBUG_ASSERTCRASH(buttonAccept[i], ("Could not find the buttonAccept[%d]",i ));
- buttonAccept[i]->winSetTooltipFunc(gameAcceptTooltip);
-
- tmpString.format("GameSpyGameOptionsMenu.wnd:GenericPing%d", i);
- genericPingWindowID[i] = TheNameKeyGenerator->nameToKey( tmpString );
- genericPingWindow[i] = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, genericPingWindowID[i] );
- DEBUG_ASSERTCRASH(genericPingWindow[i], ("Could not find the genericPingWindow[%d]",i ));
- genericPingWindow[i]->winSetTooltipFunc(pingTooltip);
-
-// tmpString.format("GameSpyGameOptionsMenu.wnd:ButtonStartPosition%d", i);
-// buttonStartPositionID[i] = TheNameKeyGenerator->nameToKey( tmpString );
-// buttonStartPosition[i] = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, buttonStartPositionID[i] );
-// DEBUG_ASSERTCRASH(buttonStartPosition[i], ("Could not find the ButtonStartPosition[%d]",i ));
-
- tmpString.format("GameSpyGameOptionsMenu.wnd:ButtonMapStartPosition%d", i);
- buttonMapStartPositionID[i] = TheNameKeyGenerator->nameToKey( tmpString );
- buttonMapStartPosition[i] = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, buttonMapStartPositionID[i] );
- DEBUG_ASSERTCRASH(buttonMapStartPosition[i], ("Could not find the ButtonMapStartPosition[%d]",i ));
-
-// if (buttonStartPosition[i])
-// buttonStartPosition[i]->winHide(TRUE);
-
- if(i !=0 && buttonAccept[i])
- buttonAccept[i]->winHide(TRUE);
- }
-
- if( buttonAccept[0] )
- buttonAccept[0]->winEnable(TRUE);
-
- if (buttonBack != NULL)
- {
- buttonBack->winEnable(TRUE);
- }
- //GadgetButtonSetEnabledColor(buttonAccept[0], GameSpyColor[GSCOLOR_ACCEPT_TRUE]);
-}
-
-void DeinitWOLGameGadgets( void )
-{
- parentWOLGameSetup = NULL;
- buttonEmote = NULL;
- buttonSelectMap = NULL;
- buttonStart = NULL;
- buttonBack = NULL;
- listboxGameSetupChat = NULL;
- textEntryChat = NULL;
- textEntryMapDisplay = NULL;
- windowMap = NULL;
-// GameWindow *staticTextTitle = NULL;
- for (Int i = 0; i < MAX_SLOTS; i++)
- {
- comboBoxPlayer[i] = NULL;
- staticTextPlayer[i] = NULL;
- comboBoxColor[i] = NULL;
- comboBoxPlayerTemplate[i] = NULL;
- comboBoxTeam[i] = NULL;
- buttonAccept[i] = NULL;
-// buttonStartPosition[i] = NULL;
- buttonMapStartPosition[i] = NULL;
- genericPingWindow[i] = NULL;
- }
-}
-
-static Bool initDone = false;
-UnsignedInt lastSlotlistTime = 0;
-UnsignedInt enterTime = 0;
-Bool initialAcceptEnable = FALSE;
-//-------------------------------------------------------------------------------------------------
-/** Initialize the Lan Game Options Menu */
-//-------------------------------------------------------------------------------------------------
-void WOLGameSetupMenuInit( WindowLayout *layout, void *userData )
-{
- if (TheGameSpyGame && TheGameSpyGame->isGameInProgress())
- {
- TheGameSpyGame->setGameInProgress(FALSE);
-
- // check if we were disconnected
- Int disconReason;
- if (TheGameSpyInfo->isDisconnectedAfterGameStart(&disconReason))
- {
- AsciiString disconMunkee;
- disconMunkee.format("GUI:GSDisconReason%d", disconReason);
- UnicodeString title, body;
- title = TheGameText->fetch( "GUI:GSErrorTitle" );
- body = TheGameText->fetch( disconMunkee );
- GameSpyCloseAllOverlays();
- GSMessageBoxOk( title, body );
- TheGameSpyInfo->reset();
- DEBUG_LOG(("WOLGameSetupMenuInit() - game was in progress, and we were disconnected, so pop immediate back to main menu\n"));
- TheShell->popImmediate();
- return;
- }
-
- // If we init while the game is in progress, we are really returning to the menu
- // after the game. So, we pop the menu and go back to the lobby. Whee!
- DEBUG_LOG(("WOLGameSetupMenuInit() - game was in progress, so pop immediate back to lobby\n"));
- TheShell->popImmediate();
- if (TheGameSpyPeerMessageQueue && TheGameSpyPeerMessageQueue->isConnected())
- {
- DEBUG_LOG(("We're still connected, so pushing back on the lobby\n"));
- TheShell->push("Menus/WOLCustomLobby.wnd", TRUE);
- }
- return;
- }
- TheGameSpyInfo->setCurrentGroupRoom(0);
-
- if (TheNAT != NULL) {
- delete TheNAT;
- TheNAT = NULL;
- }
-
- nextScreen = NULL;
- buttonPushed = false;
- isShuttingDown = false;
- launchGameNext = FALSE;
-
- //initialize the gadgets
- EnableSlotListUpdates(FALSE);
- InitWOLGameGadgets();
- EnableSlotListUpdates(TRUE);
- TheGameSpyInfo->registerTextWindow(listboxGameSetupChat);
-
- //The dialog needs to react differently depending on whether it's the host or not.
- TheMapCache->updateCache();
- GameSpyStagingRoom *game = TheGameSpyInfo->getCurrentStagingRoom();
- GameSpyGameSlot *hostSlot = game->getGameSpySlot(0);
- hostSlot->setAccept();
- if (TheGameSpyInfo->amIHost())
- {
- OptionPreferences natPref;
- CustomMatchPreferences customPref;
- hostSlot->setColor( customPref.getPreferredColor() );
- hostSlot->setPlayerTemplate( customPref.getPreferredFaction() );
- hostSlot->setNATBehavior((FirewallHelperClass::FirewallBehaviorType)natPref.getFirewallBehavior());
- hostSlot->setPingString(TheGameSpyInfo->getPingString());
- game->setMap(customPref.getPreferredMap());
-
- for (Int i=1; igetGameSpySlot(i);
- slot->setState( SLOT_OPEN );
- }
-
- AsciiString lowerMap = customPref.getPreferredMap();
- lowerMap.toLower();
- std::map::iterator it = TheMapCache->find(lowerMap);
- if (it != TheMapCache->end())
- {
- hostSlot->setMapAvailability(TRUE);
- game->setMapCRC( it->second.m_CRC );
- game->setMapSize( it->second.m_filesize );
-
- game->adjustSlotsForMap(); // BGC- adjust the slots for the new map.
- }
-
-
- WOLDisplaySlotList();
- WOLDisplayGameOptions();
- }
- else
- {
- OptionPreferences natPref;
- CustomMatchPreferences customPref;
- AsciiString options;
- PeerRequest req;
- UnicodeString uName = hostSlot->getName();
- AsciiString aName;
- aName.translate(uName);
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMPLAYER;
- req.UTM.isStagingRoom = TRUE;
- req.id = "REQ/";
- req.nick = aName.str();
- options.format("PlayerTemplate=%d", customPref.getPreferredFaction());
- req.options = options.str();
- TheGameSpyPeerMessageQueue->addRequest(req);
- options.format("Color=%d", customPref.getPreferredColor());
- req.options = options.str();
- TheGameSpyPeerMessageQueue->addRequest(req);
- options.format("NAT=%d", natPref.getFirewallBehavior());
- req.options = options.str();
- TheGameSpyPeerMessageQueue->addRequest(req);
- options.format("Ping=%s", TheGameSpyInfo->getPingString().str());
- req.options = options.str();
- TheGameSpyPeerMessageQueue->addRequest(req);
-
- game->setMapCRC( game->getMapCRC() ); // force a recheck
- game->setMapSize( game->getMapSize() ); // of if we have the map
-
- for (Int i = 0; i < MAX_SLOTS; ++i)
- {
- //I'm a client, disable the controls I can't touch.
- comboBoxPlayer[i]->winEnable(FALSE);
-
- comboBoxColor[i]->winEnable(FALSE);
- comboBoxPlayerTemplate[i]->winEnable(FALSE);
- comboBoxTeam[i]->winEnable(FALSE);
-// buttonStartPosition[i]->winEnable(FALSE);
- buttonMapStartPosition[i]->winEnable(FALSE);
-
- }
- buttonStart->winSetText(TheGameText->fetch("GUI:Accept"));
- buttonStart->winEnable( FALSE );
- buttonSelectMap->winEnable( FALSE );
- initialAcceptEnable = FALSE;
- }
-
- // Show the Menu
- layout->hide( FALSE );
-
- // Make sure the text fields are clear
- GadgetListBoxReset( listboxGameSetupChat );
- GadgetTextEntrySetText(textEntryChat, UnicodeString::TheEmptyString);
-
- initDone = true;
- TheGameSpyInfo->setGameOptions();
- //TheShell->registerWithAnimateManager(parentWOLGameSetup, WIN_ANIMATION_SLIDE_TOP, TRUE);
- WOLPositionStartSpots();
-
- lastSlotlistTime = 0;
- enterTime = timeGetTime();
-
- // Set Keyboard to chat entry
- TheWindowManager->winSetFocus( textEntryChat );
- raiseMessageBoxes = true;
- TheTransitionHandler->setGroup("GameSpyGameOptionsMenuFade");
-}// void WOLGameSetupMenuInit( WindowLayout *layout, void *userData )
-
-//-------------------------------------------------------------------------------------------------
-/** This is called when a shutdown is complete for this menu */
-//-------------------------------------------------------------------------------------------------
-static void shutdownComplete( WindowLayout *layout )
-{
-
- isShuttingDown = false;
-
- // hide the layout
- layout->hide( TRUE );
-
- // our shutdown is complete
- TheShell->shutdownComplete( layout, (nextScreen != NULL) );
-
- if (nextScreen != NULL)
- {
- if (!TheGameSpyPeerMessageQueue || !TheGameSpyPeerMessageQueue->isConnected())
- {
- DEBUG_LOG(("GameSetup shutdownComplete() - skipping push because we're disconnected\n"));
- }
- else
- {
- TheShell->push(nextScreen);
- }
- }
-
- /*
- if (launchGameNext)
- {
- TheGameSpyGame->launchGame();
- TheGameSpyInfo->leaveStagingRoom();
- }
- */
-
- nextScreen = NULL;
-
-} // end if
-
-//-------------------------------------------------------------------------------------------------
-/** GameSpy Game Options menu shutdown method */
-//-------------------------------------------------------------------------------------------------
-void WOLGameSetupMenuShutdown( WindowLayout *layout, void *userData )
-{
- TheGameSpyInfo->unregisterTextWindow(listboxGameSetupChat);
-
- if( WOLMapSelectLayout )
- {
- WOLMapSelectLayout->destroyWindows();
- WOLMapSelectLayout->deleteInstance();
- WOLMapSelectLayout = NULL;
- }
- parentWOLGameSetup = NULL;
- EnableSlotListUpdates(FALSE);
- DeinitWOLGameGadgets();
- if (TheEstablishConnectionsMenu != NULL)
- {
- TheEstablishConnectionsMenu->endMenu();
- }
- initDone = false;
-
- isShuttingDown = true;
-
- // if we are shutting down for an immediate pop, skip the animations
- Bool popImmediate = *(Bool *)userData;
- if( popImmediate )
- {
-
- shutdownComplete( layout );
- return;
-
- } //end if
-
- TheShell->reverseAnimatewindow();
-
- RaiseGSMessageBox();
- TheTransitionHandler->reverse("GameSpyGameOptionsMenuFade");
-} // void WOLGameSetupMenuShutdown( WindowLayout *layout, void *userData )
-
-static void fillPlayerInfo(const PeerResponse *resp, PlayerInfo *info)
-{
- info->m_name = resp->nick.c_str();
- info->m_profileID = resp->player.profileID;
- info->m_flags = resp->player.flags;
- info->m_wins = resp->player.wins;
- info->m_losses = resp->player.losses;
- info->m_locale = resp->locale.c_str();
- info->m_rankPoints= resp->player.rankPoints;
- info->m_side = resp->player.side;
- info->m_preorder = resp->player.preorder;
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Lan Game Options menu update method */
-//-------------------------------------------------------------------------------------------------
-void WOLGameSetupMenuUpdate( WindowLayout * layout, void *userData)
-{
- // We'll only be successful if we've requested to
- if(isShuttingDown && TheShell->isAnimFinished() && TheTransitionHandler->isFinished())
- {
- shutdownComplete(layout);
- return;
- }
-
- if (raiseMessageBoxes)
- {
- RaiseGSMessageBox();
- raiseMessageBoxes = false;
- }
-
- if (TheShell->isAnimFinished() && !buttonPushed && TheGameSpyPeerMessageQueue)
- {
- HandleBuddyResponses();
- HandlePersistentStorageResponses();
-
- if (TheGameSpyGame && TheGameSpyGame->isGameInProgress())
- {
- if (TheGameSpyInfo->isDisconnectedAfterGameStart(NULL))
- {
- return; // already been disconnected, so don't worry.
- }
-
- Int allowedMessages = TheGameSpyInfo->getMaxMessagesPerUpdate();
- Bool sawImportantMessage = FALSE;
- PeerResponse resp;
- while (allowedMessages-- && !sawImportantMessage && TheGameSpyPeerMessageQueue->getResponse( resp ))
- {
- switch (resp.peerResponseType)
- {
- case PeerResponse::PEERRESPONSE_DISCONNECT:
- {
- sawImportantMessage = TRUE;
- AsciiString disconMunkee;
- disconMunkee.format("GUI:GSDisconReason%d", resp.discon.reason);
-
- // check for scorescreen
- NameKeyType listboxChatWindowScoreScreenID = NAMEKEY("ScoreScreen.wnd:ListboxChatWindowScoreScreen");
- GameWindow *listboxChatWindowScoreScreen = TheWindowManager->winGetWindowFromId( NULL, listboxChatWindowScoreScreenID );
- if (listboxChatWindowScoreScreen)
- {
- GadgetListBoxAddEntryText(listboxChatWindowScoreScreen, TheGameText->fetch(disconMunkee),
- GameSpyColor[GSCOLOR_DEFAULT], -1);
- }
- else
- {
- // still ingame
- TheInGameUI->message(disconMunkee);
- }
- TheGameSpyInfo->markAsDisconnectedAfterGameStart(resp.discon.reason);
- }
- }
- }
-
- return; // if we're in game, all we care about is if we've been disconnected from the chat server
- }
-
- Bool isHosting = TheGameSpyInfo->amIHost(); // only while in game setup screen
- isHosting = isHosting || (TheGameSpyGame && TheGameSpyGame->isInGame() && TheGameSpyGame->amIHost()); // while in game
- if (!isHosting && !lastSlotlistTime && timeGetTime() > enterTime + 10000)
- {
- // don't do this if we're disconnected
- if (TheGameSpyPeerMessageQueue->isConnected())
- {
- // haven't seen ourselves
- buttonPushed = true;
- DEBUG_LOG(("Haven't seen ourselves in slotlist\n"));
- if (TheGameSpyGame)
- TheGameSpyGame->reset();
- TheGameSpyInfo->leaveStagingRoom();
- //TheGameSpyInfo->joinBestGroupRoom();
- GSMessageBoxOk(TheGameText->fetch("GUI:HostLeftTitle"), TheGameText->fetch("GUI:HostLeft"));
- nextScreen = "Menus/WOLCustomLobby.wnd";
- TheShell->pop();
- }
- return;
- }
-
- if (TheNAT != NULL) {
- NATStateType NATState = TheNAT->update();
- if (NATState == NATSTATE_DONE)
- {
- //launchGameNext = TRUE;
- //TheShell->pop();
- TheGameSpyGame->launchGame();
- if (TheGameSpyInfo) // this can be blown away by a disconnect on the map transfer screen
- TheGameSpyInfo->leaveStagingRoom();
- return;
- }
- else if (NATState == NATSTATE_FAILED)
- {
- // Just back out. This cleans up some slot list problems
- buttonPushed = true;
-
- // delete TheNAT, its no good for us anymore.
- delete TheNAT;
- TheNAT = NULL;
-
- TheGameSpyInfo->getCurrentStagingRoom()->reset();
- TheGameSpyInfo->leaveStagingRoom();
- //TheGameSpyInfo->joinBestGroupRoom();
- GSMessageBoxOk(TheGameText->fetch("GUI:Error"), TheGameText->fetch("GUI:NATNegotiationFailed"));
- nextScreen = "Menus/WOLCustomLobby.wnd";
- TheShell->pop();
- return;
- }
- }
-
- PeerResponse resp;
-
- Int allowedMessages = TheGameSpyInfo->getMaxMessagesPerUpdate();
- Bool sawImportantMessage = FALSE;
- while (allowedMessages-- && !sawImportantMessage)
- {
-
- if (!TheLobbyQueuedUTMs.empty())
- {
- DEBUG_LOG(("Got response from queued lobby UTM list\n"));
- resp = TheLobbyQueuedUTMs.front();
- TheLobbyQueuedUTMs.pop_front();
- }
- else if (TheGameSpyPeerMessageQueue->getResponse( resp ))
- {
- DEBUG_LOG(("Got response from message queue\n"));
- }
- else
- {
- break;
- }
-
- switch (resp.peerResponseType)
- {
- case PeerResponse::PEERRESPONSE_FAILEDTOHOST:
- {
- // oops - we've not heard from the qr server. bail.
- TheGameSpyInfo->addText(TheGameText->fetch("GUI:GSFailedToHost"), GameSpyColor[GSCOLOR_DEFAULT], NULL);
- }
- break;
- case PeerResponse::PEERRESPONSE_GAMESTART:
- {
- sawImportantMessage = TRUE;
- GameSpyStagingRoom *myGame = TheGameSpyInfo->getCurrentStagingRoom();
- if (!myGame || !myGame->isInGame())
- break;
-
- if (!TheGameSpyGame)
- break;
-
- SendStatsToOtherPlayers(TheGameSpyGame);
-
- // we've started, there's no going back
- // i.e. disable the back button.
- buttonBack->winEnable(FALSE);
- GameWindow *buttonBuddy = TheWindowManager->winGetWindowFromId(NULL, NAMEKEY("GameSpyGameOptionsMenu.wnd:ButtonCommunicator"));
- if (buttonBuddy)
- buttonBuddy->winEnable(FALSE);
- GameSpyCloseOverlay(GSOVERLAY_BUDDY);
-
- *TheGameSpyGame = *myGame;
- TheGameSpyGame->startGame(0);
- }
- break;
- case PeerResponse::PEERRESPONSE_PLAYERCHANGEDFLAGS:
- {
- PlayerInfo p;
- fillPlayerInfo(&resp, &p);
- TheGameSpyInfo->updatePlayerInfo(p);
- WOLDisplaySlotList();
- }
- break;
- case PeerResponse::PEERRESPONSE_PLAYERINFO:
- {
- PlayerInfo p;
- fillPlayerInfo(&resp, &p);
- TheGameSpyInfo->updatePlayerInfo(p);
- WOLDisplaySlotList();
- // send out new slotlist if I'm host
- TheGameSpyInfo->setGameOptions();
- }
- break;
- case PeerResponse::PEERRESPONSE_PLAYERJOIN:
- {
- if (resp.player.roomType != StagingRoom)
- {
- break;
- }
- sawImportantMessage = TRUE;
- PlayerInfo p;
- fillPlayerInfo(&resp, &p);
- TheGameSpyInfo->updatePlayerInfo(p);
-
- if (p.m_profileID)
- {
- if (TheGameSpyPSMessageQueue->findPlayerStatsByID(p.m_profileID).id == 0)
- {
- PSRequest req;
- req.requestType = PSRequest::PSREQUEST_READPLAYERSTATS;
- req.player.id = p.m_profileID;
- TheGameSpyPSMessageQueue->addRequest(req);
- }
- }
-
- // check if we have room for the dude
- GameInfo *game = TheGameSpyInfo->getCurrentStagingRoom();
- if (TheGameSpyInfo->amIHost() && game)
- {
- if (TheNAT)
- {
- // ditch him
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMPLAYER;
- req.UTM.isStagingRoom = TRUE;
- req.id = "KICK/";
- req.nick = p.m_name.str();
- req.options = "GameStarted";
- TheGameSpyPeerMessageQueue->addRequest(req);
- }
- else
- {
- // look for room for him
- // See if there's room
- // First get the number of players currently in the room.
- Int numPlayers = 0;
- for (Int player = 0; player < MAX_SLOTS; ++player)
- {
- if (game->getSlot(player)->isOccupied() &&
- game->getSlot(player)->getPlayerTemplate() != PLAYERTEMPLATE_OBSERVER)
- {
- ++numPlayers;
- }
- }
-
- // now get the number of starting spots on the map.
- Int numStartingSpots = MAX_SLOTS;
- const MapMetaData *md = TheMapCache->findMap(game->getMap());
- if (md != NULL)
- {
- numStartingSpots = md->m_numPlayers;
- }
-
- Int openSlotIndex = -1;
- for (Int i=0; igetConstSlot(i);
- if (slot && slot->isOpen())
- {
- openSlotIndex = i;
- break;
- }
- }
-
- if (openSlotIndex >= 0)
- {
- // add him
- GameSlot newSlot;
- UnicodeString uName;
- uName.translate(p.m_name);
- newSlot.setState(SLOT_PLAYER, uName);
- newSlot.setIP(ntohl(resp.player.IP));
- game->setSlot( openSlotIndex, newSlot );
- game->resetAccepted(); // BGC - need to unaccept everyone if someone joins the game.
- }
- else
- {
- // ditch him
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMPLAYER;
- req.UTM.isStagingRoom = TRUE;
- req.id = "KICK/";
- req.nick = p.m_name.str();
- req.options = "GameFull";
- TheGameSpyPeerMessageQueue->addRequest(req);
- }
-
- // send out new slotlist if I'm host
- TheGameSpyInfo->setGameOptions();
- }
- }
- WOLDisplaySlotList();
- }
- break;
-
- case PeerResponse::PEERRESPONSE_PLAYERLEFT:
- {
- sawImportantMessage = TRUE;
- PlayerInfo p;
- fillPlayerInfo(&resp, &p);
- TheGameSpyInfo->playerLeftGroupRoom(resp.nick.c_str());
-
- if (TheGameSpyGame && TheGameSpyGame->isGameInProgress())
- {
- break;
- }
-
- if (TheNAT == NULL) // don't update slot list if we're trying to start a game
- {
-
- GameInfo *game = TheGameSpyInfo->getCurrentStagingRoom();
- if (game && TheGameSpyInfo->amIHost())
- {
- Int idx = game->getSlotNum(resp.nick.c_str());
- if (idx >= 0)
- {
- game->getSlot(idx)->setState(SLOT_OPEN);
- game->resetAccepted(); // BGC - need to unaccept everyone if someone leaves the game.
- }
- }
-
- // send out new slotlist if I'm host
- TheGameSpyInfo->setGameOptions();
- WOLDisplaySlotList();
-
- if (game && !TheGameSpyInfo->amIHost())
- {
- Int idx = game->getSlotNum(resp.nick.c_str());
- if (idx == 0)
- {
- // host left
- buttonPushed = true;
- TheGameSpyInfo->getCurrentStagingRoom()->reset();
- TheGameSpyInfo->leaveStagingRoom();
- //TheGameSpyInfo->joinBestGroupRoom();
- GSMessageBoxOk(TheGameText->fetch("GUI:HostLeftTitle"), TheGameText->fetch("GUI:HostLeft"));
- nextScreen = "Menus/WOLCustomLobby.wnd";
- TheShell->pop();
- }
- }
-
- }
- }
- break;
-
- case PeerResponse::PEERRESPONSE_MESSAGE:
- {
- TheGameSpyInfo->addChat(resp.nick.c_str(), resp.message.profileID,
- UnicodeString(resp.text.c_str()), !resp.message.isPrivate, resp.message.isAction, listboxGameSetupChat);
- }
- break;
-
- case PeerResponse::PEERRESPONSE_DISCONNECT:
- {
- sawImportantMessage = TRUE;
- UnicodeString title, body;
- AsciiString disconMunkee;
- disconMunkee.format("GUI:GSDisconReason%d", resp.discon.reason);
- title = TheGameText->fetch( "GUI:GSErrorTitle" );
- body = TheGameText->fetch( disconMunkee );
- GameSpyCloseAllOverlays();
- GSMessageBoxOk( title, body );
- TheGameSpyInfo->reset();
- TheShell->pop();
- }
-
- case PeerResponse::PEERRESPONSE_ROOMUTM:
- {
- sawImportantMessage = TRUE;
-#if defined(_DEBUG) || defined(_INTERNAL)
- if (g_debugSlots)
- {
- DEBUG_LOG(("About to process a room UTM. Command is '%s', command options is '%s'\n",
- resp.command.c_str(), resp.commandOptions.c_str()));
- }
-#endif
- if (!strcmp(resp.command.c_str(), "SL"))
- {
- // slotlist
- GameSpyStagingRoom *game = TheGameSpyInfo->getCurrentStagingRoom();
- Bool isValidSlotList = game && game->getSlot(0) && game->getSlot(0)->isPlayer( resp.nick.c_str() ) && !TheGameSpyInfo->amIHost();
- if (!isValidSlotList)
- {
- SLOTLIST_DEBUG_LOG(("Not a valid slotlist\n"));
- if (!game)
- {
- SLOTLIST_DEBUG_LOG(("No game!\n"));
- }
- else
- {
- if (!game->getSlot(0))
- {
- SLOTLIST_DEBUG_LOG(("No slot 0!\n"));
- }
- else
- {
- if (TheGameSpyInfo->amIHost())
- {
- SLOTLIST_DEBUG_LOG(("I'm the host!\n"));
- }
- else
- {
- SLOTLIST_DEBUG_LOG(("Not from the host! isHuman:%d, name:'%ls', sender:'%s'\n",
- game->getSlot(0)->isHuman(), game->getSlot(0)->getName().str(),
- resp.nick.c_str()));
- }
- }
- }
- }
- else // isValidSlotList
- {
- Int oldLocalSlotNum = (game->isInGame()) ? game->getLocalSlotNum() : -1;
- Bool wasInGame = oldLocalSlotNum >= 0;
- AsciiString oldMap = game->getMap();
- UnsignedInt oldMapCRC, newMapCRC;
- oldMapCRC = game->getMapCRC();
-
- AsciiString options = resp.commandOptions.c_str();
- options.trim();
- UnsignedShort ports[MAX_SLOTS];
- UnsignedInt ips[MAX_SLOTS];
- Int i;
- for (i=0; igetConstSlot(i))
- {
- ips[i] = game->getConstSlot(i)->getIP();
- ports[i] = game->getConstSlot(i)->getPort();
- }
- else
- {
- ips[i] = 0;
- ports[i] = 0;
- }
- }
- Bool optionsOK = ParseAsciiStringToGameInfo(game, options.str());
- if (TheNAT)
- {
- for (i=0; igetSlot(i))
- {
-#ifdef DEBUG_LOGGING
- UnsignedShort newPort = game->getConstSlot(i)->getPort();
- UnsignedInt newIP = game->getConstSlot(i)->getIP();
- DEBUG_ASSERTLOG(newIP == ips[i], ("IP was different for player %d (%X --> %X)\n",
- i, ips[i], newIP));
- DEBUG_ASSERTLOG(newPort == ports[i], ("Port was different for player %d (%d --> %d)\n",
- i, ports[i], newPort));
-#endif
- game->getSlot(i)->setPort(ports[i]);
- game->getSlot(i)->setIP(ips[i]);
- }
- }
- }
- Int newLocalSlotNum = (game->isInGame()) ? game->getLocalSlotNum() : -1;
- Bool isInGame = newLocalSlotNum >= 0;
- if (!optionsOK)
- {
- SLOTLIST_DEBUG_LOG(("Options are bad! bailing!\n"));
- break;
- }
- else
- {
- SLOTLIST_DEBUG_LOG(("Options are good, local slot is %d\n", newLocalSlotNum));
- if (!isInGame)
- {
- SLOTLIST_DEBUG_LOG(("Not in game; players are:\n"));
- for (Int i=0; igetGameSpySlot(i);
- if (slot && slot->isHuman())
- {
- UnicodeString munkee;
- munkee.format(L"\t%d: %ls", i, slot->getName().str());
- SLOTLIST_DEBUG_LOG(("%ls\n", munkee.str()));
- }
- }
- }
- }
- WOLDisplaySlotList();
-
- // if I changed map availability, send it across
- newMapCRC = game->getMapCRC();
- if (isInGame)
- {
- lastSlotlistTime = timeGetTime();
- if ( (oldMapCRC ^ newMapCRC) || (!wasInGame && isInGame) )
- {
- // it changed. send it
- UnicodeString hostName = TheGameSpyInfo->getCurrentStagingRoom()->getSlot(0)->getName();
- AsciiString asciiName;
- asciiName.translate(hostName);
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMPLAYER;
- req.UTM.isStagingRoom = TRUE;
- req.id = "MAP";
- req.nick = asciiName.str();
- req.options = (game->getSlot(newLocalSlotNum)->hasMap())?"1":"0";
- TheGameSpyPeerMessageQueue->addRequest(req);
- if (!game->getSlot(newLocalSlotNum)->hasMap())
- {
- UnicodeString text;
- UnicodeString mapDisplayName;
- const MapMetaData *mapData = TheMapCache->findMap( game->getMap() );
- Bool willTransfer = TRUE;
- if (mapData)
- {
- mapDisplayName.format(L"%ls", mapData->m_displayName.str());
- willTransfer = !mapData->m_isOfficial;
- }
- else
- {
- mapDisplayName.format(L"%hs", TheGameState->getMapLeafName(game->getMap()).str());
- willTransfer = WouldMapTransfer(game->getMap());
- }
- if (willTransfer)
- text.format(TheGameText->fetch("GUI:LocalPlayerNoMapWillTransfer"), mapDisplayName.str());
- else
- text.format(TheGameText->fetch("GUI:LocalPlayerNoMap"), mapDisplayName.str());
- TheGameSpyInfo->addText(text, GameSpyColor[GSCOLOR_DEFAULT], listboxGameSetupChat);
- }
- }
- if (!initialAcceptEnable)
- {
- buttonStart->winEnable( TRUE );
- initialAcceptEnable = TRUE;
- }
- }
- else
- {
- if (lastSlotlistTime)
- {
- // can't see ourselves
- buttonPushed = true;
- DEBUG_LOG(("Can't see ourselves in slotlist %s\n", options.str()));
- TheGameSpyInfo->getCurrentStagingRoom()->reset();
- TheGameSpyInfo->leaveStagingRoom();
- //TheGameSpyInfo->joinBestGroupRoom();
- GSMessageBoxOk(TheGameText->fetch("GUI:GSErrorTitle"), TheGameText->fetch("GUI:GSKicked"));
- nextScreen = "Menus/WOLCustomLobby.wnd";
- TheShell->pop();
- }
- }
- }
- }
- else if (!strcmp(resp.command.c_str(), "HWS"))
- {
- // host wants to start
- GameInfo *game = TheGameSpyInfo->getCurrentStagingRoom();
- if (game && game->isInGame() && game->getSlot(0) && game->getSlot(0)->isPlayer( resp.nick.c_str() ))
- {
- Int slotNum = game->getLocalSlotNum();
- GameSlot *slot = game->getSlot(slotNum);
- if (slot && (slot->isAccepted() == false))
- {
- TheGameSpyInfo->addText(TheGameText->fetch("GUI:HostWantsToStart"), GameSpyColor[GSCOLOR_DEFAULT], listboxGameSetupChat);
- }
- }
- }
- else if (!stricmp(resp.command.c_str(), "NAT"))
- {
- if (TheNAT != NULL) {
- TheNAT->processGlobalMessage(-1, resp.commandOptions.c_str());
- }
- }
- else if (!stricmp(resp.command.c_str(), "Pings"))
- {
- if (!TheGameSpyInfo->amIHost())
- {
- AsciiString pings = resp.commandOptions.c_str();
- AsciiString token;
- for (Int i=0; igetCurrentStagingRoom()->getGameSpySlot(i);
- if (pings.nextToken(&token, ","))
- {
- token.trim();
- slot->setPingString(token);
- }
- else
- {
- slot->setPingString("");
- }
- }
- }
- }
- }
- break;
-
- case PeerResponse::PEERRESPONSE_PLAYERUTM:
- {
- sawImportantMessage = TRUE;
- if (!strcmp(resp.command.c_str(), "STATS"))
- {
- PSPlayerStats stats = TheGameSpyPSMessageQueue->parsePlayerKVPairs(resp.commandOptions.c_str());
- if (stats.id && (TheGameSpyPSMessageQueue->findPlayerStatsByID(stats.id).id == 0))
- TheGameSpyPSMessageQueue->trackPlayerStats(stats);
- break;
- }
- GameSpyStagingRoom *game = TheGameSpyInfo->getCurrentStagingRoom();
- if (game)
- {
- Int slotNum = game->getSlotNum(resp.nick.c_str());
- if ((slotNum >= 0) && (slotNum < MAX_SLOTS) && (!stricmp(resp.command.c_str(), "NAT"))) {
- // this is a command for NAT negotiations, pass if off to TheNAT
- if (TheNAT != NULL) {
- TheNAT->processGlobalMessage(slotNum, resp.commandOptions.c_str());
- }
- }
- if (slotNum == 0 && !TheGameSpyInfo->amIHost())
- {
- if (!strcmp(resp.command.c_str(), "KICK"))
- {
- // oops - we've been kicked. bail.
- buttonPushed = true;
- TheGameSpyInfo->getCurrentStagingRoom()->reset();
- TheGameSpyInfo->leaveStagingRoom();
- //TheGameSpyInfo->joinBestGroupRoom();
- UnicodeString message = TheGameText->fetch("GUI:GSKicked");
- AsciiString commandMessage = resp.commandOptions.c_str();
- commandMessage.trim();
- DEBUG_LOG(("We were kicked: reason was '%s'\n", resp.commandOptions.c_str()));
- if (commandMessage == "GameStarted")
- {
- message = TheGameText->fetch("GUI:GSKickedGameStarted");
- }
- else if (commandMessage == "GameFull")
- {
- message = TheGameText->fetch("GUI:GSKickedGameFull");
- }
- GSMessageBoxOk(TheGameText->fetch("GUI:GSErrorTitle"), message);
- nextScreen = "Menus/WOLCustomLobby.wnd";
- TheShell->pop();
- }
- }
- else if (slotNum > 0 && TheGameSpyInfo->amIHost())
- {
- if (!strcmp(resp.command.c_str(), "accept"))
- {
- game->getSlot(slotNum)->setAccept();
- TheGameSpyInfo->setGameOptions();
- WOLDisplaySlotList();
- }
- else if (!strcmp(resp.command.c_str(), "MAP"))
- {
- Bool hasMap = atoi(resp.commandOptions.c_str());
- game->getSlot(slotNum)->setMapAvailability(hasMap);
- if (!hasMap)
- {
- // tell the host the user doesn't have the map
- UnicodeString mapDisplayName;
- const MapMetaData *mapData = TheMapCache->findMap( game->getMap() );
- Bool willTransfer = TRUE;
- if (mapData)
- {
- mapDisplayName.format(L"%ls", mapData->m_displayName.str());
- willTransfer = !mapData->m_isOfficial;
- }
- else
- {
- mapDisplayName.format(L"%hs", game->getMap().str());
- willTransfer = WouldMapTransfer(game->getMap());
- }
- UnicodeString text;
- if (willTransfer)
- text.format(TheGameText->fetch("GUI:PlayerNoMapWillTransfer"), game->getSlot(slotNum)->getName().str(), mapDisplayName.str());
- else
- text.format(TheGameText->fetch("GUI:PlayerNoMap"), game->getSlot(slotNum)->getName().str(), mapDisplayName.str());
- TheGameSpyInfo->addText(text, GameSpyColor[GSCOLOR_DEFAULT], listboxGameSetupChat);
- }
- WOLDisplaySlotList();
- }
- else if (!strcmp(resp.command.c_str(), "REQ"))
- {
- AsciiString options = resp.commandOptions.c_str();
- options.trim();
-
- Bool change = false;
- Bool shouldUnaccept = false;
- AsciiString key;
- options.nextToken(&key, "=");
- Int val = atoi(options.str()+1);
- UnsignedInt uVal = atoi(options.str()+1);
- DEBUG_LOG(("GameOpt request: key=%s, val=%s from player %d\n", key.str(), options.str()+1, slotNum));
-
- GameSpyGameSlot *slot = game->getGameSpySlot(slotNum);
- if (!slot)
- break;
-
- if (key == "Color")
- {
- if (val >= -1 && val < TheMultiplayerSettings->getNumColors() && val != slot->getColor() && slot->getPlayerTemplate() != PLAYERTEMPLATE_OBSERVER)
- {
- Bool colorAvailable = TRUE;
- if(val != -1 )
- {
- for(Int i=0; i getSlot(i);
- if(val == checkSlot->getColor() && slot != checkSlot)
- {
- colorAvailable = FALSE;
- break;
- }
- }
- }
- if(colorAvailable)
- slot->setColor(val);
- change = true;
- }
- else
- {
- DEBUG_LOG(("Rejecting invalid color %d\n", val));
- }
- }
- else if (key == "PlayerTemplate")
- {
- if (val >= PLAYERTEMPLATE_MIN && val < ThePlayerTemplateStore->getPlayerTemplateCount() && val != slot->getPlayerTemplate())
- {
- slot->setPlayerTemplate(val);
- if (val == PLAYERTEMPLATE_OBSERVER)
- {
- slot->setColor(-1);
- slot->setStartPos(-1);
- slot->setTeamNumber(-1);
- }
- change = true;
- shouldUnaccept = true;
- }
- else
- {
- DEBUG_LOG(("Rejecting invalid PlayerTemplate %d\n", val));
- }
- }
- else if (key == "StartPos")
- {
- if (val >= -1 && val < MAX_SLOTS && val != slot->getStartPos() && slot->getPlayerTemplate() != PLAYERTEMPLATE_OBSERVER)
- {
- Bool startPosAvailable = TRUE;
- if(val != -1)
- {
- for(Int i=0; i getSlot(i);
- if(val == checkSlot->getStartPos() && slot != checkSlot)
- {
- startPosAvailable = FALSE;
- break;
- }
- }
- }
- if(startPosAvailable)
- slot->setStartPos(val);
- change = true;
- shouldUnaccept = true;
- }
- else
- {
- DEBUG_LOG(("Rejecting invalid startPos %d\n", val));
- }
- }
- else if (key == "Team")
- {
- if (val >= -1 && val < MAX_SLOTS/2 && val != slot->getTeamNumber() && slot->getPlayerTemplate() != PLAYERTEMPLATE_OBSERVER)
- {
- slot->setTeamNumber(val);
- change = true;
- shouldUnaccept = true;
- }
- else
- {
- DEBUG_LOG(("Rejecting invalid team %d\n", val));
- }
- }
- else if (key == "IP")
- {
- if (uVal != slot->getIP())
- {
- DEBUG_LOG(("setting IP of player %ls from 0x%08x to be 0x%08x", slot->getName().str(), slot->getIP(), uVal));
- slot->setIP(uVal);
- change = true;
- shouldUnaccept = true;
- }
- else
- {
- DEBUG_LOG(("Rejecting invalid IP %d\n", uVal));
- }
- }
- else if (key == "NAT")
- {
- if ((val >= FirewallHelperClass::FIREWALL_MIN) &&
- (val <= FirewallHelperClass::FIREWALL_MAX))
- {
- slot->setNATBehavior((FirewallHelperClass::FirewallBehaviorType)val);
- DEBUG_LOG(("Setting NAT behavior to %d for player %d\n", val, slotNum));
- change = true;
- }
- else
- {
- DEBUG_LOG(("Rejecting invalid NAT behavior %d from player %d\n", val, slotNum));
- }
- }
- else if (key == "Ping")
- {
- slot->setPingString(options.str()+1);
- TheGameSpyInfo->setGameOptions();
- DEBUG_LOG(("Setting ping string to %s for player %d\n", options.str()+1, slotNum));
- }
-
- if (change)
- {
- if (shouldUnaccept)
- game->resetAccepted();
-
- TheGameSpyInfo->setGameOptions();
-
- WOLDisplaySlotList();
- DEBUG_LOG(("Slot value is color=%d, PlayerTemplate=%d, startPos=%d, team=%d, IP=0x%8.8X\n",
- slot->getColor(), slot->getPlayerTemplate(), slot->getStartPos(), slot->getTeamNumber(), slot->getIP()));
- DEBUG_LOG(("Slot list updated to %s\n", GameInfoToAsciiString(game).str()));
- }
- }
- }
- }
- }
- break;
-
- }
- }
-
-
- }
-}// void WOLGameSetupMenuUpdate( WindowLayout * layout, void *userData)
-
-//-------------------------------------------------------------------------------------------------
-/** Lan Game Options menu input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLGameSetupMenuInput( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- /*
- switch( msg )
- {
-
- //-------------------------------------------------------------------------------------------------
- case GWM_RIGHT_UP:
- {
- if (buttonPushed)
- break;
-
- GameWindow *control = (GameWindow *)mData1;
- NameKeyType controlID = (NameKeyType)control->winGetWindowId();
- DEBUG_LOG(("GWM_RIGHT_UP for control %d(%s)\n", controlID, TheNameKeyGenerator->keyToName(controlID).str()));
- break;
- }
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
- UnsignedByte key = mData1;
- UnsignedByte state = mData2;
- if (buttonPushed)
- break;
-
- switch( key )
- {
- // ----------------------------------------------------------------------------------------
- case KEY_ESC:
- {
- //
- // send a simulated selected event to the parent window of the
- // back/exit button
- //
- if( BitTest( state, KEY_STATE_UP ) )
- {
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)buttonBack, buttonBackID );
- } // end if
- // don't let key fall through anywhere else
- return MSG_HANDLED;
- } // end escape
- } // end switch( key )
- } // end char
- } // end switch( msg )
- */
- return MSG_IGNORED;
-}//WindowMsgHandledType WOLGameSetupMenuInput( GameWindow *window, UnsignedInt msg,
-
-
-// Slash commands -------------------------------------------------------------------------
-//extern "C" {
-//int getQR2HostingStatus(void);
-//}
-extern int isThreadHosting;
-
-Bool handleGameSetupSlashCommands(UnicodeString uText)
-{
- AsciiString message;
- message.translate(uText);
-
- if (message.getCharAt(0) != '/')
- {
- return FALSE; // not a slash command
- }
-
- AsciiString remainder = message.str() + 1;
- AsciiString token;
- remainder.nextToken(&token);
- token.toLower();
-
- if (token == "host")
- {
- UnicodeString s;
- s.format(L"Hosting qr2:%d thread:%d", 0, isThreadHosting);
- TheGameSpyInfo->addText(s, GameSpyColor[GSCOLOR_DEFAULT], NULL);
- return TRUE; // was a slash command
- }
- else if (token == "me" && uText.getLength()>4)
- {
- TheGameSpyInfo->sendChat(UnicodeString(uText.str()+4), TRUE, NULL);
- return TRUE; // was a slash command
- }
-#if defined(_DEBUG) || defined(_INTERNAL)
- else if (token == "slots")
- {
- g_debugSlots = !g_debugSlots;
- TheGameSpyInfo->addText(UnicodeString(L"Toggled SlotList debug"), GameSpyColor[GSCOLOR_DEFAULT], NULL);
- return TRUE; // was a slash command
- }
- else if (token == "discon")
- {
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_LOGOUT;
- TheGameSpyPeerMessageQueue->addRequest( req );
- return TRUE;
- }
-#endif // defined(_DEBUG) || defined(_INTERNAL)
-
- return FALSE; // not a slash command
-}
-
-static Int getNextSelectablePlayer(Int start)
-{
- GameSpyStagingRoom *game = TheGameSpyInfo->getCurrentStagingRoom();
- if (!game->amIHost())
- return -1;
- for (Int j=start; jgetGameSpySlot(j);
- if (slot && slot->getStartPos() == -1 &&
- ( (j==game->getLocalSlotNum() && game->getConstSlot(j)->getPlayerTemplate()!=PLAYERTEMPLATE_OBSERVER)
- || slot->isAI()))
- {
- return j;
- }
- }
- return -1;
-}
-
-static Int getFirstSelectablePlayer(const GameInfo *game)
-{
- const GameSlot *slot = game->getConstSlot(game->getLocalSlotNum());
- if (!game->amIHost() || slot && slot->getPlayerTemplate() != PLAYERTEMPLATE_OBSERVER)
- return game->getLocalSlotNum();
-
- for (Int i=0; igetConstSlot(i);
- if (slot && slot->isAI())
- return i;
- }
-
- return game->getLocalSlotNum();
-}
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Game Options menu window system callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLGameSetupMenuSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- UnicodeString txtInput;
- static buttonCommunicatorID = NAMEKEY_INVALID;
- switch( msg )
- {
- //-------------------------------------------------------------------------------------------------
- case GWM_CREATE:
- {
- buttonCommunicatorID = NAMEKEY("GameSpyGameOptionsMenu.wnd:ButtonCommunicator");
- break;
- } // case GWM_DESTROY:
- //-------------------------------------------------------------------------------------------------
- case GWM_DESTROY:
- {
- break;
- } // case GWM_DESTROY:
- //-------------------------------------------------------------------------------------------------
- case GWM_INPUT_FOCUS:
- {
- // if we're givin the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
-
- return MSG_HANDLED;
- }//case GWM_INPUT_FOCUS:
- //-------------------------------------------------------------------------------------------------
- case GCM_SELECTED:
- {
- if (!initDone)
- break;
- if (buttonPushed)
- break;
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- GameSpyStagingRoom *myGame = TheGameSpyInfo->getCurrentStagingRoom();
- for (Int i = 0; i < MAX_SLOTS; i++)
- {
- if (controlID == comboBoxColorID[i])
- {
- handleColorSelection(i);
- }
- else if (controlID == comboBoxPlayerTemplateID[i])
- {
- handlePlayerTemplateSelection(i);
- }
- else if (controlID == comboBoxTeamID[i])
- {
- handleTeamSelection(i);
- }
- else if( controlID == comboBoxPlayerID[i] && TheGameSpyInfo->amIHost() )
- {
- // We don't have anything that'll happen if we click on ourselves
- if(i == myGame->getLocalSlotNum())
- break;
- // Get
- Int pos = -1;
- GadgetComboBoxGetSelectedPos(comboBoxPlayer[i], &pos);
- if( pos != SLOT_PLAYER && pos >= 0)
- {
- if( myGame->getSlot(i)->getState() == SLOT_PLAYER )
- {
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMPLAYER;
- req.UTM.isStagingRoom = TRUE;
- AsciiString aName;
- aName.translate(myGame->getSlot(i)->getName());
- req.nick = aName.str();
- req.id = "KICK/";
- req.options = "true";
- TheGameSpyPeerMessageQueue->addRequest(req);
-
- UnicodeString name = myGame->getSlot(i)->getName();
- myGame->getSlot(i)->setState(SlotState(pos));
- myGame->resetAccepted();
- TheGameSpyInfo->setGameOptions();
- WOLDisplaySlotList();
- //TheLAN->OnPlayerLeave(name);
- }
- else if( myGame->getSlot(i)->getState() != pos )
- {
- Bool wasAI = (myGame->getSlot(i)->isAI());
- myGame->getSlot(i)->setState(SlotState(pos));
- Bool isAI = (myGame->getSlot(i)->isAI());
- myGame->resetAccepted();
- if (wasAI ^ isAI)
- PopulatePlayerTemplateComboBox(i, comboBoxPlayerTemplate, myGame, wasAI && myGame->getAllowObservers());
- TheGameSpyInfo->setGameOptions();
- WOLDisplaySlotList();
- }
- }
- break;
- }
- }
- }// case GCM_SELECTED:
- //-------------------------------------------------------------------------------------------------
- case GBM_SELECTED:
- {
- if (buttonPushed)
- break;
-
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- static buttonCommunicatorID = NAMEKEY("GameSpyGameOptionsMenu.wnd:ButtonCommunicator");
-
- if ( controlID == buttonBackID )
- {
- savePlayerInfo();
- if( WOLMapSelectLayout )
- {
- WOLMapSelectLayout->destroyWindows();
- WOLMapSelectLayout->deleteInstance();
- WOLMapSelectLayout = NULL;
- }
-
- TheGameSpyInfo->getCurrentStagingRoom()->reset();
- //peerLeaveRoom(TheGameSpyChat->getPeer(), StagingRoom, NULL);
- TheGameSpyInfo->leaveStagingRoom();
- buttonPushed = true;
- nextScreen = "Menus/WOLCustomLobby.wnd";
- TheShell->pop();
-
- } //if ( controlID == buttonBack )
- else if ( controlID == buttonCommunicatorID )
- {
- GameSpyToggleOverlay( GSOVERLAY_BUDDY );
-
- }
- else if ( controlID == buttonEmoteID )
- {
- // read the user's input
- txtInput.set(GadgetTextEntryGetText( textEntryChat ));
- // Clear the text entry line
- GadgetTextEntrySetText(textEntryChat, UnicodeString::TheEmptyString);
- // Clean up the text (remove leading/trailing chars, etc)
- txtInput.trim();
- // Echo the user's input to the chat window
- if (!txtInput.isEmpty())
- TheGameSpyInfo->sendChat(txtInput, FALSE, NULL); // 'emote' button is now carriage-return
- } //if ( controlID == buttonEmote )
- else if ( controlID == buttonSelectMapID )
- {
- WOLMapSelectLayout = TheWindowManager->winCreateLayout( "Menus/WOLMapSelectMenu.wnd" );
- WOLMapSelectLayout->runInit();
- WOLMapSelectLayout->hide( FALSE );
- WOLMapSelectLayout->bringForward();
- }
- else if ( controlID == buttonStartID )
- {
- savePlayerInfo();
- if (TheGameSpyInfo->amIHost())
- {
- StartPressed();
- }
- else
- {
- //I'm the Client... send an accept message to the host.
- GameSlot *localSlot = TheGameSpyInfo->getCurrentStagingRoom()->getSlot(TheGameSpyInfo->getCurrentStagingRoom()->getLocalSlotNum());
- if (localSlot)
- {
- localSlot->setAccept();
- }
- UnicodeString hostName = TheGameSpyInfo->getCurrentStagingRoom()->getSlot(0)->getName();
- AsciiString asciiName;
- asciiName.translate(hostName);
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMPLAYER;
- req.UTM.isStagingRoom = TRUE;
- req.id = "accept";
- req.nick = asciiName.str();
- req.options = "true";
- TheGameSpyPeerMessageQueue->addRequest(req);
- //peerSetReady( PEER, PEERTrue );
- WOLDisplaySlotList();
- }
- }
- else
- {
- for (Int i = 0; i < MAX_SLOTS; i++)
- {
- if (controlID == buttonMapStartPositionID[i])
- {
- GameSpyStagingRoom *game = TheGameSpyInfo->getCurrentStagingRoom();
- Int playerIdxInPos = -1;
- for (Int j=0; jgetGameSpySlot(j);
- if (slot && slot->getStartPos() == i)
- {
- playerIdxInPos = j;
- break;
- }
- }
- if (playerIdxInPos >= 0)
- {
- GameSpyGameSlot *slot = game->getGameSpySlot(playerIdxInPos);
- if (playerIdxInPos == game->getLocalSlotNum() || (game->amIHost() && slot && slot->isAI()))
- {
- // it's one of my type. Try to change it.
- Int nextPlayer = getNextSelectablePlayer(playerIdxInPos+1);
- handleStartPositionSelection(playerIdxInPos, -1);
- if (nextPlayer >= 0)
- {
- handleStartPositionSelection(nextPlayer, i);
- }
- }
- }
- else
- {
- // nobody in the slot - put us in
- Int nextPlayer = getNextSelectablePlayer(0);
- if (nextPlayer < 0)
- nextPlayer = getFirstSelectablePlayer(game);
- handleStartPositionSelection(nextPlayer, i);
- }
- }
- }
- }
-
-
- break;
- }// case GBM_SELECTED:
- //-------------------------------------------------------------------------------------------------
- case GBM_SELECTED_RIGHT:
- {
- if (buttonPushed)
- break;
-
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- for (Int i = 0; i < MAX_SLOTS; i++)
- {
- if (controlID == buttonMapStartPositionID[i])
- {
- GameSpyStagingRoom *game = TheGameSpyInfo->getCurrentStagingRoom();
- Int playerIdxInPos = -1;
- for (Int j=0; jgetGameSpySlot(j);
- if (slot && slot->getStartPos() == i)
- {
- playerIdxInPos = j;
- break;
- }
- }
- if (playerIdxInPos >= 0)
- {
- GameSpyGameSlot *slot = game->getGameSpySlot(playerIdxInPos);
- if (playerIdxInPos == game->getLocalSlotNum() || (game->amIHost() && slot && slot->isAI()))
- {
- // it's one of my type. Remove it.
- handleStartPositionSelection(playerIdxInPos, -1);
- }
- }
- }
- }
- break;
- }
-
- //-------------------------------------------------------------------------------------------------
- case GEM_EDIT_DONE:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- // Take the user's input and echo it into the chat window as well as
- // send it to the other clients on the lan
- if ( controlID == textEntryChatID )
- {
-
- // read the user's input
- txtInput.set(GadgetTextEntryGetText( textEntryChat ));
- // Clear the text entry line
- GadgetTextEntrySetText(textEntryChat, UnicodeString::TheEmptyString);
- // Clean up the text (remove leading/trailing chars, etc)
- txtInput.trim();
- // Echo the user's input to the chat window
- if (!txtInput.isEmpty())
- {
- if (!handleGameSetupSlashCommands(txtInput))
- {
- TheGameSpyInfo->sendChat(txtInput, false, NULL);
- }
- }
-
- }// if ( controlID == textEntryChatID )
- break;
- }
- //-------------------------------------------------------------------------------------------------
- default:
- return MSG_IGNORED;
- }//Switch
- return MSG_HANDLED;
-}//WindowMsgHandledType WOLGameSetupMenuSystem( GameWindow *window, UnsignedInt msg,
-
-
diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLadderScreen.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLadderScreen.cpp
deleted file mode 100644
index ae044416076..00000000000
--- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLadderScreen.cpp
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: ReplayMenu.cpp /////////////////////////////////////////////////////////////////////
-// Author: Chris The masta Huybregts, December 2001
-// Description: Replay Menus
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/GameEngine.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Shell.h"
-#include "GameClient/KeyDefs.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/MessageBox.h"
-
-// window ids -------------------------------------------------------------------------------------
-static NameKeyType parentWindowID = NAMEKEY_INVALID;
-static NameKeyType buttonBackID = NAMEKEY_INVALID;
-static NameKeyType windowLadderID = NAMEKEY_INVALID;
-
-
-// window pointers --------------------------------------------------------------------------------
-static GameWindow *parentWindow = NULL;
-static GameWindow *buttonBack = NULL;
-static GameWindow *windowLadder = NULL;
-
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the single player menu */
-//-------------------------------------------------------------------------------------------------
-void WOLLadderScreenInit( WindowLayout *layout, void *userData )
-{
- TheShell->showShellMap(TRUE);
-
- // get ids for our children controls
- parentWindowID = TheNameKeyGenerator->nameToKey( AsciiString("WOLLadderScreen.wnd:LadderParent") );
- buttonBackID = TheNameKeyGenerator->nameToKey( AsciiString("WOLLadderScreen.wnd:ButtonBack") );
- windowLadderID = TheNameKeyGenerator->nameToKey( AsciiString("WOLLadderScreen.wnd:WindowLadder") );
-
- parentWindow = TheWindowManager->winGetWindowFromId( NULL, parentWindowID );
- buttonBack = TheWindowManager->winGetWindowFromId( parentWindow, buttonBackID );
- windowLadder = TheWindowManager->winGetWindowFromId( parentWindow, windowLadderID );
-
- //Load the listbox shiznit
-// PopulateReplayFileListbox(listboxReplayFiles);
-
- // show menu
- layout->hide( FALSE );
-
- // set keyboard focus to main parent
- TheWindowManager->winSetFocus( parentWindow );
-
-} // end ReplayMenuInit
-
-//-------------------------------------------------------------------------------------------------
-/** single player menu shutdown method */
-//-------------------------------------------------------------------------------------------------
-void WOLLadderScreenShutdown( WindowLayout *layout, void *userData )
-{
-
- // hide menu
- layout->hide( TRUE );
-
- // our shutdown is complete
- TheShell->shutdownComplete( layout );
-
-} // end ReplayMenuShutdown
-
-//-------------------------------------------------------------------------------------------------
-/** single player menu update method */
-//-------------------------------------------------------------------------------------------------
-void WOLLadderScreenUpdate( WindowLayout *layout, void *userData )
-{
-
-} // end ReplayMenuUpdate
-
-//-------------------------------------------------------------------------------------------------
-/** Replay menu input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLLadderScreenInput( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
-
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
- UnsignedByte key = mData1;
- UnsignedByte state = mData2;
-
- switch( key )
- {
-
- // ----------------------------------------------------------------------------------------
- case KEY_ESC:
- {
-
- //
- // send a simulated selected event to the parent window of the
- // back/exit button
- //
- if( BitTest( state, KEY_STATE_UP ) )
- {
-
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)buttonBack, buttonBackID );
-
- } // end if
-
- // don't let key fall through anywhere else
- return MSG_HANDLED;
-
- } // end escape
-
- } // end switch( key )
-
- } // end char
-
- } // end switch( msg )
-
- return MSG_IGNORED;
-
-} // end ReplayMenuInput
-
-//-------------------------------------------------------------------------------------------------
-/** single player menu window system callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLLadderScreenSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
-
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CREATE:
- {
-
-
- break;
-
- } // end create
-
- //---------------------------------------------------------------------------------------------
- case GWM_DESTROY:
- {
-
- break;
-
- } // end case
-
- // --------------------------------------------------------------------------------------------
- case GWM_INPUT_FOCUS:
- {
-
- // if we're givin the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
-
- return MSG_HANDLED;
-
- } // end input
- //---------------------------------------------------------------------------------------------
- case GBM_SELECTED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if( controlID == buttonBackID )
- {
-
- // thou art directed to return to thy known solar system immediately!
- TheShell->pop();
-
- } // end else if
-
- break;
-
- } // end selected
-
- default:
- return MSG_IGNORED;
- } // end switch
-
- return MSG_HANDLED;
-} // end ReplayMenuSystem
-
diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLobbyMenu.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLobbyMenu.cpp
deleted file mode 100644
index 63d64aa6780..00000000000
--- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLobbyMenu.cpp
+++ /dev/null
@@ -1,1857 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////////////
-// FILE: WOLLobbyMenu.cpp
-// Author: Chris Huybregts, November 2001
-// Description: WOL Lobby Menu
-///////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/GameEngine.h"
-#include "Common/GameState.h"
-#include "Common/MiniLog.h"
-#include "Common/MultiplayerSettings.h"
-#include "Common/PlayerTemplate.h"
-#include "Common/CustomMatchPreferences.h"
-#include "Common/Version.h"
-#include "GameClient/AnimateWindowManager.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/GameClient.h"
-#include "GameClient/Shell.h"
-#include "GameClient/ShellHooks.h"
-#include "GameClient/KeyDefs.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/GadgetComboBox.h"
-#include "GameClient/GadgetListBox.h"
-#include "GameClient/GadgetSlider.h"
-#include "GameClient/GadgetTextEntry.h"
-#include "GameClient/GameText.h"
-#include "GameClient/MessageBox.h"
-#include "GameClient/Mouse.h"
-#include "GameClient/Display.h"
-#include "GameNetwork/GameSpyOverlay.h"
-#include "GameClient/GameWindowTransitions.h"
-
-#include "GameLogic/GameLogic.h"
-
-#include "GameClient/LanguageFilter.h"
-#include "GameNetwork/GameSpy/BuddyDefs.h"
-#include "GameNetwork/GameSpy/GSConfig.h"
-#include "GameNetwork/GameSpy/LadderDefs.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpy/PeerThread.h"
-#include "GameNetwork/GameSpy/PersistentStorageDefs.h"
-#include "GameNetwork/GameSpy/PersistentStorageThread.h"
-#include "GameNetwork/GameSpy/LobbyUtils.h"
-#include "GameNetwork/RankPointValue.h"
-
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-void refreshGameList( Bool forceRefresh = FALSE );
-void refreshPlayerList( Bool forceRefresh = FALSE );
-
-#ifdef DEBUG_LOGGING
-#define PERF_TEST
-static LogClass s_perfLog("Perf.txt");
-#define PERF_LOG(x) s_perfLog.log x
-#else // DEBUG_LOGGING
-#define PERF_LOG(x) {}
-#endif // DEBUG_LOGGING
-
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-static Bool isShuttingDown = false;
-static Bool buttonPushed = false;
-static char *nextScreen = NULL;
-static Bool raiseMessageBoxes = false;
-static time_t gameListRefreshTime = 0;
-static const time_t gameListRefreshInterval = 10000;
-static time_t playerListRefreshTime = 0;
-static const time_t playerListRefreshInterval = 5000;
-
-void setUnignoreText( WindowLayout *layout, AsciiString nick, GPProfile id);
-static void doSliderTrack(GameWindow *control, Int val);
-Bool DontShowMainMenu = FALSE;
-enum { COLUMN_PLAYERNAME = 2 };
-
-// window ids ------------------------------------------------------------------------------
-static NameKeyType parentWOLLobbyID = NAMEKEY_INVALID;
-static NameKeyType buttonBackID = NAMEKEY_INVALID;
-static NameKeyType buttonHostID = NAMEKEY_INVALID;
-static NameKeyType buttonRefreshID = NAMEKEY_INVALID;
-static NameKeyType buttonJoinID = NAMEKEY_INVALID;
-static NameKeyType buttonBuddyID = NAMEKEY_INVALID;
-static NameKeyType buttonEmoteID = NAMEKEY_INVALID;
-static NameKeyType textEntryChatID = NAMEKEY_INVALID;
-static NameKeyType listboxLobbyPlayersID = NAMEKEY_INVALID;
-static NameKeyType listboxLobbyChatID = NAMEKEY_INVALID;
-static NameKeyType comboLobbyGroupRoomsID = NAMEKEY_INVALID;
-//static NameKeyType // sliderChatAdjustID = NAMEKEY_INVALID;
-
-// Window Pointers ------------------------------------------------------------------------
-static GameWindow *parentWOLLobby = NULL;
-static GameWindow *buttonBack = NULL;
-static GameWindow *buttonHost = NULL;
-static GameWindow *buttonRefresh = NULL;
-static GameWindow *buttonJoin = NULL;
-static GameWindow *buttonBuddy = NULL;
-static GameWindow *buttonEmote = NULL;
-static GameWindow *textEntryChat = NULL;
-static GameWindow *listboxLobbyPlayers = NULL;
-static GameWindow *listboxLobbyChat = NULL;
-static GameWindow *comboLobbyGroupRooms = NULL;
-static GameWindow *parent = NULL;
-
-static Int groupRoomToJoin = 0;
-static Int initialGadgetDelay = 2;
-static Bool justEntered = FALSE;
-
-#if defined(_INTERNAL) || defined(_DEBUG)
-Bool g_fakeCRC = FALSE;
-Bool g_debugSlots = FALSE;
-#endif
-
-std::list TheLobbyQueuedUTMs;
-
-// Slash commands -------------------------------------------------------------------------
-//extern "C" {
-//int getQR2HostingStatus(void);
-//}
-extern int isThreadHosting;
-
-Bool handleLobbySlashCommands(UnicodeString uText)
-{
- AsciiString message;
- message.translate(uText);
-
- if (message.getCharAt(0) != '/')
- {
- return FALSE; // not a slash command
- }
-
- AsciiString remainder = message.str() + 1;
- AsciiString token;
- remainder.nextToken(&token);
- token.toLower();
-
- if (token == "host")
- {
- UnicodeString s;
- s.format(L"Hosting qr2:%d thread:%d", 0, isThreadHosting);
- TheGameSpyInfo->addText(s, GameSpyColor[GSCOLOR_DEFAULT], NULL);
- return TRUE; // was a slash command
- }
- else if (token == "me" && uText.getLength()>4)
- {
- TheGameSpyInfo->sendChat(UnicodeString(uText.str()+4), TRUE, listboxLobbyPlayers);
- return TRUE; // was a slash command
- }
- else if (token == "refresh")
- {
- // Added 2/19/03 added the game refresh
- refreshGameList(TRUE);
- refreshPlayerList(TRUE);
- return TRUE; // was a slash command
- }
- /*
- if (token == "togglegamelist")
- {
- NameKeyType buttonID = NAMEKEY("WOLCustomLobby.wnd:ButtonGameListToggle");
- GameWindow *button = TheWindowManager->winGetWindowFromId(parent, buttonID);
- if (button)
- {
- button->winHide(!button->winIsHidden());
- }
- return TRUE; // was a slash command
- }
- else if (token == "adjustchat")
- {
- NameKeyType sliderID = NAMEKEY("WOLCustomLobby.wnd:SliderChatAdjust");
- GameWindow *slider = TheWindowManager->winGetWindowFromId(parent, sliderID);
- if (slider)
- {
- slider->winHide(!slider->winIsHidden());
- }
- return TRUE; // was a slash command
- }
- */
-#if defined(_INTERNAL) || defined(_DEBUG)
- else if (token == "fakecrc")
- {
- g_fakeCRC = !g_fakeCRC;
- TheGameSpyInfo->addText(UnicodeString(L"Toggled CRC fakery"), GameSpyColor[GSCOLOR_DEFAULT], NULL);
- return TRUE; // was a slash command
- }
- else if (token == "slots")
- {
- g_debugSlots = !g_debugSlots;
- TheGameSpyInfo->addText(UnicodeString(L"Toggled SlotList debug"), GameSpyColor[GSCOLOR_DEFAULT], NULL);
- return TRUE; // was a slash command
- }
-#endif
-
- return FALSE; // not a slash command
-}
-
-static Bool s_tryingToHostOrJoin = FALSE;
-void SetLobbyAttemptHostJoin(Bool start)
-{
- s_tryingToHostOrJoin = start;
-}
-
-// Tooltips -------------------------------------------------------------------------------
-
-static void playerTooltip(GameWindow *window,
- WinInstanceData *instData,
- UnsignedInt mouse)
-{
- Int x, y, row, col;
- x = LOLONGTOSHORT(mouse);
- y = HILONGTOSHORT(mouse);
-
- GadgetListBoxGetEntryBasedOnXY(window, x, y, row, col);
-
- if (row == -1 || col == -1)
- {
- TheMouse->setCursorTooltip( UnicodeString::TheEmptyString);//TheGameText->fetch("TOOLTIP:PlayersInLobby") );
- return;
- }
-
- UnicodeString uName = GadgetListBoxGetText(window, row, 2);
- AsciiString aName;
- aName.translate(uName);
-
- PlayerInfoMap::iterator it = TheGameSpyInfo->getPlayerInfoMap()->find(aName);
- PlayerInfo *info = &(it->second);
- Bool isLocalPlayer = (TheGameSpyInfo->getLocalName().compareNoCase(info->m_name) == 0);
-
- if (col == 0)
- {
- if (info->m_preorder)
- {
- TheMouse->setCursorTooltip( TheGameText->fetch("TOOLTIP:LobbyOfficersClub") );
- }
- else
- {
- TheMouse->setCursorTooltip( UnicodeString::TheEmptyString);
- }
- return;
- }
-
- AsciiString playerLocale = info->m_locale;
- AsciiString localeIdentifier;
- localeIdentifier.format("WOL:Locale%2.2d", atoi(playerLocale.str()));
- Int playerWins = info->m_wins;
- Int playerLosses = info->m_losses;
- UnicodeString playerInfo;
- playerInfo.format(TheGameText->fetch("TOOLTIP:PlayerInfo"), TheGameText->fetch(localeIdentifier).str(), playerWins, playerLosses);
-
- UnicodeString tooltip = UnicodeString::TheEmptyString;//TheGameText->fetch("TOOLTIP:PlayersInLobby");
- if (isLocalPlayer)
- {
- tooltip.format(TheGameText->fetch("TOOLTIP:LocalPlayer"), uName.str());
- }
- else
- {
- // not us
- if (TheGameSpyInfo->getBuddyMap()->find(info->m_profileID) != TheGameSpyInfo->getBuddyMap()->end())
- {
- // buddy
- tooltip.format(TheGameText->fetch("TOOLTIP:BuddyPlayer"), uName.str());
- }
- else
- {
- if (info->m_profileID)
- {
- // non-buddy profiled player
- tooltip.format(TheGameText->fetch("TOOLTIP:ProfiledPlayer"), uName.str());
- }
- else
- {
- // non-profiled player
- tooltip.format(TheGameText->fetch("TOOLTIP:GenericPlayer"), uName.str());
- }
- }
- }
-
- if (info->isIgnored())
- {
- tooltip.concat(TheGameText->fetch("TOOLTIP:IgnoredModifier"));
- }
-
- if (info->m_profileID)
- {
- tooltip.concat(playerInfo);
- }
-
- Int rank = 0;
- Int i = 0;
- while( info->m_rankPoints >= TheRankPointValues->m_ranks[i + 1])
- ++i;
- rank = i;
- AsciiString sideName = "GUI:RandomSide";
- if (info->m_side > 0)
- {
- const PlayerTemplate *fac = ThePlayerTemplateStore->getNthPlayerTemplate(info->m_side);
- if (fac)
- {
- sideName.format("SIDE:%s", fac->getSide().str());
- }
- }
- AsciiString rankName;
- rankName.format("GUI:GSRank%d", rank);
- UnicodeString tmp;
- tmp.format(L"\n%ls %ls", TheGameText->fetch(sideName).str(), TheGameText->fetch(rankName).str());
- tooltip.concat(tmp);
-
- TheMouse->setCursorTooltip( tooltip, -1, NULL, 1.5f ); // the text and width are the only params used. the others are the default values.
-}
-
-static void populateGroupRoomListbox(GameWindow *lb)
-{
- if (!lb)
- return;
-
- GadgetComboBoxReset(lb);
- Int indexToSelect = -1;
- GroupRoomMap::iterator iter;
-
- // now populate the combo box
- for (iter = TheGameSpyInfo->getGroupRoomList()->begin(); iter != TheGameSpyInfo->getGroupRoomList()->end(); ++iter)
- {
- GameSpyGroupRoom room = iter->second;
- if (room.m_groupID != TheGameSpyConfig->getQMChannel())
- {
- DEBUG_LOG(("populateGroupRoomListbox(): groupID %d\n", room.m_groupID));
- if (room.m_groupID == TheGameSpyInfo->getCurrentGroupRoom())
- {
- Int selected = GadgetComboBoxAddEntry(lb, room.m_translatedName, GameSpyColor[GSCOLOR_CURRENTROOM]);
- GadgetComboBoxSetItemData(lb, selected, (void *)(room.m_groupID));
- indexToSelect = selected;
- }
- else
- {
- Int selected = GadgetComboBoxAddEntry(lb, room.m_translatedName, GameSpyColor[GSCOLOR_ROOM]);
- GadgetComboBoxSetItemData(lb, selected, (void *)(room.m_groupID));
- }
- }
- else
- {
- DEBUG_LOG(("populateGroupRoomListbox(): skipping QM groupID %d\n", room.m_groupID));
- }
- }
-
- GadgetComboBoxSetSelectedPos(lb, indexToSelect);
-}
-
-static const char *rankNames[] = {
- "Private",
- "Corporal",
- "Sergeant",
- "Lieutenant",
- "Captain",
- "Major",
- "Colonel",
- "General",
- "Brigadier",
- "Commander",
-};
-
-const Image* LookupSmallRankImage(Int side, Int rankPoints)
-{
- if (rankPoints == 0)
- return NULL;
-
- Int rank = 0;
- Int i = 0;
- while( rankPoints >= TheRankPointValues->m_ranks[i + 1])
- ++i;
- rank = i;
-
- if (rank < 0 || rank >= 10)
- return NULL;
-
- AsciiString sideStr = "N";
- switch(side)
- {
- case 2:
- sideStr = "USA";
- break;
- case 3:
- sideStr = "CHA";
- break;
- case 4:
- sideStr = "GLA";
- break;
- }
-
- AsciiString fullImageName;
- fullImageName.format("%s-%s", rankNames[rank], sideStr.str());
- const Image *img = TheMappedImageCollection->findImageByName(fullImageName);
- DEBUG_ASSERTLOG(img, ("*** Could not load small rank image '%s' from TheMappedImageCollection!\n", fullImageName.str()));
- return img;
-}
-
-static Int insertPlayerInListbox(const PlayerInfo& info, Color color)
-{
- UnicodeString uStr;
- uStr.translate(info.m_name);
-
- Int currentRank = info.m_rankPoints;
- Int currentSide = info.m_side;
- /* since PersistentStorage updates now update PlayerInfo, we don't need this.
- if (info.m_profileID)
- {
- PSPlayerStats psStats = TheGameSpyPSMessageQueue->findPlayerStatsByID(info.m_profileID);
- if (psStats.id)
- {
- currentRank = CalculateRank(psStats);
-
- PerGeneralMap::iterator it;
- Int numGames = 0;
- for(it = psStats.games.begin(); it != psStats.games.end(); ++it)
- {
- if(it->second >= numGames)
- {
- numGames = it->second;
- currentSide = it->first;
- }
- }
- if(numGames == 0 || psStats.gamesAsRandom >= numGames )
- {
- currentSide = 0;
- }
- }
- }
- */
-
- Bool isPreorder = TheGameSpyInfo->didPlayerPreorder(info.m_profileID);
-
- const Image *preorderImg = TheMappedImageCollection->findImageByName("OfficersClubsmall");
- Int w = (preorderImg)?preorderImg->getImageWidth():10;
- //Int h = (preorderImg)?preorderImg->getImageHeight():10;
- w = min(GadgetListBoxGetColumnWidth(listboxLobbyPlayers, 0), w);
- Int h = w;
- if (!isPreorder)
- preorderImg = NULL;
-
- const Image *rankImg = LookupSmallRankImage(currentSide, currentRank);
-
- Int index = GadgetListBoxAddEntryImage(listboxLobbyPlayers, preorderImg, -1, 0, w, h);
- GadgetListBoxAddEntryImage(listboxLobbyPlayers, rankImg, index, 1, w, h);
- GadgetListBoxAddEntryText(listboxLobbyPlayers, uStr, color, index, 2);
-
- return index;
-}
-
-void PopulateLobbyPlayerListbox(void)
-{
- if (!listboxLobbyPlayers)
- return;
-
- // Display players
- PlayerInfoMap *players = TheGameSpyInfo->getPlayerInfoMap();
- PlayerInfoMap::iterator it;
- BuddyInfoMap *buddies = TheGameSpyInfo->getBuddyMap();
- BuddyInfoMap::iterator bIt;
- if (listboxLobbyPlayers)
- {
- // save off old selection
- Int maxSelectedItems = GadgetListBoxGetNumEntries(listboxLobbyPlayers);
- Int *selectedIndices;
- GadgetListBoxGetSelected(listboxLobbyPlayers, (Int *)(&selectedIndices));
- std::set selectedNames;
- std::set::const_iterator selIt;
- std::set indicesToSelect;
- UnicodeString uStr;
- Int numSelected = 0;
- for (Int i=0; ibegin(); it != players->end(); ++it)
- {
- PlayerInfo info = it->second;
- if (info.m_flags & PEER_FLAG_OP || TheGameSpyConfig->isPlayerVIP(info.m_profileID))
- {
- Int index = insertPlayerInListbox(info, info.isIgnored()?GameSpyColor[GSCOLOR_PLAYER_IGNORED]:GameSpyColor[GSCOLOR_PLAYER_OWNER]);
-
- selIt = selectedNames.find(info.m_name);
- if (selIt != selectedNames.end())
- {
- DEBUG_LOG(("Marking index %d (%s) to re-select\n", index, info.m_name.str()));
- indicesToSelect.insert(index);
- }
- }
- }
-
- // Buddies
- for (it = players->begin(); it != players->end(); ++it)
- {
- PlayerInfo info = it->second;
- bIt = buddies->find(info.m_profileID);
- if ( !(info.m_flags & PEER_FLAG_OP || TheGameSpyConfig->isPlayerVIP(info.m_profileID)) && bIt != buddies->end() )
- {
- Int index = insertPlayerInListbox(info, info.isIgnored()?GameSpyColor[GSCOLOR_PLAYER_IGNORED]:GameSpyColor[GSCOLOR_PLAYER_BUDDY]);
-
- selIt = selectedNames.find(info.m_name);
- if (selIt != selectedNames.end())
- {
- DEBUG_LOG(("Marking index %d (%s) to re-select\n", index, info.m_name.str()));
- indicesToSelect.insert(index);
- }
- }
- }
-
- // Everyone else
- for (it = players->begin(); it != players->end(); ++it)
- {
- PlayerInfo info = it->second;
- bIt = buddies->find(info.m_profileID);
- if ( !(info.m_flags & PEER_FLAG_OP || TheGameSpyConfig->isPlayerVIP(info.m_profileID)) && bIt == buddies->end() )
- {
- Int index = insertPlayerInListbox(info, info.isIgnored()?GameSpyColor[GSCOLOR_PLAYER_IGNORED]:GameSpyColor[GSCOLOR_PLAYER_NORMAL]);
-
- selIt = selectedNames.find(info.m_name);
- if (selIt != selectedNames.end())
- {
- DEBUG_LOG(("Marking index %d (%s) to re-select\n", index, info.m_name.str()));
- indicesToSelect.insert(index);
- }
- }
- }
-
- // restore selection
- if (indicesToSelect.size())
- {
- std::set::const_iterator indexIt;
- Int *newIndices = NEW Int[indicesToSelect.size()];
- for (i=0, indexIt = indicesToSelect.begin(); indexIt != indicesToSelect.end(); ++i, ++indexIt)
- {
- newIndices[i] = *indexIt;
- DEBUG_LOG(("Queueing up index %d to re-select\n", *indexIt));
- }
- GadgetListBoxSetSelected(listboxLobbyPlayers, newIndices, indicesToSelect.size());
- delete[] newIndices;
- }
-
- if (indicesToSelect.size() != numSelected)
- {
- TheWindowManager->winSetLoneWindow(NULL);
- }
-
- // restore top visible entry
- GadgetListBoxSetTopVisibleEntry(listboxLobbyPlayers, previousTopIndex);
- }
-
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the WOL Lobby Menu */
-//-------------------------------------------------------------------------------------------------
-void WOLLobbyMenuInit( WindowLayout *layout, void *userData )
-{
- nextScreen = NULL;
- buttonPushed = false;
- isShuttingDown = false;
-
- SetLobbyAttemptHostJoin(FALSE); // not trying to host or join
-
- gameListRefreshTime = 0;
- playerListRefreshTime = 0;
-
- parentWOLLobbyID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLCustomLobby.wnd:WOLLobbyMenuParent" ) );
- parent = TheWindowManager->winGetWindowFromId(NULL, parentWOLLobbyID);
-
- buttonBackID = TheNameKeyGenerator->nameToKey(AsciiString("WOLCustomLobby.wnd:ButtonBack"));
- buttonBack = TheWindowManager->winGetWindowFromId(parent, buttonBackID);
-
- buttonHostID = TheNameKeyGenerator->nameToKey(AsciiString("WOLCustomLobby.wnd:ButtonHost"));
- buttonHost = TheWindowManager->winGetWindowFromId(parent, buttonHostID);
-
- buttonRefreshID = TheNameKeyGenerator->nameToKey(AsciiString("WOLCustomLobby.wnd:ButtonRefresh"));
- buttonRefresh = TheWindowManager->winGetWindowFromId(parent, buttonRefreshID);
-
- buttonJoinID = TheNameKeyGenerator->nameToKey(AsciiString("WOLCustomLobby.wnd:ButtonJoin"));
- buttonJoin = TheWindowManager->winGetWindowFromId(parent, buttonJoinID);
- buttonJoin->winEnable(FALSE);
-
- buttonBuddyID = TheNameKeyGenerator->nameToKey(AsciiString("WOLCustomLobby.wnd:ButtonBuddy"));
- buttonBuddy = TheWindowManager->winGetWindowFromId(parent, buttonBuddyID);
-
- buttonEmoteID = TheNameKeyGenerator->nameToKey(AsciiString("WOLCustomLobby.wnd:ButtonEmote"));
- buttonEmote = TheWindowManager->winGetWindowFromId(parent, buttonEmoteID);
-
- textEntryChatID = TheNameKeyGenerator->nameToKey(AsciiString("WOLCustomLobby.wnd:TextEntryChat"));
- textEntryChat = TheWindowManager->winGetWindowFromId(parent, textEntryChatID);
-
- listboxLobbyPlayersID = TheNameKeyGenerator->nameToKey(AsciiString("WOLCustomLobby.wnd:ListboxPlayers"));
- listboxLobbyPlayers = TheWindowManager->winGetWindowFromId(parent, listboxLobbyPlayersID);
- listboxLobbyPlayers->winSetTooltipFunc(playerTooltip);
-
- listboxLobbyChatID = TheNameKeyGenerator->nameToKey(AsciiString("WOLCustomLobby.wnd:ListboxChat"));
- listboxLobbyChat = TheWindowManager->winGetWindowFromId(parent, listboxLobbyChatID);
- TheGameSpyInfo->registerTextWindow(listboxLobbyChat);
-
- comboLobbyGroupRoomsID = TheNameKeyGenerator->nameToKey(AsciiString("WOLCustomLobby.wnd:ComboBoxGroupRooms"));
- comboLobbyGroupRooms = TheWindowManager->winGetWindowFromId(parent, comboLobbyGroupRoomsID);
-
- GadgetTextEntrySetText(textEntryChat, UnicodeString.TheEmptyString);
-
- populateGroupRoomListbox(comboLobbyGroupRooms);
-
- // Show Menu
- layout->hide( FALSE );
-
- // if we're not in a room, this will join the best available one
- if (!TheGameSpyInfo->getCurrentGroupRoom())
- {
- if (groupRoomToJoin)
- {
- DEBUG_LOG(("WOLLobbyMenuInit() - rejoining group room %d\n", groupRoomToJoin));
- TheGameSpyInfo->joinGroupRoom(groupRoomToJoin);
- groupRoomToJoin = 0;
- }
- else
- {
- DEBUG_LOG(("WOLLobbyMenuInit() - joining best group room\n"));
- TheGameSpyInfo->joinBestGroupRoom();
- }
- }
- else
- {
- DEBUG_LOG(("WOLLobbyMenuInit() - not joining group room because we're already in one\n"));
- }
-
- GrabWindowInfo();
-
- TheGameSpyInfo->clearStagingRoomList();
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_STARTGAMELIST;
- req.gameList.restrictGameList = TheGameSpyConfig->restrictGamesToLobby();
- TheGameSpyPeerMessageQueue->addRequest(req);
-
- // animate controls
-// TheShell->registerWithAnimateManager(parent, WIN_ANIMATION_SLIDE_TOP, TRUE);
- TheShell->showShellMap(TRUE);
- TheGameSpyGame->reset();
-
- CustomMatchPreferences pref;
-// GameWindow *slider = TheWindowManager->winGetWindowFromId(parent, sliderChatAdjustID);
-// if (slider)
-// {
-// GadgetSliderSetPosition(slider, pref.getChatSizeSlider());
-// doSliderTrack(slider, pref.getChatSizeSlider());
-// }
-//
- if (pref.usesLongGameList())
- {
- ToggleGameListType();
- }
-
- // Set Keyboard to chat window
- TheWindowManager->winSetFocus( textEntryChat );
- raiseMessageBoxes = true;
-
- TheLobbyQueuedUTMs.clear();
- justEntered = TRUE;
- initialGadgetDelay = 2;
- GameWindow *win = TheWindowManager->winGetWindowFromId(NULL, TheNameKeyGenerator->nameToKey("WOLCustomLobby.wnd:GadgetParent"));
- if(win)
- win->winHide(TRUE);
- DontShowMainMenu = TRUE;
-} // WOLLobbyMenuInit
-
-//-------------------------------------------------------------------------------------------------
-/** This is called when a shutdown is complete for this menu */
-//-------------------------------------------------------------------------------------------------
-static void shutdownComplete( WindowLayout *layout )
-{
-
- isShuttingDown = false;
-
- // hide the layout
- layout->hide( TRUE );
-
- // our shutdown is complete
- TheShell->shutdownComplete( layout, (nextScreen != NULL) );
-
- if (nextScreen != NULL)
- {
- TheShell->push(nextScreen);
- }
-
- nextScreen = NULL;
-
-} // end if
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Lobby Menu shutdown method */
-//-------------------------------------------------------------------------------------------------
-void WOLLobbyMenuShutdown( WindowLayout *layout, void *userData )
-{
- CustomMatchPreferences pref;
-// GameWindow *slider = TheWindowManager->winGetWindowFromId(parent, sliderChatAdjustID);
-// if (slider)
-// {
-// pref.setChatSizeSlider(GadgetSliderGetPosition(slider));
-// }
- if (GetGameInfoListBox())
- {
- pref.setUsesLongGameList(FALSE);
- }
- else
- {
- pref.setUsesLongGameList(TRUE);
- }
- pref.write();
-
- ReleaseWindowInfo();
-
- TheGameSpyInfo->unregisterTextWindow(listboxLobbyChat);
-
- //TheGameSpyChat->stopListingGames();
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_STOPGAMELIST;
- TheGameSpyPeerMessageQueue->addRequest(req);
-
- listboxLobbyChat = NULL;
- listboxLobbyPlayers = NULL;
-
- isShuttingDown = true;
-
- // if we are shutting down for an immediate pop, skip the animations
- Bool popImmediate = *(Bool *)userData;
- if( popImmediate )
- {
-
- shutdownComplete( layout );
- return;
-
- } //end if
-
- TheShell->reverseAnimatewindow();
- DontShowMainMenu = FALSE;
-
- RaiseGSMessageBox();
- TheTransitionHandler->reverse("WOLCustomLobbyFade");
-
-} // WOLLobbyMenuShutdown
-
-static void fillPlayerInfo(const PeerResponse *resp, PlayerInfo *info)
-{
- info->m_name = resp->nick.c_str();
- info->m_profileID = resp->player.profileID;
- info->m_flags = resp->player.flags;
- info->m_wins = resp->player.wins;
- info->m_losses = resp->player.losses;
- info->m_locale = resp->locale.c_str();
- info->m_rankPoints= resp->player.rankPoints;
- info->m_side = resp->player.side;
- info->m_preorder = resp->player.preorder;
-}
-
-#ifdef PERF_TEST
-static const char* getMessageString(Int t)
-{
- switch(t)
- {
- case PeerResponse::PEERRESPONSE_LOGIN:
- return "login";
- case PeerResponse::PEERRESPONSE_DISCONNECT:
- return "disconnect";
- case PeerResponse::PEERRESPONSE_MESSAGE:
- return "message";
- case PeerResponse::PEERRESPONSE_GROUPROOM:
- return "group room";
- case PeerResponse::PEERRESPONSE_STAGINGROOM:
- return "staging room";
- case PeerResponse::PEERRESPONSE_STAGINGROOMPLAYERINFO:
- return "staging room player info";
- case PeerResponse::PEERRESPONSE_JOINGROUPROOM:
- return "group room join";
- case PeerResponse::PEERRESPONSE_CREATESTAGINGROOM:
- return "staging room create";
- case PeerResponse::PEERRESPONSE_JOINSTAGINGROOM:
- return "staging room join";
- case PeerResponse::PEERRESPONSE_PLAYERJOIN:
- return "player join";
- case PeerResponse::PEERRESPONSE_PLAYERLEFT:
- return "player part";
- case PeerResponse::PEERRESPONSE_PLAYERCHANGEDNICK:
- return "player nick";
- case PeerResponse::PEERRESPONSE_PLAYERINFO:
- return "player info";
- case PeerResponse::PEERRESPONSE_PLAYERCHANGEDFLAGS:
- return "player flags";
- case PeerResponse::PEERRESPONSE_ROOMUTM:
- return "room UTM";
- case PeerResponse::PEERRESPONSE_PLAYERUTM:
- return "player UTM";
- case PeerResponse::PEERRESPONSE_QUICKMATCHSTATUS:
- return "QM status";
- case PeerResponse::PEERRESPONSE_GAMESTART:
- return "game start";
- case PeerResponse::PEERRESPONSE_FAILEDTOHOST:
- return "host failure";
- }
- return "unknown";
-}
-#endif // PERF_TEST
-
-//-------------------------------------------------------------------------------------------------
-/** refreshGameList
- The Bool is used to force refresh if the refresh button was hit.*/
-//-------------------------------------------------------------------------------------------------
-static void refreshGameList( Bool forceRefresh )
-{
- Int refreshInterval = gameListRefreshInterval;
-
- if (forceRefresh || ((gameListRefreshTime == 0) || ((gameListRefreshTime + refreshInterval) <= timeGetTime())))
- {
- if (TheGameSpyInfo->hasStagingRoomListChanged())
- {
- //DEBUG_LOG(("################### refreshing game list\n"));
- //DEBUG_LOG(("gameRefreshTime=%d, refreshInterval=%d, now=%d\n", gameListRefreshTime, refreshInterval, timeGetTime()));
- RefreshGameListBoxes();
- gameListRefreshTime = timeGetTime();
- } else {
- //DEBUG_LOG(("-"));
- }
- } else {
- //DEBUG_LOG(("gameListRefreshTime: %d refreshInterval: %d\n"));
- }
-}
-//-------------------------------------------------------------------------------------------------
-/** refreshPlayerList
- The Bool is used to force refresh if the refresh button was hit.*/
-//-------------------------------------------------------------------------------------------------
-static void refreshPlayerList( Bool forceRefresh )
-{
- Int refreshInterval = playerListRefreshInterval;
-
- if (forceRefresh ||((playerListRefreshTime == 0) || ((playerListRefreshTime + refreshInterval) <= timeGetTime())))
- {
- PopulateLobbyPlayerListbox();
- playerListRefreshTime = timeGetTime();
- }
-}
-//-------------------------------------------------------------------------------------------------
-/** WOL Lobby Menu update method */
-//-------------------------------------------------------------------------------------------------
-void WOLLobbyMenuUpdate( WindowLayout * layout, void *userData)
-{
- if(justEntered)
- {
- if(initialGadgetDelay == 1)
- {
- TheTransitionHandler->remove("MainMenuDefaultMenuLogoFade");
- TheTransitionHandler->setGroup("WOLCustomLobbyFade");
- initialGadgetDelay = 2;
- justEntered = FALSE;
- }
- else
- initialGadgetDelay--;
- }
- if (TheGameLogic->isInShellGame() && TheGameLogic->getFrame() == 1)
- {
- SignalUIInteraction(SHELL_SCRIPT_HOOK_GENERALS_ONLINE_ENTERED_FROM_GAME);
- }
-
-
- // We'll only be successful if we've requested to
- if(isShuttingDown && TheShell->isAnimFinished() && TheTransitionHandler->isFinished())
- shutdownComplete(layout);
-
- if (raiseMessageBoxes)
- {
- RaiseGSMessageBox();
- raiseMessageBoxes = false;
- }
-
- if (TheShell->isAnimFinished() && TheTransitionHandler->isFinished() && !buttonPushed && TheGameSpyPeerMessageQueue)
- {
- HandleBuddyResponses();
- HandlePersistentStorageResponses();
-
-#ifdef PERF_TEST
- UnsignedInt start = timeGetTime();
- UnsignedInt end = timeGetTime();
- std::list responses;
- Int numMessages = 0;
-#endif // PERF_TEST
-
- Int allowedMessages = TheGameSpyInfo->getMaxMessagesPerUpdate();
- Bool sawImportantMessage = FALSE;
- Bool shouldRepopulatePlayers = FALSE;
- PeerResponse resp;
- while (allowedMessages-- && !sawImportantMessage && TheGameSpyPeerMessageQueue->getResponse( resp ))
- {
-#ifdef PERF_TEST
- ++numMessages;
- responses.push_back(resp.peerResponseType);
-#endif // PERF_TEST
- switch (resp.peerResponseType)
- {
- case PeerResponse::PEERRESPONSE_JOINGROUPROOM:
- sawImportantMessage = TRUE;
- if (resp.joinGroupRoom.ok)
- {
- //buttonPushed = true;
- TheGameSpyInfo->setCurrentGroupRoom(resp.joinGroupRoom.id);
- TheGameSpyInfo->getPlayerInfoMap()->clear();
- GroupRoomMap::iterator iter = TheGameSpyInfo->getGroupRoomList()->find(resp.joinGroupRoom.id);
- if (iter != TheGameSpyInfo->getGroupRoomList()->end())
- {
- GameSpyGroupRoom room = iter->second;
- UnicodeString msg;
- msg.format(TheGameText->fetch("GUI:LobbyJoined"), room.m_translatedName.str());
- TheGameSpyInfo->addText(msg, GameSpyColor[GSCOLOR_DEFAULT], NULL);
- }
- }
- else
- {
- DEBUG_LOG(("WOLLobbyMenuUpdate() - joining best group room\n"));
- TheGameSpyInfo->joinBestGroupRoom();
- }
- populateGroupRoomListbox(comboLobbyGroupRooms);
- shouldRepopulatePlayers = TRUE;
- break;
- case PeerResponse::PEERRESPONSE_PLAYERCHANGEDFLAGS:
- {
- PlayerInfo p;
- fillPlayerInfo(&resp, &p);
- TheGameSpyInfo->updatePlayerInfo(p);
- shouldRepopulatePlayers = TRUE;
- }
- break;
- case PeerResponse::PEERRESPONSE_PLAYERCHANGEDNICK:
- {
- PlayerInfo p;
- fillPlayerInfo(&resp, &p);
- TheGameSpyInfo->updatePlayerInfo(p);
- shouldRepopulatePlayers = TRUE;
- }
- break;
- case PeerResponse::PEERRESPONSE_PLAYERINFO:
- {
- PlayerInfo p;
- fillPlayerInfo(&resp, &p);
- TheGameSpyInfo->updatePlayerInfo(p);
- shouldRepopulatePlayers = TRUE;
- }
- break;
- case PeerResponse::PEERRESPONSE_PLAYERJOIN:
- {
- if (resp.player.roomType == GroupRoom)
- {
- PlayerInfo p;
- fillPlayerInfo(&resp, &p);
- TheGameSpyInfo->updatePlayerInfo(p);
- shouldRepopulatePlayers = TRUE;
- }
- }
- break;
- case PeerResponse::PEERRESPONSE_PLAYERUTM:
- case PeerResponse::PEERRESPONSE_ROOMUTM:
- {
- DEBUG_LOG(("Putting off a UTM in the lobby\n"));
- TheLobbyQueuedUTMs.push_back(resp);
- }
- break;
- case PeerResponse::PEERRESPONSE_PLAYERLEFT:
- {
- PlayerInfo p;
- fillPlayerInfo(&resp, &p);
- TheGameSpyInfo->playerLeftGroupRoom(resp.nick.c_str());
- shouldRepopulatePlayers = TRUE;
- }
- break;
- case PeerResponse::PEERRESPONSE_MESSAGE:
- {
- TheGameSpyInfo->addChat(resp.nick.c_str(), resp.message.profileID,
- UnicodeString(resp.text.c_str()), !resp.message.isPrivate, resp.message.isAction, listboxLobbyChat);
- }
- break;
- case PeerResponse::PEERRESPONSE_DISCONNECT:
- {
- sawImportantMessage = TRUE;
- UnicodeString title, body;
- AsciiString disconMunkee;
- disconMunkee.format("GUI:GSDisconReason%d", resp.discon.reason);
- title = TheGameText->fetch( "GUI:GSErrorTitle" );
- body = TheGameText->fetch( disconMunkee );
- GameSpyCloseAllOverlays();
- GSMessageBoxOk( title, body );
- TheGameSpyInfo->reset();
- TheShell->pop();
- }
- case PeerResponse::PEERRESPONSE_CREATESTAGINGROOM:
- {
- sawImportantMessage = TRUE;
- SetLobbyAttemptHostJoin(FALSE);
- if (resp.createStagingRoom.result == PEERJoinSuccess)
- {
- // Woohoo! On to our next screen!
- buttonPushed = true;
- nextScreen = "Menus/GameSpyGameOptionsMenu.wnd";
- TheShell->pop();
- TheGameSpyInfo->markAsStagingRoomHost();
- TheGameSpyInfo->setGameOptions();
- }
- }
- break;
- case PeerResponse::PEERRESPONSE_JOINSTAGINGROOM:
- {
- sawImportantMessage = TRUE;
- SetLobbyAttemptHostJoin(FALSE);
- Bool isHostPresent = TRUE;
- if (resp.joinStagingRoom.ok == PEERTrue)
- {
- GameSpyStagingRoom *room = TheGameSpyInfo->getCurrentStagingRoom();
- if (!room)
- {
- isHostPresent = FALSE;
- }
- else
- {
- isHostPresent = FALSE;
- for (Int i=0; igetConstSlot(0)->getName());
- const char *firstPlayer = resp.stagingRoomPlayerNames[i].c_str();
- if (!strcmp(hostName.str(), firstPlayer))
- {
- DEBUG_LOG(("Saw host %s == %s in slot %d\n", hostName.str(), firstPlayer, i));
- isHostPresent = TRUE;
- }
- }
- }
- }
- if (resp.joinStagingRoom.ok == PEERTrue && isHostPresent)
- {
- // Woohoo! On to our next screen!
- buttonPushed = true;
- nextScreen = "Menus/GameSpyGameOptionsMenu.wnd";
- TheShell->pop();
- }
- else
- {
- UnicodeString s;
-
- switch(resp.joinStagingRoom.result)
- {
- case PEERFullRoom: // The room is full.
- s = TheGameText->fetch("GUI:JoinFailedRoomFull");
- break;
- case PEERInviteOnlyRoom: // The room is invite only.
- s = TheGameText->fetch("GUI:JoinFailedInviteOnly");
- break;
- case PEERBannedFromRoom: // The local user is banned from the room.
- s = TheGameText->fetch("GUI:JoinFailedBannedFromRoom");
- break;
- case PEERBadPassword: // An incorrect password (or none) was given for a passworded room.
- s = TheGameText->fetch("GUI:JoinFailedBadPassword");
- break;
- case PEERAlreadyInRoom: // The local user is already in or entering a room of the same type.
- s = TheGameText->fetch("GUI:JoinFailedAlreadyInRoom");
- break;
- case PEERNoConnection: // Can't join a room if there's no chat connection.
- s = TheGameText->fetch("GUI:JoinFailedNoConnection");
- break;
- default:
- s = TheGameText->fetch("GUI:JoinFailedDefault");
- break;
- }
- GSMessageBoxOk(TheGameText->fetch("GUI:JoinFailedDefault"), s);
- if (groupRoomToJoin)
- {
- DEBUG_LOG(("WOLLobbyMenuUpdate() - rejoining group room %d\n", groupRoomToJoin));
- TheGameSpyInfo->joinGroupRoom(groupRoomToJoin);
- groupRoomToJoin = 0;
- }
- else
- {
- DEBUG_LOG(("WOLLobbyMenuUpdate() - joining best group room\n"));
- TheGameSpyInfo->joinBestGroupRoom();
- }
- }
- }
- break;
- case PeerResponse::PEERRESPONSE_STAGINGROOMLISTCOMPLETE:
- TheGameSpyInfo->sawFullGameList();
- break;
- case PeerResponse::PEERRESPONSE_STAGINGROOM:
- {
- GameSpyStagingRoom room;
- switch(resp.stagingRoom.action)
- {
- case PEER_CLEAR:
- TheGameSpyInfo->clearStagingRoomList();
- //TheGameSpyInfo->addText( UnicodeString(L"gameList: PEER_CLEAR"), GameSpyColor[GSCOLOR_DEFAULT], listboxLobbyChat );
- break;
- case PEER_ADD:
- case PEER_UPDATE:
- {
- if (resp.stagingRoom.percentComplete == 100)
- {
- TheGameSpyInfo->sawFullGameList();
- }
-
- //if (ParseAsciiStringToGameInfo(&room, resp.stagingRoomMapName.c_str()))
- //if (ParseAsciiStringToGameInfo(&room, resp.stagingServerGameOptions.c_str()))
- Bool serverOk = TRUE;
- if (!resp.stagingRoomMapName.length())
- {
- serverOk = FALSE;
- }
- // fix for ghost game problem - need to iterate over all resp.stagingRoomPlayerNames[i]
- Bool sawSelf = FALSE;
- //for (Int i=0; igetLocalName() == resp.stagingRoomPlayerNames[0].c_str())
- {
- sawSelf = TRUE; // don't show ghost games for myself
- }
- //}
- if (sawSelf)
- serverOk = FALSE;
-
- if (serverOk)
- {
- room.setGameName(UnicodeString(resp.stagingServerName.c_str()));
- room.setID(resp.stagingRoom.id);
- room.setHasPassword(resp.stagingRoom.requiresPassword);
- room.setVersion(resp.stagingRoom.version);
- room.setExeCRC(resp.stagingRoom.exeCRC);
- room.setIniCRC(resp.stagingRoom.iniCRC);
- room.setAllowObservers(resp.stagingRoom.allowObservers);
- room.setPingString(resp.stagingServerPingString.c_str());
- room.setLadderIP(resp.stagingServerLadderIP.c_str());
- room.setLadderPort(resp.stagingRoom.ladderPort);
- room.setReportedNumPlayers(resp.stagingRoom.numPlayers);
- room.setReportedMaxPlayers(resp.stagingRoom.maxPlayers);
- room.setReportedNumObservers(resp.stagingRoom.numObservers);
-
- Int i;
- AsciiString gsMapName = resp.stagingRoomMapName.c_str();
- AsciiString mapName = "";
- for (i=0; iportableMapPathToRealMapPath(mapName));
-
- Int numPlayers = 0;
- for (i=0; isetWins( resp.stagingRoom.wins[i] );
- slot->setLosses( resp.stagingRoom.losses[i] );
- slot->setProfileID( resp.stagingRoom.profileID[i] );
- slot->setPlayerTemplate( resp.stagingRoom.faction[i] );
- slot->setColor( resp.stagingRoom.color[i] );
- if (resp.stagingRoom.profileID[i] == SLOT_EASY_AI)
- {
- slot->setState(SLOT_EASY_AI);
- ++numPlayers;
- }
- else if (resp.stagingRoom.profileID[i] == SLOT_MED_AI)
- {
- slot->setState(SLOT_MED_AI);
- ++numPlayers;
- }
- else if (resp.stagingRoom.profileID[i] == SLOT_BRUTAL_AI)
- {
- slot->setState(SLOT_BRUTAL_AI);
- ++numPlayers;
- }
- else if (resp.stagingRoomPlayerNames[i].length())
- {
- UnicodeString nameUStr;
- nameUStr.translate(resp.stagingRoomPlayerNames[i].c_str());
- slot->setState(SLOT_PLAYER, nameUStr);
- ++numPlayers;
- }
- else
- {
- slot->setState(SLOT_OPEN);
- }
- }
- }
- DEBUG_ASSERTCRASH(numPlayers, ("Game had no players!\n"));
- //DEBUG_LOG(("Saw room: hasPass=%d, allowsObservers=%d\n", room.getHasPassword(), room.getAllowObservers()));
- if (resp.stagingRoom.action == PEER_ADD)
- {
- TheGameSpyInfo->addStagingRoom(room);
- //TheGameSpyInfo->addText( UnicodeString(L"gameList: PEER_ADD"), GameSpyColor[GSCOLOR_DEFAULT], listboxLobbyChat );
- }
- else
- {
- TheGameSpyInfo->updateStagingRoom(room);
- //TheGameSpyInfo->addText( UnicodeString(L"gameList: PEER_UPDATE"), GameSpyColor[GSCOLOR_DEFAULT], listboxLobbyChat );
- }
- }
- else
- {
- room.setID(resp.stagingRoom.id);
- TheGameSpyInfo->removeStagingRoom(room);
- //TheGameSpyInfo->addText( UnicodeString(L"gameList: PEER_UPDATE FAILED"), GameSpyColor[GSCOLOR_DEFAULT], listboxLobbyChat );
- }
- break;
- }
- case PEER_REMOVE:
- room.setID(resp.stagingRoom.id);
- TheGameSpyInfo->removeStagingRoom(room);
- //TheGameSpyInfo->addText( UnicodeString(L"gameList: PEER_REMOVE"), GameSpyColor[GSCOLOR_DEFAULT], listboxLobbyChat );
- break;
- default:
- //TheGameSpyInfo->addText( UnicodeString(L"gameList: Unknown"), GameSpyColor[GSCOLOR_DEFAULT], listboxLobbyChat );
- break;
- }
- }
- break;
- }
- }
-#if 0
- if (shouldRepopulatePlayers)
- {
- PopulateLobbyPlayerListbox();
- }
-#else
- refreshPlayerList();
-#endif
-
-#ifdef PERF_TEST
- // check performance
- end = timeGetTime();
- PERF_LOG(("Frame time was %d ms\n", end-start));
- std::list::const_iterator it;
- for (it = responses.begin(); it != responses.end(); ++it)
- {
- PERF_LOG((" %s\n", getMessageString(*it)));
- }
- PERF_LOG(("\n"));
-#endif // PERF_TEST
-
-#if 0
-// Removed 2-17-03 to pull out into a function so we can do the same checks
- Int refreshInterval = gameListRefreshInterval;
-
- if ((gameListRefreshTime == 0) || ((gameListRefreshTime + refreshInterval) <= timeGetTime()))
- {
- if (TheGameSpyInfo->hasStagingRoomListChanged())
- {
- //DEBUG_LOG(("################### refreshing game list\n"));
- //DEBUG_LOG(("gameRefreshTime=%d, refreshInterval=%d, now=%d\n", gameListRefreshTime, refreshInterval, timeGetTime()));
- RefreshGameListBoxes();
- gameListRefreshTime = timeGetTime();
- } else {
- //DEBUG_LOG(("-"));
- }
- } else {
- //DEBUG_LOG(("gameListRefreshTime: %d refreshInterval: %d\n"));
- }
-#else
- refreshGameList();
-#endif
- }
-}// WOLLobbyMenuUpdate
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Lobby Menu input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLLobbyMenuInput( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
- UnsignedByte key = mData1;
- UnsignedByte state = mData2;
- if (buttonPushed)
- break;
-
- switch( key )
- {
-
- // ----------------------------------------------------------------------------------------
- case KEY_ESC:
- {
-
- //
- // send a simulated selected event to the parent window of the
- // back/exit button
- //
- if( BitTest( state, KEY_STATE_UP ) )
- {
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)buttonBack, buttonBackID );
-
- } // end if
-
- // don't let key fall through anywhere else
- return MSG_HANDLED;
-
- } // end escape
-
- } // end switch( key )
-
- } // end char
-
- } // end switch( msg )
-
- return MSG_IGNORED;
-}// WOLLobbyMenuInput
-
-//static void doSliderTrack(GameWindow *control, Int val)
-//{
-// Int sliderW, sliderH, sliderX, sliderY;
-// control->winGetPosition(&sliderX, &sliderY);
-// control->winGetSize(&sliderW, &sliderH);
-// Real cursorY = sliderY + (100-val)*0.01f*sliderH;
-//
-// extern GameWindow *listboxLobbyGamesSmall;
-// extern GameWindow *listboxLobbyGamesLarge;
-// extern GameWindow *listboxLobbyGameInfo;
-//
-// static Int gwsX = 0, gwsY = 0, gwsW = 0, gwsH = 0;
-// static Int gwlX = 0, gwlY = 0, gwlW = 0, gwlH = 0;
-// static Int gwiX = 0, gwiY = 0, gwiW = 0, gwiH = 0;
-// static Int pwX = 0, pwY = 0, pwW = 0, pwH = 0;
-// static Int chatPosX = 0, chatPosY = 0, chatW = 0, chatH = 0;
-// static Int spacing = 0;
-// if (chatPosX == 0)
-// {
-// listboxLobbyChat->winGetPosition(&chatPosX, &chatPosY);
-// listboxLobbyChat->winGetSize(&chatW, &chatH);
-//
-//// listboxLobbyGamesSmall->winGetPosition(&gwsX, &gwsY);
-//// listboxLobbyGamesSmall->winGetSize(&gwsW, &gwsH);
-//
-// listboxLobbyGamesLarge->winGetPosition(&gwlX, &gwlY);
-// listboxLobbyGamesLarge->winGetSize(&gwlW, &gwlH);
-//
-//// listboxLobbyGameInfo->winGetPosition(&gwiX, &gwiY);
-//// listboxLobbyGameInfo->winGetSize(&gwiW, &gwiH);
-////
-// listboxLobbyPlayers->winGetPosition(&pwX, &pwY);
-// listboxLobbyPlayers->winGetSize(&pwW, &pwH);
-//
-// spacing = chatPosY - pwY - pwH;
-// }
-//
-// Int newChatY = cursorY;
-// Int newChatH = chatH + chatPosY - newChatY;
-// listboxLobbyChat->winSetPosition(chatPosX, newChatY);
-// listboxLobbyChat->winSetSize(chatW, newChatH);
-//
-// Int newH = cursorY - pwY - spacing;
-// listboxLobbyPlayers->winSetSize(pwW, newH);
-//// listboxLobbyGamesSmall->winSetSize(gwsW, newH);
-// listboxLobbyGamesLarge->winSetSize(gwlW, newH);
-//// listboxLobbyGameInfo->winSetSize(gwiW, newH);
-
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Lobby Menu window system callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLLobbyMenuSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- UnicodeString txtInput;
- static NameKeyType buttonGameListTypeToggleID = NAMEKEY_INVALID;
-
- switch( msg )
- {
-
-
- //---------------------------------------------------------------------------------------------
- case GWM_CREATE:
- {
- buttonGameListTypeToggleID = NAMEKEY("WOLCustomLobby.wnd:ButtonGameListToggle");
-// sliderChatAdjustID = NAMEKEY("WOLCustomLobby.wnd:SliderChatAdjust");
-
- break;
- } // case GWM_DESTROY:
-
- //---------------------------------------------------------------------------------------------
- case GWM_DESTROY:
- {
- break;
- } // case GWM_DESTROY:
-
- //---------------------------------------------------------------------------------------------
- case GWM_INPUT_FOCUS:
- {
- // if we're givin the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
-
- return MSG_HANDLED;
- }//case GWM_INPUT_FOCUS:
-
- //---------------------------------------------------------------------------------------------
- case GLM_SELECTED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- if ( controlID == GetGameListBoxID() )
- {
- int rowSelected = mData2;
- if( rowSelected >= 0 )
- {
- buttonJoin->winEnable(TRUE);
- static UnsignedInt lastFrame = 0;
- static Int lastID = -1;
- UnsignedInt now = TheGameClient->getFrame();
-
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_GETEXTENDEDSTAGINGROOMINFO;
- req.stagingRoom.id = (Int)GadgetListBoxGetItemData(control, rowSelected, 0);
-
- if (lastID != req.stagingRoom.id || now > lastFrame + 60)
- {
- TheGameSpyPeerMessageQueue->addRequest(req);
- }
-
- lastID = req.stagingRoom.id;
- lastFrame = now;
- }
- else
- {
- buttonJoin->winEnable(FALSE);
- }
- if (GetGameInfoListBox())
- {
- RefreshGameInfoListBox(GetGameListBox(), GetGameInfoListBox());
- }
- } //if ( controlID == GetGameListBoxID() )
-
- break;
- }
-
- //---------------------------------------------------------------------------------------------
- case GBM_SELECTED:
- {
- if (buttonPushed)
- break;
-
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if (HandleSortButton((NameKeyType)controlID))
- break;
-
- // If we back out, just bail - we haven't gotten far enough to need to log out
- if ( controlID == buttonBackID )
- {
- if (s_tryingToHostOrJoin)
- break;
-
- // Leave any group room, then pop off the screen
- TheGameSpyInfo->leaveGroupRoom();
-
- SetLobbyAttemptHostJoin( TRUE ); // pretend, since we don't want to queue up another action
- buttonPushed = true;
- nextScreen = "Menus/WOLWelcomeMenu.wnd";
- TheShell->pop();
-
- } //if ( controlID == buttonBack )
- else if ( controlID == buttonRefreshID )
- {
- // Added 2/17/03 added the game refresh button
- refreshGameList(TRUE);
- refreshPlayerList(TRUE);
- }
- else if ( controlID == buttonHostID )
- {
- if (s_tryingToHostOrJoin)
- break;
-
- SetLobbyAttemptHostJoin( TRUE );
- TheLobbyQueuedUTMs.clear();
- groupRoomToJoin = TheGameSpyInfo->getCurrentGroupRoom();
- GameSpyOpenOverlay(GSOVERLAY_GAMEOPTIONS);
- }
- else if ( controlID == buttonJoinID )
- {
- if (s_tryingToHostOrJoin)
- break;
-
- TheLobbyQueuedUTMs.clear();
- // Look for a game to join
- groupRoomToJoin = TheGameSpyInfo->getCurrentGroupRoom();
- Int selected;
- GadgetListBoxGetSelected(GetGameListBox(), &selected);
- if (selected >= 0)
- {
- Int selectedID = (Int)GadgetListBoxGetItemData(GetGameListBox(), selected);
- if (selectedID > 0)
- {
- StagingRoomMap *srm = TheGameSpyInfo->getStagingRoomList();
- StagingRoomMap::iterator srmIt = srm->find(selectedID);
- if (srmIt != srm->end())
- {
- GameSpyStagingRoom *roomToJoin = srmIt->second;
- if (!roomToJoin || roomToJoin->getExeCRC() != TheGlobalData->m_exeCRC || roomToJoin->getIniCRC() != TheGlobalData->m_iniCRC)
- {
- // bad crc. don't go.
- DEBUG_LOG(("WOLLobbyMenuSystem - CRC mismatch with the game I'm trying to join. My CRC's - EXE:0x%08X INI:0x%08X Their CRC's - EXE:0x%08x INI:0x%08x\n", TheGlobalData->m_exeCRC, TheGlobalData->m_iniCRC, roomToJoin->getExeCRC(), roomToJoin->getIniCRC()));
-#if defined(_DEBUG) || defined(_INTERNAL)
- if (TheGlobalData->m_netMinPlayers)
- {
- GSMessageBoxOk(TheGameText->fetch("GUI:JoinFailedDefault"), TheGameText->fetch("GUI:JoinFailedCRCMismatch"));
- break;
- }
- else if (g_fakeCRC)
- {
- TheWritableGlobalData->m_exeCRC = roomToJoin->getExeCRC();
- TheWritableGlobalData->m_iniCRC = roomToJoin->getIniCRC();
- }
-#else
- GSMessageBoxOk(TheGameText->fetch("GUI:JoinFailedDefault"), TheGameText->fetch("GUI:JoinFailedCRCMismatch"));
- break;
-#endif
- }
- Bool unknownLadder = (roomToJoin->getLadderPort() && TheLadderList->findLadder(roomToJoin->getLadderIP(), roomToJoin->getLadderPort()) == NULL);
- if (unknownLadder)
- {
- GSMessageBoxOk(TheGameText->fetch("GUI:JoinFailedDefault"), TheGameText->fetch("GUI:JoinFailedUnknownLadder"));
- break;
- }
- if (roomToJoin->getNumPlayers() == MAX_SLOTS)
- {
- GSMessageBoxOk(TheGameText->fetch("GUI:JoinFailedDefault"), TheGameText->fetch("GUI:JoinFailedRoomFull"));
- break;
- }
- TheGameSpyInfo->markAsStagingRoomJoiner(selectedID);
- TheGameSpyGame->setGameName(roomToJoin->getGameName());
- TheGameSpyGame->setLadderIP(roomToJoin->getLadderIP());
- TheGameSpyGame->setLadderPort(roomToJoin->getLadderPort());
- SetLobbyAttemptHostJoin( TRUE );
- if (roomToJoin->getHasPassword())
- {
- GameSpyOpenOverlay(GSOVERLAY_GAMEPASSWORD);
- }
- else
- {
- // no password - just join it
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_JOINSTAGINGROOM;
- req.text = srmIt->second->getGameName().str();
- req.stagingRoom.id = selectedID;
- req.password = "";
- TheGameSpyPeerMessageQueue->addRequest(req);
- }
- }
- }
- else
- {
- GSMessageBoxOk(TheGameText->fetch("GUI:Error"), TheGameText->fetch("GUI:NoGameInfo"), NULL);
- }
- }
- else
- {
- GSMessageBoxOk(TheGameText->fetch("GUI:Error"), TheGameText->fetch("GUI:NoGameSelected"), NULL);
- }
- }
- else if ( controlID == buttonBuddyID )
- {
- GameSpyToggleOverlay( GSOVERLAY_BUDDY );
- }
- else if ( controlID == buttonGameListTypeToggleID )
- {
- ToggleGameListType();
- }
- else if ( controlID == buttonEmoteID )
- {
- // read the user's input and clear the entry box
- UnicodeString txtInput;
- txtInput.set(GadgetTextEntryGetText( textEntryChat ));
- GadgetTextEntrySetText(textEntryChat, UnicodeString::TheEmptyString);
- txtInput.trim();
- if (!txtInput.isEmpty())
- {
- // Send the message
- TheGameSpyInfo->sendChat( txtInput, FALSE, listboxLobbyPlayers ); // 'emote' button now just sends text
- }
- }
-
- break;
- }// case GBM_SELECTED:
-
- //---------------------------------------------------------------------------------------------
- case GCM_SELECTED:
- {
- if (s_tryingToHostOrJoin)
- break;
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- if( controlID == comboLobbyGroupRoomsID )
- {
- int rowSelected = -1;
- GadgetComboBoxGetSelectedPos(control, &rowSelected);
-
- DEBUG_LOG(("Row selected = %d\n", rowSelected));
- if (rowSelected >= 0)
- {
- Int groupID;
- groupID = (Int)GadgetComboBoxGetItemData(comboLobbyGroupRooms, rowSelected);
- DEBUG_LOG(("ItemData was %d, current Group Room is %d\n", groupID, TheGameSpyInfo->getCurrentGroupRoom()));
- if (groupID && groupID != TheGameSpyInfo->getCurrentGroupRoom())
- {
- TheGameSpyInfo->leaveGroupRoom();
- TheGameSpyInfo->joinGroupRoom(groupID);
-
- if (TheGameSpyConfig->restrictGamesToLobby())
- {
- TheGameSpyInfo->clearStagingRoomList();
- RefreshGameListBoxes();
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_STARTGAMELIST;
- req.gameList.restrictGameList = TRUE;
- TheGameSpyPeerMessageQueue->addRequest(req);
- }
- }
- }
- }
- } // case GCM_SELECTED
- break;
-
- //---------------------------------------------------------------------------------------------
- case GLM_DOUBLE_CLICKED:
- {
- if (buttonPushed)
- break;
-
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- if (controlID == GetGameListBoxID())
- {
- int rowSelected = mData2;
-
- if (rowSelected >= 0)
- {
- GadgetListBoxSetSelected( control, rowSelected );
- GameWindow *button = TheWindowManager->winGetWindowFromId( window, buttonJoinID );
-
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)button, buttonJoinID );
- }
- }
- break;
- }// case GLM_DOUBLE_CLICKED:
-
- //---------------------------------------------------------------------------------------------
- case GLM_RIGHT_CLICKED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if( controlID == listboxLobbyPlayersID )
- {
- RightClickStruct *rc = (RightClickStruct *)mData2;
- WindowLayout *rcLayout = NULL;
- GameWindow *rcMenu;
- if(rc->pos < 0)
- {
- GadgetListBoxSetSelected(control, -1);
- break;
- }
-
- GPProfile profileID = 0;
- AsciiString aName;
- aName.translate(GadgetListBoxGetText(control, rc->pos, COLUMN_PLAYERNAME));
- PlayerInfoMap::iterator it = TheGameSpyInfo->getPlayerInfoMap()->find(aName);
- if (it != TheGameSpyInfo->getPlayerInfoMap()->end())
- profileID = it->second.m_profileID;
-
- Bool isBuddy = FALSE;
- if (profileID <= 0)
- rcLayout = TheWindowManager->winCreateLayout(AsciiString("Menus/RCNoProfileMenu.wnd"));
- else
- {
- if (profileID == TheGameSpyInfo->getLocalProfileID())
- {
- rcLayout = TheWindowManager->winCreateLayout(AsciiString("Menus/RCLocalPlayerMenu.wnd"));
- }
- else if(TheGameSpyInfo->isBuddy(profileID))
- {
- rcLayout = TheWindowManager->winCreateLayout(AsciiString("Menus/RCBuddiesMenu.wnd"));
- isBuddy = TRUE;
- }
- else
- rcLayout = TheWindowManager->winCreateLayout(AsciiString("Menus/RCNonBuddiesMenu.wnd"));
- }
- if(!rcLayout)
- break;
-
- GadgetListBoxSetSelected(control, rc->pos);
-
- rcMenu = rcLayout->getFirstWindow();
- rcMenu->winGetLayout()->runInit();
- rcMenu->winBringToTop();
- rcMenu->winHide(FALSE);
- setUnignoreText( rcLayout, aName, profileID);
- ICoord2D rcSize, rcPos;
- rcMenu->winGetSize(&rcSize.x, &rcSize.y);
- rcPos.x = rc->mouseX;
- rcPos.y = rc->mouseY;
- if(rc->mouseX + rcSize.x > TheDisplay->getWidth())
- rcPos.x = TheDisplay->getWidth() - rcSize.x;
- if(rc->mouseY + rcSize.y > TheDisplay->getHeight())
- rcPos.y = TheDisplay->getHeight() - rcSize.y;
- rcMenu->winSetPosition(rcPos.x, rcPos.y);
-
- GameSpyRCMenuData *rcData = NEW GameSpyRCMenuData;
- rcData->m_id = profileID;
- rcData->m_nick = aName;
- rcData->m_itemType = (isBuddy)?ITEM_BUDDY:ITEM_NONBUDDY;
- rcMenu->winSetUserData((void *)rcData);
- TheWindowManager->winSetLoneWindow(rcMenu);
- }
- else if( controlID == GetGameListBoxID() )
- {
- RightClickStruct *rc = (RightClickStruct *)mData2;
- WindowLayout *rcLayout = NULL;
- GameWindow *rcMenu;
- if(rc->pos < 0)
- {
- GadgetListBoxSetSelected(control, -1);
- break;
- }
-
- Int selectedID = (Int)GadgetListBoxGetItemData(control, rc->pos);
- if (selectedID > 0)
- {
- StagingRoomMap *srm = TheGameSpyInfo->getStagingRoomList();
- StagingRoomMap::iterator srmIt = srm->find(selectedID);
- if (srmIt != srm->end())
- {
- GameSpyStagingRoom *theRoom = srmIt->second;
- if (!theRoom)
- break;
- const LadderInfo *linfo = TheLadderList->findLadder(theRoom->getLadderIP(), theRoom->getLadderPort());
- if (linfo)
- {
- rcLayout = TheWindowManager->winCreateLayout(AsciiString("Menus/RCGameDetailsMenu.wnd"));
- if (!rcLayout)
- break;
-
- GadgetListBoxSetSelected(control, rc->pos);
-
- rcMenu = rcLayout->getFirstWindow();
- rcMenu->winGetLayout()->runInit();
- rcMenu->winBringToTop();
- rcMenu->winHide(FALSE);
- rcMenu->winSetPosition(rc->mouseX, rc->mouseY);
-
- rcMenu->winSetUserData((void *)selectedID);
- TheWindowManager->winSetLoneWindow(rcMenu);
- }
- }
- }
- }
- break;
- }
-
-// //---------------------------------------------------------------------------------------------
-// case GSM_SLIDER_TRACK:
-// {
-// if (buttonPushed)
-// break;
-//
-// GameWindow *control = (GameWindow *)mData1;
-// Int val = (Int)mData2;
-// Int controlID = control->winGetWindowId();
-// if (controlID == sliderChatAdjustID)
-// {
-// doSliderTrack(control, val);
-// }
-// break;
-// }
-
- //---------------------------------------------------------------------------------------------
- case GEM_EDIT_DONE:
- {
- if (buttonPushed)
- break;
-
- // read the user's input and clear the entry box
- UnicodeString txtInput;
- txtInput.set(GadgetTextEntryGetText( textEntryChat ));
- GadgetTextEntrySetText(textEntryChat, UnicodeString::TheEmptyString);
- txtInput.trim();
- if (!txtInput.isEmpty())
- {
- // Send the message
- if (!handleLobbySlashCommands(txtInput))
- {
- TheGameSpyInfo->sendChat( txtInput, false, listboxLobbyPlayers );
- }
- }
- break;
- }
-
- //---------------------------------------------------------------------------------------------
- default:
- return MSG_IGNORED;
-
- }//Switch
-
- return MSG_HANDLED;
-}// WOLLobbyMenuSystem
diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLocaleSelectPopup.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLocaleSelectPopup.cpp
deleted file mode 100644
index 6d088b5c00b..00000000000
--- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLocaleSelectPopup.cpp
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////////////
-// FILE: WOLLocaleSelectPopup.cpp
-// Author: Matt Campbell, December 2001
-// Description: WOL locale select popup
-///////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "GameClient/GameText.h"
-#include "Common/CustomMatchPreferences.h"
-#include "Common/GameEngine.h"
-#include "Common/GameSpyMiscPreferences.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/Shell.h"
-#include "GameClient/KeyDefs.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/GadgetListBox.h"
-#include "Common/GlobalData.h"
-#include "GameNetwork/GameSpyOverlay.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpy/PeerThread.h"
-#include "GameNetwork/GameSpy/PersistentStorageDefs.h"
-#include "GameNetwork/GameSpy/PersistentStorageThread.h"
-
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-// window ids ------------------------------------------------------------------------------
-static NameKeyType parentLocaleSelectID = NAMEKEY_INVALID;
-static NameKeyType buttonOkID = NAMEKEY_INVALID;
-static NameKeyType listboxLocaleID = NAMEKEY_INVALID;
-
-// Window Pointers ------------------------------------------------------------------------
-static GameWindow *parentLocaleSelect = NULL;
-static GameWindow *buttonOk = NULL;
-static GameWindow *listboxLocale = NULL;
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the WOL Status Menu */
-//-------------------------------------------------------------------------------------------------
-void WOLLocaleSelectInit( WindowLayout *layout, void *userData )
-{
- parentLocaleSelectID = TheNameKeyGenerator->nameToKey( AsciiString( "PopupLocaleSelect.wnd:ParentLocaleSelect" ) );
- buttonOkID = TheNameKeyGenerator->nameToKey( AsciiString( "PopupLocaleSelect.wnd:ButtonOk" ) );
- listboxLocaleID = TheNameKeyGenerator->nameToKey( AsciiString( "PopupLocaleSelect.wnd:ListBoxLocaleSelect" ) );
- parentLocaleSelect = TheWindowManager->winGetWindowFromId( NULL, parentLocaleSelectID );
- buttonOk = TheWindowManager->winGetWindowFromId( NULL, buttonOkID);
- listboxLocale = TheWindowManager->winGetWindowFromId( NULL, listboxLocaleID);
-
- for (int i=LOC_MIN; i<=LOC_MAX; ++i)
- {
- AsciiString id;
- id.format("WOL:Locale%2.2d", i);
- GadgetListBoxAddEntryText(listboxLocale, TheGameText->fetch(id.str()), GameSpyColor[GSCOLOR_DEFAULT], -1, -1);
- }
- GadgetListBoxSetSelected(listboxLocale, 0);
-
- // Show Menu
- layout->hide( FALSE );
-
- // Set Keyboard to Main Parent
- TheWindowManager->winSetFocus( parentLocaleSelect );
- TheWindowManager->winSetModal( parentLocaleSelect );
-} // WOLLocaleSelectInit
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Status Menu shutdown method */
-//-------------------------------------------------------------------------------------------------
-void WOLLocaleSelectShutdown( WindowLayout *layout, void *userData )
-{
-
- // hide menu
- layout->hide( TRUE );
-
- // our shutdown is complete
- TheShell->shutdownComplete( layout );
-
-} // WOLLocaleSelectShutdown
-
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Status Menu update method */
-//-------------------------------------------------------------------------------------------------
-void WOLLocaleSelectUpdate( WindowLayout * layout, void *userData)
-{
-
-}// WOLLocaleSelectUpdate
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Status Menu input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLLocaleSelectInput( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
-// UnsignedByte key = mData1;
-// UnsignedByte state = mData2;
-
- // ----------------------------------------------------------------------------------------
- // don't let key fall through anywhere else
- return MSG_HANDLED;
- } // end char
- } // end switch( msg )
- return MSG_IGNORED;
-}// WOLLocaleSelectInput
-
-//Int getRegistryNicknameOffset(AsciiString nick); /// @todo: mdc remove this once we can save ini pref files
-//-------------------------------------------------------------------------------------------------
-/** WOL Status Menu window system callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLLocaleSelectSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- UnicodeString txtInput;
-
- switch( msg )
- {
-
-
- case GWM_CREATE:
- {
-
- break;
- } // case GWM_DESTROY:
-
- case GWM_DESTROY:
- {
- break;
- } // case GWM_DESTROY:
-
- case GWM_INPUT_FOCUS:
- {
- // if we're givin the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
-
- return MSG_HANDLED;
- }//case GWM_INPUT_FOCUS:
-
- case GBM_SELECTED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if ( controlID == buttonOkID )
- {
- int selected;
- GadgetListBoxGetSelected(listboxLocale, &selected);
- if (selected < 0)
- return MSG_HANDLED; // can't select nothing!
- PSRequest psReq;
- psReq.requestType = PSRequest::PSREQUEST_UPDATEPLAYERLOCALE;
- psReq.player.locale = selected + LOC_MIN;
- psReq.email = TheGameSpyInfo->getLocalEmail().str();
- psReq.nick = TheGameSpyInfo->getLocalBaseName().str();
- psReq.password = TheGameSpyInfo->getLocalPassword().str();
- psReq.player.id = TheGameSpyInfo->getLocalProfileID();
-
- TheGameSpyPSMessageQueue->addRequest(psReq);
- GameSpyCloseOverlay(GSOVERLAY_LOCALESELECT);
-
- GameSpyMiscPreferences cPref;
- cPref.setLocale(psReq.player.locale);
- cPref.write();
-
- PSPlayerStats stats = TheGameSpyPSMessageQueue->findPlayerStatsByID(TheGameSpyInfo->getLocalProfileID());
- stats.locale = psReq.player.locale;
- if (stats.id == TheGameSpyInfo->getLocalProfileID())
- TheGameSpyPSMessageQueue->trackPlayerStats(stats);
-
- if(stats.id == 0)
- {
- stats = TheGameSpyInfo->getCachedLocalPlayerStats();
- stats.locale = psReq.player.locale;
- TheGameSpyInfo->setCachedLocalPlayerStats(stats);
- }
- else
- {
- // force an update of our shtuff
- PSResponse newResp;
- newResp.responseType = PSResponse::PSRESPONSE_PLAYERSTATS;
- newResp.player = TheGameSpyPSMessageQueue->findPlayerStatsByID(TheGameSpyInfo->getLocalProfileID());
- TheGameSpyPSMessageQueue->addResponse(newResp);
- }
- CheckReOpenPlayerInfo();
- } //if ( controlID == buttonDisconnect )
- break;
- }// case GBM_SELECTED:
-
- case GEM_EDIT_DONE:
- {
- break;
- }
- default:
- return MSG_IGNORED;
-
- }//Switch
-
- return MSG_HANDLED;
-}// WOLLocaleSelectSystem
diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLoginMenu.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLoginMenu.cpp
deleted file mode 100644
index f60e693e50e..00000000000
--- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLoginMenu.cpp
+++ /dev/null
@@ -1,1511 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////////////
-// FILE: WOLLoginMenu.cpp
-// Author: Chris Huybregts, November 2001
-// Description: Lan Lobby Menu
-///////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/STLTypedefs.h"
-
-#include "Common/File.h"
-#include "Common/FileSystem.h"
-#include "Common/GameEngine.h"
-#include "Common/GameSpyMiscPreferences.h"
-#include "Common/QuotedPrintable.h"
-#include "Common/Registry.h"
-#include "Common/UserPreferences.h"
-#include "GameClient/AnimateWindowManager.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/GameText.h"
-#include "GameClient/Shell.h"
-#include "GameClient/KeyDefs.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/GadgetListBox.h"
-#include "GameClient/GadgetComboBox.h"
-#include "GameClient/GadgetCheckBox.h"
-#include "GameClient/GadgetStaticText.h"
-#include "GameClient/GadgetTextEntry.h"
-#include "GameClient/MessageBox.h"
-#include "GameClient/ShellHooks.h"
-#include "GameClient/GameWindowTransitions.h"
-
-#include "GameNetwork/GameSpy/GSConfig.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpy/PeerThread.h"
-#include "GameNetwork/GameSpy/PingThread.h"
-#include "GameNetwork/GameSpy/BuddyThread.h"
-#include "GameNetwork/GameSpy/ThreadUtils.h"
-#include "GameNetwork/GameSpy/PersistentStorageThread.h"
-
-#include "GameNetwork/GameSpyOverlay.h"
-
-
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-
-#ifdef ALLOW_NON_PROFILED_LOGIN
-Bool GameSpyUseProfiles = false;
-#endif // ALLOW_NON_PROFILED_LOGIN
-
-
-static Bool isShuttingDown = false;
-static Bool buttonPushed = false;
-static char *nextScreen = NULL;
-
-static const UnsignedInt loginTimeoutInMS = 10000;
-static UnsignedInt loginAttemptTime = 0;
-
-class GameSpyLoginPreferences : public UserPreferences
-{
-public:
- GameSpyLoginPreferences() { m_emailPasswordMap.clear(); m_emailNickMap.clear(); }
- virtual ~GameSpyLoginPreferences() { m_emailPasswordMap.clear(); m_emailNickMap.clear(); }
-
- virtual Bool load(AsciiString fname);
- virtual Bool write(void);
-
- AsciiString getPasswordForEmail( AsciiString email );
- AsciiString getDateForEmail( AsciiString email, AsciiString &month, AsciiString &date, AsciiString &year );
- AsciiStringList getNicksForEmail( AsciiString email );
- void addLogin( AsciiString email, AsciiString nick, AsciiString password, AsciiString date );
- void forgetLogin( AsciiString email );
- AsciiStringList getEmails( void );
-
-private:
- typedef std::map PassMap;
- typedef std::map DateMap;
- typedef std::map NickMap;
- PassMap m_emailPasswordMap;
- NickMap m_emailNickMap;
- DateMap m_emailDateMap;
-};
-
-static AsciiString obfuscate( AsciiString in )
-{
- char *buf = NEW char[in.getLength() + 1];
- strcpy(buf, in.str());
- static const char *xor = "1337Munkee";
- char *c = buf;
- const char *c2 = xor;
- while (*c)
- {
- if (!*c2)
- c2 = xor;
- if (*c != *c2)
- *c = *c++ ^ *c2++;
- else
- c++, c2++;
- }
- AsciiString out = buf;
- delete buf;
- return out;
-}
-
-Bool GameSpyLoginPreferences::load( AsciiString fname )
-{
- if (!UserPreferences::load(fname))
- return false;
-
- UserPreferences::iterator upIt = begin();
- while (upIt != end())
- {
- AsciiString key = upIt->first;
- if (key.startsWith("pass_"))
- {
- AsciiString email, pass;
- email = key.str() + 5;
- pass = upIt->second;
-
- AsciiString quoPass = QuotedPrintableToAsciiString(pass);
- pass = obfuscate(quoPass);
-
- m_emailPasswordMap[email] = pass;
- }
- if (key.startsWith("date_"))
- {
- AsciiString email, date;
- email = key.str() + 5;
- date = upIt->second;
-
- date = QuotedPrintableToAsciiString(date);
-
- m_emailDateMap[email] = date;
- }
- else if (key.startsWith("nick_"))
- {
- AsciiString email, nick, nicks;
- email = key.str() + 5;
- nicks = upIt->second;
- while (nicks.nextToken(&nick, ","))
- {
- m_emailNickMap[email].push_back(nick);
- }
- }
- ++upIt;
- }
-
- return true;
-}
-
-Bool GameSpyLoginPreferences::write( void )
-{
- if (m_filename.isEmpty())
- return false;
-
- FILE *fp = fopen(m_filename.str(), "w");
- if (fp)
- {
- fprintf(fp, "lastEmail = %s\n", ((*this)["lastEmail"].str()));
- fprintf(fp, "lastName = %s\n", ((*this)["lastName"].str()));
- fprintf(fp, "useProfiles = %s\n", ((*this)["useProfiles"].str()));
- PassMap::iterator passIt = m_emailPasswordMap.begin();
- while (passIt != m_emailPasswordMap.end())
- {
- AsciiString pass = obfuscate(passIt->second);
- AsciiString quoPass = AsciiStringToQuotedPrintable(pass);
-
- fprintf(fp, "pass_%s = %s\n", passIt->first.str(), quoPass.str());
- ++passIt;
- }
-
- PassMap::iterator dateIt = m_emailDateMap.begin();
- while (dateIt != m_emailDateMap.end())
- {
- AsciiString date = AsciiStringToQuotedPrintable(dateIt->second);
-
- fprintf(fp, "date_%s = %s\n", dateIt->first.str(), date.str());
- ++dateIt;
- }
-
- NickMap::iterator nickIt = m_emailNickMap.begin();
- while (nickIt != m_emailNickMap.end())
- {
- AsciiString nicks;
- AsciiStringListIterator listIt = nickIt->second.begin();
- while (listIt != nickIt->second.end())
- {
- nicks.concat(*listIt);
- nicks.concat(',');
- ++listIt;
- }
- fprintf(fp, "nick_%s = %s\n", nickIt->first.str(), nicks.str());
- ++nickIt;
- }
-
- fclose(fp);
- return true;
- }
- return false;
-}
-AsciiString GameSpyLoginPreferences::getDateForEmail( AsciiString email, AsciiString &month, AsciiString &date, AsciiString &year )
-{
- if ( m_emailDateMap.find(email) == m_emailDateMap.end() )
- return AsciiString::TheEmptyString;
- AsciiString fullDate = m_emailDateMap[email];
- if(fullDate.getLength() != 8)
- return AsciiString::TheEmptyString;
- month.format("%c%c", fullDate.getCharAt(0), fullDate.getCharAt(1));
- date.format("%c%c", fullDate.getCharAt(2), fullDate.getCharAt(3));
- year.format("%c%c%c%c", fullDate.getCharAt(4), fullDate.getCharAt(5), fullDate.getCharAt(6), fullDate.getCharAt(7));
- return m_emailDateMap[email];
-}
-
-AsciiString GameSpyLoginPreferences::getPasswordForEmail( AsciiString email )
-{
- if ( m_emailPasswordMap.find(email) == m_emailPasswordMap.end() )
- return AsciiString::TheEmptyString;
- return m_emailPasswordMap[email];
-}
-
-AsciiStringList GameSpyLoginPreferences::getNicksForEmail( AsciiString email )
-{
- if ( m_emailNickMap.find(email) == m_emailNickMap.end() )
- {
- AsciiStringList empty;
- return empty;
- }
- return m_emailNickMap[email];
-}
-
-void GameSpyLoginPreferences::addLogin( AsciiString email, AsciiString nick, AsciiString password, AsciiString date )
-{
- if ( std::find(m_emailNickMap[email].begin(), m_emailNickMap[email].end(), nick) == m_emailNickMap[email].end() )
- m_emailNickMap[email].push_back(nick);
- m_emailPasswordMap[email] = password;
- m_emailDateMap[email] = date;
-}
-
-void GameSpyLoginPreferences::forgetLogin( AsciiString email )
-{
- m_emailNickMap.erase(email);
- m_emailPasswordMap.erase(email);
- m_emailDateMap.erase(email);
-
-}
-
-AsciiStringList GameSpyLoginPreferences::getEmails( void )
-{
- AsciiStringList theList;
- NickMap::iterator it = m_emailNickMap.begin();
- while (it != m_emailNickMap.end())
- {
- theList.push_back(it->first);
- ++it;
- }
- return theList;
-}
-
-static const char *PREF_FILENAME = "GameSpyLogin.ini";
-static GameSpyLoginPreferences *loginPref = NULL;
-
-static void startPings( void )
-{
- std::list pingServers = TheGameSpyConfig->getPingServers();
- Int timeout = TheGameSpyConfig->getPingTimeoutInMs();
- Int reps = TheGameSpyConfig->getNumPingRepetitions();
-
- for (std::list::const_iterator it = pingServers.begin(); it != pingServers.end(); ++it)
- {
- AsciiString pingServer = *it;
- PingRequest req;
- req.hostname = pingServer.str();
- req.repetitions = reps;
- req.timeout = timeout;
- ThePinger->addRequest(req);
- }
-}
-
-//-------------------------------------------------------------------------------------------------
-/** This is called when a shutdown is complete for this menu */
-//-------------------------------------------------------------------------------------------------
-static void shutdownComplete( WindowLayout *layout )
-{
-
- isShuttingDown = false;
-
- // hide the layout
- layout->hide( TRUE );
-
- // our shutdown is complete
- TheShell->shutdownComplete( layout, (nextScreen != NULL) );
-
- if (nextScreen != NULL)
- {
- if (loginPref)
- {
- loginPref->write();
- delete loginPref;
- loginPref = NULL;
- }
- TheShell->push(nextScreen);
- }
- else
- {
- DEBUG_ASSERTCRASH(loginPref != NULL, ("loginPref == NULL"));
- if (loginPref)
- {
- loginPref->write();
- delete loginPref;
- loginPref = NULL;
- }
- }
-
- nextScreen = NULL;
-
-} // end if
-
-
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-// window ids ------------------------------------------------------------------------------
-static NameKeyType parentWOLLoginID = NAMEKEY_INVALID;
-static NameKeyType buttonBackID = NAMEKEY_INVALID; // profile, quick
-static NameKeyType buttonLoginID = NAMEKEY_INVALID; // profile, quick
-static NameKeyType buttonCreateAccountID = NAMEKEY_INVALID; // profile, quick
-static NameKeyType buttonUseAccountID = NAMEKEY_INVALID; // quick
-static NameKeyType buttonDontUseAccountID = NAMEKEY_INVALID; // profile
-static NameKeyType buttonTOSID = NAMEKEY_INVALID; // TOS
-static NameKeyType parentTOSID = NAMEKEY_INVALID; // TOS Parent
-static NameKeyType buttonTOSOKID = NAMEKEY_INVALID; // TOS
-static NameKeyType listboxTOSID = NAMEKEY_INVALID; // TOS
-static NameKeyType comboBoxEmailID = NAMEKEY_INVALID; // profile
-static NameKeyType comboBoxLoginNameID = NAMEKEY_INVALID; // profile
-static NameKeyType textEntryLoginNameID = NAMEKEY_INVALID; // quick
-static NameKeyType textEntryPasswordID = NAMEKEY_INVALID; // profile
-static NameKeyType checkBoxRememberPasswordID = NAMEKEY_INVALID; // checkbox to remember information or not
-static NameKeyType textEntryMonthID = NAMEKEY_INVALID; // profile
-static NameKeyType textEntryDayID = NAMEKEY_INVALID; // profile
-static NameKeyType textEntryYearID = NAMEKEY_INVALID; // profile
-
-// Window Pointers ------------------------------------------------------------------------
-static GameWindow *parentWOLLogin = NULL;
-static GameWindow *buttonBack = NULL;
-static GameWindow *buttonLogin = NULL;
-static GameWindow *buttonCreateAccount = NULL;
-static GameWindow *buttonUseAccount = NULL;
-static GameWindow *buttonDontUseAccount = NULL;
-static GameWindow *buttonTOS = NULL;
-static GameWindow *parentTOS = NULL;
-static GameWindow *buttonTOSOK = NULL;
-static GameWindow *listboxTOS = NULL;
-static GameWindow *comboBoxEmail = NULL;
-static GameWindow *comboBoxLoginName = NULL;
-static GameWindow *textEntryLoginName = NULL;
-static GameWindow *textEntryPassword = NULL;
-static GameWindow *checkBoxRememberPassword = NULL;
-static GameWindow *textEntryMonth = NULL;
-static GameWindow *textEntryDay = NULL;
-static GameWindow *textEntryYear = NULL;
-
-void EnableLoginControls( Bool state )
-{
- if (buttonLogin)
- buttonLogin->winEnable(state);
- if (buttonCreateAccount)
- buttonCreateAccount->winEnable(state);
- if (buttonUseAccount)
- buttonUseAccount->winEnable(state);
- if (buttonDontUseAccount)
- buttonDontUseAccount->winEnable(state);
- if (comboBoxEmail)
- comboBoxEmail->winEnable(state);
- if (comboBoxLoginName)
- comboBoxLoginName->winEnable(state);
- if (textEntryLoginName)
- textEntryLoginName->winEnable(state);
- if (textEntryPassword)
- textEntryPassword->winEnable(state);
- if (checkBoxRememberPassword)
- checkBoxRememberPassword->winEnable(state);
- if( buttonTOS )
- buttonTOS->winEnable(state);
-
- if (textEntryMonth)
- textEntryMonth->winEnable(state);
- if (textEntryDay)
- textEntryDay->winEnable(state);
- if( textEntryYear )
- textEntryYear->winEnable(state);
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the WOL Login Menu */
-//-------------------------------------------------------------------------------------------------
-void WOLLoginMenuInit( WindowLayout *layout, void *userData )
-{
- nextScreen = NULL;
- buttonPushed = false;
- isShuttingDown = false;
- loginAttemptTime = 0;
-
- if (!loginPref)
- {
- loginPref = NEW GameSpyLoginPreferences;
- loginPref->load(PREF_FILENAME);
- }
-
- // if the ESRB warning is blank (other country) hide the box
- GameWindow *esrbTitle = TheWindowManager->winGetWindowFromId( NULL, NAMEKEY("GameSpyLoginProfile.wnd:StaticTextESRBTop") );
- GameWindow *esrbParent = TheWindowManager->winGetWindowFromId( NULL, NAMEKEY("GameSpyLoginProfile.wnd:ParentESRB") );
- if (esrbTitle && esrbParent)
- {
- if ( GadgetStaticTextGetText( esrbTitle ).getLength() < 2 )
- {
- esrbParent->winHide(TRUE);
- }
- }
-
- parentWOLLoginID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:WOLLoginMenuParent" );
- buttonBackID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:ButtonBack" );
- buttonLoginID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:ButtonLogin" );
- buttonCreateAccountID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:ButtonCreateAccount" );
- buttonUseAccountID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:ButtonUseAccount" );
- buttonDontUseAccountID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:ButtonDontUseAccount" );
- buttonTOSID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:ButtonTOS" );
- parentTOSID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:ParentTOS" );
- buttonTOSOKID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:ButtonTOSOK" );
- listboxTOSID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:ListboxTOS" );
- comboBoxEmailID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:ComboBoxEmail" );
- comboBoxLoginNameID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:ComboBoxLoginName" );
- textEntryLoginNameID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:TextEntryLoginName" );
- textEntryPasswordID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:TextEntryPassword" );
- checkBoxRememberPasswordID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:CheckBoxRememberInfo" );
- textEntryMonthID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:TextEntryMonth" );
- textEntryDayID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:TextEntryDay" );
- textEntryYearID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:TextEntryYear" );
-
- parentWOLLogin = TheWindowManager->winGetWindowFromId( NULL, parentWOLLoginID );
- buttonBack = TheWindowManager->winGetWindowFromId( NULL, buttonBackID);
- buttonLogin = TheWindowManager->winGetWindowFromId( NULL, buttonLoginID);
- buttonCreateAccount = TheWindowManager->winGetWindowFromId( NULL, buttonCreateAccountID);
- buttonUseAccount = TheWindowManager->winGetWindowFromId( NULL, buttonUseAccountID);
- buttonDontUseAccount = TheWindowManager->winGetWindowFromId( NULL, buttonDontUseAccountID);
- buttonTOS = TheWindowManager->winGetWindowFromId( NULL, buttonTOSID);
- parentTOS = TheWindowManager->winGetWindowFromId( NULL, parentTOSID);
- buttonTOSOK = TheWindowManager->winGetWindowFromId( NULL, buttonTOSOKID);
- listboxTOS = TheWindowManager->winGetWindowFromId( NULL, listboxTOSID);
- comboBoxEmail = TheWindowManager->winGetWindowFromId( NULL, comboBoxEmailID);
- comboBoxLoginName = TheWindowManager->winGetWindowFromId( NULL, comboBoxLoginNameID);
- textEntryLoginName = TheWindowManager->winGetWindowFromId( NULL, textEntryLoginNameID);
- textEntryPassword = TheWindowManager->winGetWindowFromId( NULL, textEntryPasswordID);
- checkBoxRememberPassword = TheWindowManager->winGetWindowFromId( NULL, checkBoxRememberPasswordID);
- textEntryMonth = TheWindowManager->winGetWindowFromId( NULL, textEntryMonthID);
- textEntryDay = TheWindowManager->winGetWindowFromId( NULL, textEntryDayID);
- textEntryYear = TheWindowManager->winGetWindowFromId( NULL, textEntryYearID);
-
- GadgetTextEntrySetText(textEntryMonth, UnicodeString::TheEmptyString);
-
- GadgetTextEntrySetText(textEntryDay, UnicodeString::TheEmptyString);
-
- GadgetTextEntrySetText(textEntryYear, UnicodeString::TheEmptyString);
-
-
-
- GameWindowList tabList;
- tabList.push_front(comboBoxEmail);
- tabList.push_back(comboBoxLoginName);
- tabList.push_back(textEntryPassword);
- tabList.push_back(textEntryMonth);
- tabList.push_back(textEntryDay);
- tabList.push_back(textEntryYear);
- tabList.push_back(checkBoxRememberPassword);
- tabList.push_back(buttonLogin);
- tabList.push_back(buttonCreateAccount);
- tabList.push_back(buttonTOS);
- tabList.push_back(buttonBack);
- TheWindowManager->clearTabList();
- TheWindowManager->registerTabList(tabList);
- TheWindowManager->winSetFocus( comboBoxEmail );
- // short form or long form?
-#ifdef ALLOW_NON_PROFILED_LOGIN
- if (parentWOLLogin)
- {
- GameSpyUseProfiles = true;
-#endif // ALLOW_NON_PROFILED_LOGIN
-
- DEBUG_ASSERTCRASH(buttonBack, ("buttonBack missing!"));
- DEBUG_ASSERTCRASH(buttonLogin, ("buttonLogin missing!"));
- DEBUG_ASSERTCRASH(buttonCreateAccount, ("buttonCreateAccount missing!"));
- //DEBUG_ASSERTCRASH(buttonDontUseAccount, ("buttonDontUseAccount missing!"));
- DEBUG_ASSERTCRASH(comboBoxEmail, ("comboBoxEmail missing!"));
- DEBUG_ASSERTCRASH(comboBoxLoginName, ("comboBoxLoginName missing!"));
- DEBUG_ASSERTCRASH(textEntryPassword, ("textEntryPassword missing!"));
-
- //TheShell->registerWithAnimateManager(parentWOLLogin, WIN_ANIMATION_SLIDE_TOP, TRUE);
- /**/
-// TheShell->registerWithAnimateManager(buttonTOS, WIN_ANIMATION_SLIDE_BOTTOM, TRUE);
- //TheShell->registerWithAnimateManager(buttonCreateAccount, WIN_ANIMATION_SLIDE_LEFT, TRUE);
- //TheShell->registerWithAnimateManager(buttonDontUseAccount, WIN_ANIMATION_SLIDE_LEFT, TRUE);
-// TheShell->registerWithAnimateManager(buttonBack, WIN_ANIMATION_SLIDE_BOTTOM, TRUE);
- /**/
-#ifdef ALLOW_NON_PROFILED_LOGIN
- }
- else
- {
- GameSpyUseProfiles = false;
-
- parentWOLLoginID = TheNameKeyGenerator->nameToKey( "GameSpyLoginQuick.wnd:WOLLoginMenuParent" );
- buttonBackID = TheNameKeyGenerator->nameToKey( "GameSpyLoginQuick.wnd:ButtonBack" );
- buttonLoginID = TheNameKeyGenerator->nameToKey( "GameSpyLoginQuick.wnd:ButtonLogin" );
- buttonCreateAccountID = TheNameKeyGenerator->nameToKey( "GameSpyLoginQuick.wnd:ButtonCreateAccount" );
- buttonUseAccountID = TheNameKeyGenerator->nameToKey( "GameSpyLoginQuick.wnd:ButtonUseAccount" );
- buttonDontUseAccountID = TheNameKeyGenerator->nameToKey( "GameSpyLoginQuick.wnd:ButtonDontUseAccount" );
- buttonTOSID = TheNameKeyGenerator->nameToKey( "GameSpyLoginQuick.wnd:ButtonTOS" );
- parentTOSID = TheNameKeyGenerator->nameToKey( "GameSpyLoginQuick.wnd:ParentTOS" );
- buttonTOSOKID = TheNameKeyGenerator->nameToKey( "GameSpyLoginQuick.wnd:ButtonTOSOK" );
- listboxTOSID = TheNameKeyGenerator->nameToKey( "GameSpyLoginQuick.wnd:ListboxTOS" );
- comboBoxEmailID = TheNameKeyGenerator->nameToKey( "GameSpyLoginQuick.wnd:ComboBoxEmail" );
- textEntryLoginNameID = TheNameKeyGenerator->nameToKey( "GameSpyLoginQuick.wnd:TextEntryLoginName" );
- textEntryPasswordID = TheNameKeyGenerator->nameToKey( "GameSpyLoginQuick.wnd:TextEntryPassword" );
- checkBoxRememberPasswordID = TheNameKeyGenerator->nameToKey( "GameSpyLoginQuick.wnd:CheckBoxRememberPassword" );
-
- parentWOLLogin = TheWindowManager->winGetWindowFromId( NULL, parentWOLLoginID );
- buttonBack = TheWindowManager->winGetWindowFromId( NULL, buttonBackID);
- buttonLogin = TheWindowManager->winGetWindowFromId( NULL, buttonLoginID);
- buttonCreateAccount = TheWindowManager->winGetWindowFromId( NULL, buttonCreateAccountID);
- buttonUseAccount = TheWindowManager->winGetWindowFromId( NULL, buttonUseAccountID);
- buttonDontUseAccount = TheWindowManager->winGetWindowFromId( NULL, buttonDontUseAccountID);
- comboBoxEmail = TheWindowManager->winGetWindowFromId( NULL, comboBoxEmailID);
- buttonTOS = TheWindowManager->winGetWindowFromId( NULL, buttonTOSID);
- parentTOS = TheWindowManager->winGetWindowFromId( NULL, parentTOSID);
- buttonTOSOK = TheWindowManager->winGetWindowFromId( NULL, buttonTOSOKID);
- listboxTOS = TheWindowManager->winGetWindowFromId( NULL, listboxTOSID);
- textEntryLoginName = TheWindowManager->winGetWindowFromId( NULL, textEntryLoginNameID);
- textEntryPassword = TheWindowManager->winGetWindowFromId( NULL, textEntryPasswordID);
- checkBoxRememberPassword = TheWindowManager->winGetWindowFromId( NULL, checkBoxRememberPasswordID);
-
- DEBUG_ASSERTCRASH(buttonBack, ("buttonBack missing!"));
- DEBUG_ASSERTCRASH(buttonLogin, ("buttonLogin missing!"));
- DEBUG_ASSERTCRASH(buttonCreateAccount, ("buttonCreateAccount missing!"));
- DEBUG_ASSERTCRASH(buttonUseAccount, ("buttonUseAccount missing!"));
- DEBUG_ASSERTCRASH(textEntryLoginName, ("textEntryLoginName missing!"));
- TheWindowManager->winSetFocus( textEntryLoginName );
- //TheShell->registerWithAnimateManager(parentWOLLogin, WIN_ANIMATION_SLIDE_TOP, TRUE);
-
-// TheShell->registerWithAnimateManager(buttonTOS, WIN_ANIMATION_SLIDE_LEFT, TRUE);
-// TheShell->registerWithAnimateManager(buttonCreateAccount, WIN_ANIMATION_SLIDE_LEFT, TRUE);
-// TheShell->registerWithAnimateManager(buttonUseAccount, WIN_ANIMATION_SLIDE_LEFT, TRUE);
-// TheShell->registerWithAnimateManager(buttonBack, WIN_ANIMATION_SLIDE_RIGHT, TRUE);
-
- }
-#endif // ALLOW_NON_PROFILED_LOGIN
-
-
-#ifdef ALLOW_NON_PROFILED_LOGIN
- if (GameSpyUseProfiles)
- {
-#endif // ALLOW_NON_PROFILED_LOGIN
- // Read login names from registry...
- GadgetComboBoxReset(comboBoxEmail);
- GadgetTextEntrySetText(textEntryPassword, UnicodeString.TheEmptyString);
-
- // look for cached nicks to add
- AsciiString lastName;
- AsciiString lastEmail;
- Bool markCheckBox = FALSE;
- UserPreferences::const_iterator it = loginPref->find("lastName");
- if (it != loginPref->end())
- {
- lastName = it->second;
- }
- it = loginPref->find("lastEmail");
- if (it != loginPref->end())
- {
- lastEmail = it->second;
- }
-
- // fill in list of Emails, and select the most recent
- AsciiStringList cachedEmails = loginPref->getEmails();
- AsciiStringListIterator eIt = cachedEmails.begin();
- Int selectedPos = -1;
- while (eIt != cachedEmails.end())
- {
- UnicodeString uniEmail;
- uniEmail.translate(*eIt);
- Int pos = GadgetComboBoxAddEntry(comboBoxEmail, uniEmail, GameSpyColor[GSCOLOR_DEFAULT]);
- if (*eIt == lastEmail)
- selectedPos = pos;
-
- ++eIt;
- }
- if (selectedPos >= 0)
- {
- GadgetComboBoxSetSelectedPos(comboBoxEmail, selectedPos);
-
- // fill in the password for the selected email
- UnicodeString pass;
- pass.translate(loginPref->getPasswordForEmail(lastEmail));
- GadgetTextEntrySetText(textEntryPassword, pass);
-
- AsciiString month,day,year;
- loginPref->getDateForEmail(lastEmail, month, day, year);
- pass.translate(month);
- GadgetTextEntrySetText(textEntryMonth, pass);
- pass.translate(day);
- GadgetTextEntrySetText(textEntryDay, pass);
- pass.translate(year);
- GadgetTextEntrySetText(textEntryYear, pass);
-
- markCheckBox = TRUE;
- }
-
- // fill in list of nicks for selected email, selecting the most recent
- GadgetComboBoxReset(comboBoxLoginName);
- AsciiStringList cachedNicks = loginPref->getNicksForEmail(lastEmail);
- AsciiStringListIterator nIt = cachedNicks.begin();
- selectedPos = -1;
- while (nIt != cachedNicks.end())
- {
- UnicodeString uniNick;
- uniNick.translate(*nIt);
- Int pos = GadgetComboBoxAddEntry(comboBoxLoginName, uniNick, GameSpyColor[GSCOLOR_DEFAULT]);
- if (*nIt == lastName)
- selectedPos = pos;
-
- ++nIt;
- }
- if (selectedPos >= 0)
- {
- GadgetComboBoxSetSelectedPos(comboBoxLoginName, selectedPos);
- markCheckBox = TRUE;
- }
- // always start with not storing information
- if( markCheckBox)
- GadgetCheckBoxSetChecked(checkBoxRememberPassword, TRUE);
- else
- GadgetCheckBoxSetChecked(checkBoxRememberPassword, FALSE);
-#ifdef ALLOW_NON_PROFILED_LOGIN
- }
- else
- {
- // Read login names from registry...
- GadgetComboBoxReset(comboBoxLoginName);
- UnicodeString nick;
-
- UserPreferences::const_iterator it = loginPref->find("lastName");
- if (it != loginPref->end())
- {
- nick.translate(it->second);
- }
- else
- {
- char userBuf[32] = "";
- unsigned long bufSize = 32;
- GetUserName(userBuf, &bufSize);
- nick.translate(userBuf);
- }
-
- GadgetTextEntrySetText(textEntryLoginName, nick);
- }
-#endif // ALLOW_NON_PROFILED_LOGIN
-
- EnableLoginControls(TRUE);
-
- // Show Menu
- layout->hide( FALSE );
-
- // Set Keyboard to Main Parent
-
- RaiseGSMessageBox();
-
- OptionPreferences optionPref;
- if (!optionPref.getBool("SawTOS", TRUE))
- {
- TheWindowManager->winSendSystemMsg( parentWOLLogin, GBM_SELECTED,
- (WindowMsgData)buttonTOS, buttonTOSID );
- }
- TheTransitionHandler->setGroup("GameSpyLoginProfileFade");
-
-} // WOLLoginMenuInit
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Login Menu shutdown method */
-//-------------------------------------------------------------------------------------------------
-static Bool loggedInOK = false;
-void WOLLoginMenuShutdown( WindowLayout *layout, void *userData )
-{
- isShuttingDown = true;
- loggedInOK = false;
- TheWindowManager->clearTabList();
-
- // if we are shutting down for an immediate pop, skip the animations
- Bool popImmediate = *(Bool *)userData;
- if( popImmediate )
- {
-
- shutdownComplete( layout );
- return;
-
- } //end if
-
- TheShell->reverseAnimatewindow();
- TheTransitionHandler->reverse("GameSpyLoginProfileFade");
-
-} // WOLLoginMenuShutdown
-
-
-// this is used to check if we've got all the pings
-static void checkLogin( void )
-{
- if (loggedInOK && ThePinger && !ThePinger->arePingsInProgress())
- {
- // save off our ping string, and end those threads
- AsciiString pingStr = ThePinger->getPingString( 1000 );
- DEBUG_LOG(("Ping string is %s\n", pingStr.str()));
- TheGameSpyInfo->setPingString(pingStr);
- //delete ThePinger;
- //ThePinger = NULL;
-
- buttonPushed = true;
- loggedInOK = false; // don't try this again
-
- loginAttemptTime = 0;
-
- // start looking for group rooms
- TheGameSpyInfo->clearGroupRoomList();
-
- SignalUIInteraction(SHELL_SCRIPT_HOOK_GENERALS_ONLINE_LOGIN);
- nextScreen = "Menus/WOLWelcomeMenu.wnd";
- TheShell->pop();
-
- // read in some cached data
- GameSpyMiscPreferences mPref;
- PSPlayerStats localPSStats = GameSpyPSMessageQueueInterface::parsePlayerKVPairs(mPref.getCachedStats().str());
- localPSStats.id = TheGameSpyInfo->getLocalProfileID();
- TheGameSpyInfo->setCachedLocalPlayerStats(localPSStats);
-// TheGameSpyPSMessageQueue->trackPlayerStats(localPSStats);
-
- // and push the info around to other players
-// PSResponse newResp;
-// newResp.responseType = PSResponse::PSRESPONSE_PLAYERSTATS;
-// newResp.player = localPSStats;
-// TheGameSpyPSMessageQueue->addResponse(newResp);
- }
-}
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Login Menu update method */
-//-------------------------------------------------------------------------------------------------
-void WOLLoginMenuUpdate( WindowLayout * layout, void *userData)
-{
-
- // We'll only be successful if we've requested to
- if(isShuttingDown && TheShell->isAnimFinished() && TheTransitionHandler->isFinished())
- shutdownComplete(layout);
-
- if (TheShell->isAnimFinished() && !buttonPushed && TheGameSpyPeerMessageQueue)
- {
- PingResponse pingResp;
- if (ThePinger && ThePinger->getResponse(pingResp))
- {
- checkLogin();
- }
-
- PeerResponse resp;
- if (!loggedInOK && TheGameSpyPeerMessageQueue->getResponse( resp ))
- {
- switch (resp.peerResponseType)
- {
- case PeerResponse::PEERRESPONSE_GROUPROOM:
- {
- GameSpyGroupRoom room;
- room.m_groupID = resp.groupRoom.id;
- room.m_maxWaiting = resp.groupRoom.maxWaiting;
- room.m_name = resp.groupRoomName.c_str();
- room.m_translatedName = UnicodeString(L"TEST");
- room.m_numGames = resp.groupRoom.numGames;
- room.m_numPlaying = resp.groupRoom.numPlaying;
- room.m_numWaiting = resp.groupRoom.numWaiting;
- TheGameSpyInfo->addGroupRoom( room );
- }
- break;
- case PeerResponse::PEERRESPONSE_LOGIN:
- {
- loggedInOK = true;
-
- // fetch our player info
- TheGameSpyInfo->setLocalName( resp.nick.c_str() );
- TheGameSpyInfo->setLocalProfileID( resp.player.profileID );
- TheGameSpyInfo->loadSavedIgnoreList();
- TheGameSpyInfo->setLocalIPs(resp.player.internalIP, resp.player.externalIP);
- TheGameSpyInfo->readAdditionalDisconnects();
- //TheGameSpyInfo->setLocalEmail( resp.player.email );
- //TheGameSpyInfo->setLocalPassword( resp)
-
- GameSpyMiscPreferences miscPref;
- TheGameSpyInfo->setMaxMessagesPerUpdate(miscPref.getMaxMessagesPerUpdate());
- }
- break;
- case PeerResponse::PEERRESPONSE_DISCONNECT:
- {
- loginAttemptTime = 0;
- UnicodeString title, body;
- AsciiString disconMunkee;
- disconMunkee.format("GUI:GSDisconReason%d", resp.discon.reason);
- title = TheGameText->fetch( "GUI:GSErrorTitle" );
- body = TheGameText->fetch( disconMunkee );
- GSMessageBoxOk( title, body );
- EnableLoginControls( TRUE );
-
- // kill & restart the threads
- AsciiString motd = TheGameSpyInfo->getMOTD();
- AsciiString config = TheGameSpyInfo->getConfig();
- DEBUG_LOG(("Tearing down GameSpy from WOLLoginMenuUpdate(PEERRESPONSE_DISCONNECT)\n"));
- TearDownGameSpy();
- SetUpGameSpy( motd.str(), config.str() );
- }
- break;
- }
- }
-
- checkLogin();
- }
-
- if (TheGameSpyInfo && !buttonPushed && loginAttemptTime && (loginAttemptTime + loginTimeoutInMS < timeGetTime()))
- {
- // timed out a login attempt, so say so
- loginAttemptTime = 0;
- UnicodeString title, body;
- AsciiString disconMunkee;
- disconMunkee.format("GUI:GSDisconReason4"); // ("could not connect to server")
- title = TheGameText->fetch( "GUI:GSErrorTitle" );
- body = TheGameText->fetch( disconMunkee );
- GSMessageBoxOk( title, body );
- EnableLoginControls( TRUE );
-
- // kill & restart the threads
- AsciiString motd = TheGameSpyInfo->getMOTD();
- AsciiString config = TheGameSpyInfo->getConfig();
- DEBUG_LOG(("Tearing down GameSpy from WOLLoginMenuUpdate(login timeout)\n"));
- TearDownGameSpy();
- SetUpGameSpy( motd.str(), config.str() );
- }
-
-}// WOLLoginMenuUpdate
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Login Menu input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLLoginMenuInput( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
- UnsignedByte key = mData1;
- UnsignedByte state = mData2;
- if (buttonPushed)
- break;
-
- switch( key )
- {
-
- // ----------------------------------------------------------------------------------------
- case KEY_ESC:
- {
-
- //
- // send a simulated selected event to the parent window of the
- // back/exit button
- //
- if( BitTest( state, KEY_STATE_UP ) )
- {
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)buttonBack, buttonBackID );
-
- } // end if
-
- // don't let key fall through anywhere else
- return MSG_HANDLED;
-
- } // end escape
-
- } // end switch( key )
-
- } // end char
-
- } // end switch( msg )
-
- return MSG_IGNORED;
-}// WOLLoginMenuInput
-
-static Bool isNickOkay(UnicodeString nick)
-{
- static const WideChar * legalIRCChars = L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789[]`_^{|}-";
-
- Int len = nick.getLength();
- if (len == 0)
- return TRUE;
-
- if (len == 1 && nick.getCharAt(0) == L'-')
- return FALSE;
-
- WideChar newChar = nick.getCharAt(len-1);
- if (wcschr(legalIRCChars, newChar) == NULL)
- return FALSE;
-
- return TRUE;
-}
-
-static Bool isAgeOkay(AsciiString &month, AsciiString &day, AsciiString year)
-{
- if(month.isEmpty() || day.isEmpty() || year.isEmpty() || year.getLength() != 4)
- return FALSE;
-
- Int monthInt = atoi(month.str());
- Int dayInt = atoi(day.str());
-
- if(monthInt > 12 || dayInt > 31)
- return FALSE;
- // setup date buffer for local region date format
- month.format("%02.2d",monthInt);
- day.format("%02.2d",dayInt);
-
- // test the year first
- #define DATE_BUFFER_SIZE 256
- char dateBuffer[ DATE_BUFFER_SIZE ];
- GetDateFormat( LOCALE_SYSTEM_DEFAULT,
- 0, NULL,
- "yyyy",
- dateBuffer, DATE_BUFFER_SIZE );
- Int sysVal = atoi(dateBuffer);
- Int userVal = atoi(year.str());
- if(sysVal - userVal >= 14)
- return TRUE;
- else if( sysVal - userVal <= 12)
- return FALSE;
-
- GetDateFormat( LOCALE_SYSTEM_DEFAULT,
- 0, NULL,
- "MM",
- dateBuffer, DATE_BUFFER_SIZE );
- sysVal = atoi(dateBuffer);
- userVal = atoi(month.str());
- if(sysVal - userVal >0 )
- return TRUE;
- else if( sysVal -userVal < 0 )
- return FALSE;
-// month.format("%02.2d",userVal);
- GetDateFormat( LOCALE_SYSTEM_DEFAULT,
- 0, NULL,
- "dd",
- dateBuffer, DATE_BUFFER_SIZE );
- sysVal = atoi(dateBuffer);
- userVal = atoi(day.str());
- if(sysVal - userVal< 0)
- return FALSE;
-// day.format("%02.2d",userVal);
- return TRUE;
-}
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Login Menu window system callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLLoginMenuSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- UnicodeString txtInput;
-
- switch( msg )
- {
-
-
- case GWM_CREATE:
- {
- break;
- } // case GWM_DESTROY:
-
- case GWM_DESTROY:
- {
- break;
- } // case GWM_DESTROY:
-
- case GWM_INPUT_FOCUS:
- {
- // if we're givin the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
-
- return MSG_HANDLED;
- }//case GWM_INPUT_FOCUS:
-
- // someone typed in a combo box. Clear password (or fill it in if the typed name matches a known login name)
- case GCM_UPDATE_TEXT:
- {
- UnicodeString uNick = GadgetComboBoxGetText(comboBoxLoginName);
- UnicodeString uEmail = GadgetComboBoxGetText(comboBoxEmail);
- AsciiString nick, email;
- nick.translate(uNick);
- email.translate(uEmail);
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- UnicodeString trimmedNick = uNick, trimmedEmail = uEmail;
- trimmedNick.trim();
- trimmedEmail.trim();
- if (!trimmedNick.isEmpty())
- {
- if (trimmedNick.getCharAt(trimmedNick.getLength()-1) == L'\\')
- trimmedNick.removeLastChar();
- if (trimmedNick.getCharAt(trimmedNick.getLength()-1) == L'/')
- trimmedNick.removeLastChar();
- }
- if (!trimmedEmail.isEmpty())
- {
- if (trimmedEmail.getCharAt(trimmedEmail.getLength()-1) == L'\\')
- trimmedEmail.removeLastChar();
- if (trimmedEmail.getCharAt(trimmedEmail.getLength()-1) == L'/')
- trimmedEmail.removeLastChar();
- }
- if (trimmedEmail.getLength() != uEmail.getLength())
- {
- // we just trimmed a space. set the text back and bail
- GadgetComboBoxSetText(comboBoxEmail, trimmedEmail);
- break;
- }
- if (trimmedNick.getLength() != nick.getLength())
- {
- // we just trimmed a space. set the text back and bail
- GadgetComboBoxSetText(comboBoxLoginName, trimmedNick);
- break;
- }
-
- if (controlID == comboBoxEmailID)
- {
- // email changed. look up password, and choose new login names
-
- // fill in the password for the selected email
- UnicodeString pass;
- pass.translate(loginPref->getPasswordForEmail(email));
- GadgetTextEntrySetText(textEntryPassword, pass);
-
- // fill in list of nicks for selected email, selecting the first
- AsciiStringList cachedNicks = loginPref->getNicksForEmail(email);
- AsciiStringListIterator nIt = cachedNicks.begin();
- Int selectedPos = -1;
- GadgetComboBoxReset(comboBoxLoginName);
- while (nIt != cachedNicks.end())
- {
- UnicodeString uniNick;
- uniNick.translate(*nIt);
- GadgetComboBoxAddEntry(comboBoxLoginName, uniNick, GameSpyColor[GSCOLOR_DEFAULT]);
- selectedPos = 0;
- ++nIt;
- }
- if (selectedPos >= 0)
- {
- GadgetComboBoxSetSelectedPos(comboBoxLoginName, selectedPos);
- GadgetCheckBoxSetChecked(checkBoxRememberPassword, true);
- AsciiString month,day,year;
- loginPref->getDateForEmail(email, month, day, year);
- pass.translate(month);
- GadgetTextEntrySetText(textEntryMonth, pass);
- pass.translate(day);
- GadgetTextEntrySetText(textEntryDay, pass);
- pass.translate(year);
- GadgetTextEntrySetText(textEntryYear, pass);
-
- }
- else
- {
- GadgetCheckBoxSetChecked(checkBoxRememberPassword, false);
- GadgetTextEntrySetText(textEntryMonth, UnicodeString::TheEmptyString);
- GadgetTextEntrySetText(textEntryDay, UnicodeString::TheEmptyString);
- GadgetTextEntrySetText(textEntryYear, UnicodeString::TheEmptyString);
-
- }
- }
- else if (controlID == comboBoxLoginNameID)
- {
- // they typed a new login name. Email & pass shouldn't change
- }
-
- break;
- }
-
- case GCM_SELECTED:
- {
- if (buttonPushed)
- break;
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if (controlID == comboBoxEmailID)
- {
- // email changed. look up password, and choose new login names
- UnicodeString uEmail = GadgetComboBoxGetText(comboBoxEmail);
- AsciiString email;
- email.translate(uEmail);
-
- // fill in the password for the selected email
- UnicodeString pass;
- pass.translate(loginPref->getPasswordForEmail(email));
- GadgetTextEntrySetText(textEntryPassword, pass);
-
- // fill in list of nicks for selected email, selecting the first
- AsciiStringList cachedNicks = loginPref->getNicksForEmail(email);
- AsciiStringListIterator nIt = cachedNicks.begin();
- Int selectedPos = -1;
- GadgetComboBoxReset(comboBoxLoginName);
- while (nIt != cachedNicks.end())
- {
- UnicodeString uniNick;
- uniNick.translate(*nIt);
- GadgetComboBoxAddEntry(comboBoxLoginName, uniNick, GameSpyColor[GSCOLOR_DEFAULT]);
- selectedPos = 0;
- ++nIt;
- }
- if (selectedPos >= 0)
- {
- GadgetComboBoxSetSelectedPos(comboBoxLoginName, selectedPos);
- GadgetCheckBoxSetChecked(checkBoxRememberPassword, true);
- AsciiString month,day,year;
- loginPref->getDateForEmail(email, month, day, year);
- pass.translate(month);
- GadgetTextEntrySetText(textEntryMonth, pass);
- pass.translate(day);
- GadgetTextEntrySetText(textEntryDay, pass);
- pass.translate(year);
- GadgetTextEntrySetText(textEntryYear, pass);
-
- }
- else
- {
- GadgetCheckBoxSetChecked(checkBoxRememberPassword, false);
- GadgetTextEntrySetText(textEntryMonth, UnicodeString::TheEmptyString);
- GadgetTextEntrySetText(textEntryDay, UnicodeString::TheEmptyString);
- GadgetTextEntrySetText(textEntryYear, UnicodeString::TheEmptyString);
- }
-
- }
- else if (controlID == comboBoxLoginNameID)
- {
- // they typed a new login name. Email & pass shouldn't change
- }
- break;
- }
-
- case GBM_SELECTED:
- {
- if (buttonPushed)
- break;
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- // If we back out, just bail - we haven't gotten far enough to need to log out
- if ( controlID == buttonBackID )
- {
- buttonPushed = true;
- TearDownGameSpy();
- TheShell->pop();
- } //if ( controlID == buttonBack )
-#ifdef ALLOW_NON_PROFILED_LOGIN
- else if ( controlID == buttonUseAccountID )
- {
- buttonPushed = true;
- nextScreen = "Menus/GameSpyLoginProfile.wnd";
- TheShell->pop();
- //TheShell->push( "Menus/GameSpyLoginProfile.wnd" );
- } //if ( controlID == buttonUseAccount )
- else if ( controlID == buttonDontUseAccountID )
- {
- buttonPushed = true;
- nextScreen = "Menus/GameSpyLoginQuick.wnd";
- TheShell->pop();
- //TheShell->push( "Menus/GameSpyLoginQuick.wnd" );
- } //if ( controlID == buttonDontUseAccount )
-#endif // ALLOW_NON_PROFILED_LOGIN
- else if ( controlID == buttonCreateAccountID )
- {
-#ifdef ALLOW_NON_PROFILED_LOGIN
- if (GameSpyUseProfiles)
- {
-#endif // ALLOW_NON_PROFILED_LOGIN
- // actually attempt to create an account based on info entered
- AsciiString month, day, year;
- month.translate( GadgetTextEntryGetText(textEntryMonth) );
- day.translate( GadgetTextEntryGetText(textEntryDay) );
- year.translate( GadgetTextEntryGetText(textEntryYear) );
-
- if(!isAgeOkay(month, day, year))
- {
- GSMessageBoxOk(TheGameText->fetch("GUI:AgeFailedTitle"), TheGameText->fetch("GUI:AgeFailed"));
- break;
- }
-
- AsciiString login, password, email;
- email.translate( GadgetComboBoxGetText(comboBoxEmail) );
- login.translate( GadgetComboBoxGetText(comboBoxLoginName) );
- password.translate( GadgetTextEntryGetText(textEntryPassword) );
-
- if ( !email.isEmpty() && !login.isEmpty() && !password.isEmpty() )
- {
- loginAttemptTime = timeGetTime();
- BuddyRequest req;
- req.buddyRequestType = BuddyRequest::BUDDYREQUEST_LOGINNEW;
- strcpy(req.arg.login.nick, login.str());
- strcpy(req.arg.login.email, email.str());
- strcpy(req.arg.login.password, password.str());
- req.arg.login.hasFirewall = TRUE;
-
- TheGameSpyInfo->setLocalBaseName( login );
- //TheGameSpyInfo->setLocalProfileID( resp.player.profileID );
- TheGameSpyInfo->setLocalEmail( email );
- TheGameSpyInfo->setLocalPassword( password );
- DEBUG_LOG(("before create: TheGameSpyInfo->stuff(%s/%s/%s)\n", TheGameSpyInfo->getLocalBaseName().str(), TheGameSpyInfo->getLocalEmail().str(), TheGameSpyInfo->getLocalPassword().str()));
-
- TheGameSpyBuddyMessageQueue->addRequest( req );
- if(checkBoxRememberPassword && GadgetCheckBoxIsChecked(checkBoxRememberPassword))
- {
- (*loginPref)["lastName"] = login;
- (*loginPref)["lastEmail"] = email;
- (*loginPref)["useProfiles"] = "yes";
- AsciiString date;
- date = month;
- date.concat(day);
- date.concat(year);
-
- loginPref->addLogin(email, login, password, date);
- }
-
- EnableLoginControls( FALSE );
-
- // fire off some pings
- startPings();
- }
- else
- {
- // user didn't fill in all info. prompt him.
- if(email.isEmpty() && login.isEmpty() && password.isEmpty())
- GSMessageBoxOk(TheGameText->fetch("GUI:Error"), TheGameText->fetch("GUI:GSNoLoginInfoAll"));
- else if( email.isEmpty() && login.isEmpty())
- GSMessageBoxOk(TheGameText->fetch("GUI:Error"), TheGameText->fetch("GUI:GSNoLoginInfoEmailNickname"));
- else if( email.isEmpty() && password.isEmpty())
- GSMessageBoxOk(TheGameText->fetch("GUI:Error"), TheGameText->fetch("GUI:GSNoLoginInfoEmailPassword"));
- else if( login.isEmpty() && password.isEmpty())
- GSMessageBoxOk(TheGameText->fetch("GUI:Error"), TheGameText->fetch("GUI:GSNoLoginInfoNicknamePassword"));
- else if( email.isEmpty())
- GSMessageBoxOk(TheGameText->fetch("GUI:Error"), TheGameText->fetch("GUI:GSNoLoginInfoEmail"));
- else if( password.isEmpty())
- GSMessageBoxOk(TheGameText->fetch("GUI:Error"), TheGameText->fetch("GUI:GSNoLoginInfoPassword"));
- else if( login.isEmpty() )
- GSMessageBoxOk(TheGameText->fetch("GUI:Error"), TheGameText->fetch("GUI:GSNoLoginInfoNickname"));
- else
- GSMessageBoxOk(TheGameText->fetch("GUI:Error"), TheGameText->fetch("GUI:GSNoLoginInfoAll"));
- }
-#ifdef ALLOW_NON_PROFILED_LOGIN
- }
- else
- {
- // not the profile screen - switch to it
- buttonPushed = TRUE;
- nextScreen = "Menus/GameSpyLoginProfile.wnd";
- TheShell->pop();
- }
-#endif // ALLOW_NON_PROFILED_LOGIN
- } //if ( controlID == buttonCreateAccount )
- else if ( controlID == buttonLoginID )
- {
- AsciiString login, password, email;
-
-#ifdef ALLOW_NON_PROFILED_LOGIN
- if (GameSpyUseProfiles)
- {
-#endif // ALLOW_NON_PROFILED_LOGIN
- AsciiString month, day, year;
- month.translate( GadgetTextEntryGetText(textEntryMonth) );
- day.translate( GadgetTextEntryGetText(textEntryDay) );
- year.translate( GadgetTextEntryGetText(textEntryYear) );
-
- if(!isAgeOkay(month, day, year))
- {
- GSMessageBoxOk(TheGameText->fetch("GUI:AgeFailedTitle"), TheGameText->fetch("GUI:AgeFailed"));
- break;
- }
-
- email.translate( GadgetComboBoxGetText(comboBoxEmail) );
- login.translate( GadgetComboBoxGetText(comboBoxLoginName) );
- password.translate( GadgetTextEntryGetText(textEntryPassword) );
-
- if ( !email.isEmpty() && !login.isEmpty() && !password.isEmpty() )
- {
- loginAttemptTime = timeGetTime();
- BuddyRequest req;
- req.buddyRequestType = BuddyRequest::BUDDYREQUEST_LOGIN;
- strcpy(req.arg.login.nick, login.str());
- strcpy(req.arg.login.email, email.str());
- strcpy(req.arg.login.password, password.str());
- req.arg.login.hasFirewall = true;
-
- TheGameSpyInfo->setLocalBaseName( login );
- //TheGameSpyInfo->setLocalProfileID( resp.player.profileID );
- TheGameSpyInfo->setLocalEmail( email );
- TheGameSpyInfo->setLocalPassword( password );
- DEBUG_LOG(("before login: TheGameSpyInfo->stuff(%s/%s/%s)\n", TheGameSpyInfo->getLocalBaseName().str(), TheGameSpyInfo->getLocalEmail().str(), TheGameSpyInfo->getLocalPassword().str()));
-
- TheGameSpyBuddyMessageQueue->addRequest( req );
- if(checkBoxRememberPassword && GadgetCheckBoxIsChecked(checkBoxRememberPassword))
- {
- (*loginPref)["lastName"] = login;
- (*loginPref)["lastEmail"] = email;
- (*loginPref)["useProfiles"] = "yes";
- AsciiString date;
- date = month;
- date.concat(day);
- date.concat(year);
-
- loginPref->addLogin(email, login, password,date);
- }
- else
- {
- loginPref->forgetLogin(email);
- }
- EnableLoginControls( FALSE );
-
- // fire off some pings
- startPings();
- }
- else
- {
- // user didn't fill in all info. prompt him.
- if(email.isEmpty() && login.isEmpty() && password.isEmpty())
- GSMessageBoxOk(TheGameText->fetch("GUI:GSErrorTitle"), TheGameText->fetch("GUI:GSNoLoginInfoAll"));
- else if( email.isEmpty() && login.isEmpty())
- GSMessageBoxOk(TheGameText->fetch("GUI:GSErrorTitle"), TheGameText->fetch("GUI:GSNoLoginInfoEmailNickname"));
- else if( email.isEmpty() && password.isEmpty())
- GSMessageBoxOk(TheGameText->fetch("GUI:GSErrorTitle"), TheGameText->fetch("GUI:GSNoLoginInfoEmailPassword"));
- else if( login.isEmpty() && password.isEmpty())
- GSMessageBoxOk(TheGameText->fetch("GUI:GSErrorTitle"), TheGameText->fetch("GUI:GSNoLoginInfoNicknamePassword"));
- else if( email.isEmpty())
- GSMessageBoxOk(TheGameText->fetch("GUI:GSErrorTitle"), TheGameText->fetch("GUI:GSNoLoginInfoEmail"));
- else if( password.isEmpty())
- GSMessageBoxOk(TheGameText->fetch("GUI:GSErrorTitle"), TheGameText->fetch("GUI:GSNoLoginInfoPassword"));
- else if( login.isEmpty() )
- GSMessageBoxOk(TheGameText->fetch("GUI:GSErrorTitle"), TheGameText->fetch("GUI:GSNoLoginInfoNickname"));
- else
- GSMessageBoxOk(TheGameText->fetch("GUI:GSErrorTitle"), TheGameText->fetch("GUI:GSNoLoginInfoAll"));
- }
-#ifdef ALLOW_NON_PROFILED_LOGIN
- }
- else
- {
- login.translate( GadgetTextEntryGetText(textEntryLoginName) );
-
- if ( !login.isEmpty() )
- {
- loginAttemptTime = timeGetTime();
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_LOGIN;
- req.nick = login.str();
- req.login.profileID = 0;
- TheGameSpyPeerMessageQueue->addRequest( req );
-
- (*loginPref)["lastName"] = login;
- loginPref->erase("lastEmail");
- (*loginPref)["useProfiles"] = "no";
- EnableLoginControls( FALSE );
-
- // fire off some pings
- startPings();
- }
- }
-#endif // ALLOW_NON_PROFILED_LOGIN
-
- } //if ( controlID == buttonLogin )
- else if ( controlID == buttonTOSID )
- {
- parentTOS->winHide(FALSE);
-
- if (1)
- {
- // Okay, no web browser. This means we're looking at a UTF-8 text file.
- GadgetListBoxReset(listboxTOS);
- AsciiString fileName;
- fileName.format("Data\\%s\\TOS.txt", GetRegistryLanguage().str());
- File *theFile = TheFileSystem->openFile(fileName.str(), File::READ);
- if (theFile)
- {
- Int size = theFile->size();
-
- char *fileBuf = new char[size];
- Color tosColor = GameMakeColor(255, 255, 255, 255);
-
- Int bytesRead = theFile->read(fileBuf, size);
- if (bytesRead == size && size > 2)
- {
- fileBuf[size-1] = 0; // just to be safe
- AsciiString asciiBuf = fileBuf+2;
- AsciiString asciiLine;
- while (asciiBuf.nextToken(&asciiLine, "\r\n"))
- {
- UnicodeString uniLine;
- uniLine = UnicodeString(MultiByteToWideCharSingleLine(asciiLine.str()).c_str());
- int len = uniLine.getLength();
- for (int index = len-1; index >= 0; index--)
- {
- if (iswspace(uniLine.getCharAt(index)))
- {
- uniLine.removeLastChar();
- }
- else
- {
- break;
- }
- }
- //uniLine.trim();
- DEBUG_LOG(("adding TOS line: [%ls]\n", uniLine.str()));
- GadgetListBoxAddEntryText(listboxTOS, uniLine, tosColor, -1);
- }
-
- }
-
- delete fileBuf;
- fileBuf = NULL;
-
- theFile->close();
- theFile = NULL;
- }
- }
- EnableLoginControls( FALSE );
- buttonBack->winEnable(FALSE);
-
- }
- else if ( controlID == buttonTOSOKID )
- {
- EnableLoginControls( TRUE );
-
- parentTOS->winHide(TRUE);
-
- OptionPreferences optionPref;
- optionPref["SawTOS"] = "yes";
- optionPref.write();
- buttonBack->winEnable(TRUE);
- }
- break;
- }// case GBM_SELECTED:
-
- case GEM_EDIT_DONE:
- {
- break;
- }
- /*
- case GEM_UPDATE_TEXT:
- {
- if (buttonPushed)
- break;
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if ( controlID == textEntryLoginNameID )
- {
- UnicodeString munkee = GadgetTextEntryGetText( textEntryLoginName );
- if ( !isNickOkay( munkee ) )
- {
- munkee.removeLastChar();
- GadgetTextEntrySetText( textEntryLoginName, munkee );
- }
- }// if ( controlID == textEntryLoginNameID )
- break;
- }//case GEM_UPDATE_TEXT:
- */
- default:
- return MSG_IGNORED;
-
- }//Switch
-
- return MSG_HANDLED;
-}// WOLLoginMenuSystem
-
-
diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLMapSelectMenu.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLMapSelectMenu.cpp
deleted file mode 100644
index 7cef8850394..00000000000
--- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLMapSelectMenu.cpp
+++ /dev/null
@@ -1,471 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: WOLMapSelectMenu.cpp ////////////////////////////////////////////////////////////////////////
-// Author: Matt Campbell, December 2001
-// Description: MapSelect menu window callbacks
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/CustomMatchPreferences.h"
-#include "Common/GameEngine.h"
-#include "Common/MessageStream.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/GadgetRadioButton.h"
-#include "GameClient/Shell.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/GadgetListBox.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpyOverlay.h"
-#include "GameClient/MapUtil.h"
-#include "GameNetwork/GUIUtil.h"
-
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-static NameKeyType buttonBack = NAMEKEY_INVALID;
-static NameKeyType buttonOK = NAMEKEY_INVALID;
-static NameKeyType listboxMap = NAMEKEY_INVALID;
-static GameWindow *parent = NULL;
-static Bool raiseMessageBoxes = FALSE;
-static GameWindow *winMapPreview = NULL;
-static NameKeyType winMapPreviewID = NAMEKEY_INVALID;
-
-static NameKeyType radioButtonSystemMapsID = NAMEKEY_INVALID;
-static NameKeyType radioButtonUserMapsID = NAMEKEY_INVALID;
-
-extern WindowLayout *WOLMapSelectLayout; ///< Map selection overlay
-static GameWindow *mapList = NULL;
-
-static GameWindow *buttonMapStartPosition[MAX_SLOTS] = {NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL };
-static NameKeyType buttonMapStartPositionID[MAX_SLOTS] = { NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID };
-
-static GameWindow *winMapWindow = NULL;
-
-static void NullifyControls(void)
-{
- parent = NULL;
- winMapPreview = NULL;
- mapList = NULL;
- for (Int i=0; iwinGetWindowFromId( NULL, TheNameKeyGenerator->nameToKey("GameSpyGameOptionsMenu.wnd:ButtonBack") );
- if(win)
- win->winEnable( show );
-}
-
-// PUBLIC FUNCTIONS ///////////////////////////////////////////////////////////////////////////////
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the MapSelect menu */
-//-------------------------------------------------------------------------------------------------
-void WOLMapSelectMenuInit( WindowLayout *layout, void *userData )
-{
-
- // set keyboard focus to main parent
- AsciiString parentName( "WOLMapSelectMenu.wnd:WOLMapSelectMenuParent" );
- NameKeyType parentID = TheNameKeyGenerator->nameToKey( parentName );
- parent = TheWindowManager->winGetWindowFromId( NULL, parentID );
-
- TheWindowManager->winSetFocus( parent );
-
- CustomMatchPreferences pref;
- Bool usesSystemMapDir = pref.usesSystemMapDir();
- winMapPreviewID = TheNameKeyGenerator->nameToKey( AsciiString("WOLMapSelectMenu.wnd:WinMapPreview") );
- winMapPreview = TheWindowManager->winGetWindowFromId(parent, winMapPreviewID);
-
- const MapMetaData *mmd = TheMapCache->findMap(TheGameSpyGame->getMap());
- if (mmd)
- {
- usesSystemMapDir = mmd->m_isOfficial;
- }
-
- buttonBack = TheNameKeyGenerator->nameToKey( AsciiString("WOLMapSelectMenu.wnd:ButtonBack") );
- buttonOK = TheNameKeyGenerator->nameToKey( AsciiString("WOLMapSelectMenu.wnd:ButtonOK") );
- listboxMap = TheNameKeyGenerator->nameToKey( AsciiString("WOLMapSelectMenu.wnd:ListboxMap") );
- radioButtonSystemMapsID = TheNameKeyGenerator->nameToKey( "WOLMapSelectMenu.wnd:RadioButtonSystemMaps" );
- radioButtonUserMapsID = TheNameKeyGenerator->nameToKey( "WOLMapSelectMenu.wnd:RadioButtonUserMaps" );
- winMapWindow = TheWindowManager->winGetWindowFromId( parent, listboxMap );
-
- GameWindow *radioButtonSystemMaps = TheWindowManager->winGetWindowFromId( parent, radioButtonSystemMapsID );
- GameWindow *radioButtonUserMaps = TheWindowManager->winGetWindowFromId( parent, radioButtonUserMapsID );
- if (usesSystemMapDir)
- GadgetRadioSetSelection( radioButtonSystemMaps, FALSE );
- else
- GadgetRadioSetSelection( radioButtonUserMaps, FALSE );
-
- AsciiString tmpString;
- for (Int i = 0; i < MAX_SLOTS; i++)
- {
- tmpString.format("WOLMapSelectMenu.wnd:ButtonMapStartPosition%d", i);
- buttonMapStartPositionID[i] = TheNameKeyGenerator->nameToKey( tmpString );
- buttonMapStartPosition[i] = TheWindowManager->winGetWindowFromId( winMapPreview, buttonMapStartPositionID[i] );
- DEBUG_ASSERTCRASH(buttonMapStartPosition[i], ("Could not find the ButtonMapStartPosition[%d]",i ));
- buttonMapStartPosition[i]->winHide(TRUE);
- buttonMapStartPosition[i]->winEnable(FALSE);
- }
-
- raiseMessageBoxes = TRUE;
- showGameSpyGameOptionsUnderlyingGUIElements( FALSE );
-
- // get the listbox window
- AsciiString listString( "WOLMapSelectMenu.wnd:ListboxMap" );
- NameKeyType mapListID = TheNameKeyGenerator->nameToKey( listString );
- mapList = TheWindowManager->winGetWindowFromId( parent, mapListID );
- if( mapList )
- {
- if (TheMapCache)
- TheMapCache->updateCache();
- populateMapListbox( mapList, usesSystemMapDir, TRUE, TheGameSpyGame->getMap() );
- }
-
-} // end WOLMapSelectMenuInit
-
-//-------------------------------------------------------------------------------------------------
-/** MapSelect menu shutdown method */
-//-------------------------------------------------------------------------------------------------
-void WOLMapSelectMenuShutdown( WindowLayout *layout, void *userData )
-{
- NullifyControls();
-
- // hide menu
- layout->hide( TRUE );
-
- // our shutdown is complete
- TheShell->shutdownComplete( layout );
-
-} // end WOLMapSelectMenuShutdown
-
-//-------------------------------------------------------------------------------------------------
-/** MapSelect menu update method */
-//-------------------------------------------------------------------------------------------------
-void WOLMapSelectMenuUpdate( WindowLayout *layout, void *userData )
-{
-
- if (raiseMessageBoxes)
- {
- RaiseGSMessageBox();
- raiseMessageBoxes = false;
- }
-
- // No update because the game setup screen is up at the same
- // time and it does the update for us...
-} // end WOLMapSelectMenuUpdate
-
-//-------------------------------------------------------------------------------------------------
-/** Map select menu input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLMapSelectMenuInput( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
-
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
- UnsignedByte key = mData1;
- UnsignedByte state = mData2;
-
- switch( key )
- {
-
- // ----------------------------------------------------------------------------------------
- case KEY_ESC:
- {
-
- //
- // send a simulated selected event to the parent window of the
- // back/exit button
- //
- if( BitTest( state, KEY_STATE_UP ) )
- {
- AsciiString buttonName( "WOLMapSelectMenu.wnd:ButtonBack" );
- NameKeyType buttonID = TheNameKeyGenerator->nameToKey( buttonName );
- GameWindow *button = TheWindowManager->winGetWindowFromId( window, buttonID );
-
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)button, buttonID );
-
- } // end if
-
- // don't let key fall through anywhere else
- return MSG_HANDLED;
-
- } // end escape
-
- } // end switch( key )
-
- } // end char
-
- } // end switch( msg )
-
- return MSG_IGNORED;
-
-} // end WOLMapSelectMenuInput
-void WOLPositionStartSpots( void );
-
-//-------------------------------------------------------------------------------------------------
-/** MapSelect menu window system callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLMapSelectMenuSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
-
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CREATE:
- {
- break;
-
- } // end create
-
- //---------------------------------------------------------------------------------------------
- case GWM_DESTROY:
- {
- NullifyControls();
- break;
-
- } // end case
-
- // --------------------------------------------------------------------------------------------
- case GWM_INPUT_FOCUS:
- {
-
- // if we're givin the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
-
- return MSG_HANDLED;
-
- } // end input
-
- //---------------------------------------------------------------------------------------------
- case GLM_DOUBLE_CLICKED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- if( controlID == listboxMap )
- {
- int rowSelected = mData2;
-
- if (rowSelected >= 0)
- {
- GadgetListBoxSetSelected( control, rowSelected );
- GameWindow *button = TheWindowManager->winGetWindowFromId( window, buttonOK );
-
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)button, buttonOK );
- }
- }
- break;
- }
- //---------------------------------------------------------------------------------------------
- case GLM_SELECTED:
- {
-
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- if( controlID == listboxMap )
- {
- int rowSelected = mData2;
- if( rowSelected < 0 )
- {
- positionStartSpots( AsciiString::TheEmptyString, buttonMapStartPosition, winMapPreview);
-// winMapPreview->winClearStatus(WIN_STATUS_IMAGE);
- break;
- }
- winMapPreview->winSetStatus(WIN_STATUS_IMAGE);
- UnicodeString map;
- // get text of the map to load
- map = GadgetListBoxGetText( winMapWindow, rowSelected, 0 );
-
- // set the map name in the global data map name
- AsciiString asciiMap;
- const char *mapFname = (const char *)GadgetListBoxGetItemData( winMapWindow, rowSelected );
- DEBUG_ASSERTCRASH(mapFname, ("No map item data"));
- if (mapFname)
- asciiMap = mapFname;
- else
- asciiMap.translate( map );
- asciiMap.toLower();
- Image *image = getMapPreviewImage(asciiMap);
- winMapPreview->winSetUserData((void *)TheMapCache->findMap(asciiMap));
- if(image)
- {
- winMapPreview->winSetEnabledImage(0, image);
- }
- else
- {
- winMapPreview->winClearStatus(WIN_STATUS_IMAGE);
- }
- positionStartSpots( asciiMap, buttonMapStartPosition, winMapPreview);
- }
- break;
- }
- //---------------------------------------------------------------------------------------------
- case GBM_SELECTED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if( controlID == buttonBack )
- {
- showGameSpyGameOptionsUnderlyingGUIElements( TRUE );
-
- WOLMapSelectLayout->destroyWindows();
- WOLMapSelectLayout->deleteInstance();
- WOLMapSelectLayout = NULL;
- WOLPositionStartSpots();
- } // end if
- else if ( controlID == radioButtonSystemMapsID )
- {
- if (TheMapCache)
- TheMapCache->updateCache();
- populateMapListbox( mapList, TRUE, TRUE, TheGameSpyGame->getMap() );
- CustomMatchPreferences pref;
- pref.setUsesSystemMapDir(TRUE);
- pref.write();
- }
- else if ( controlID == radioButtonUserMapsID )
- {
- if (TheMapCache)
- TheMapCache->updateCache();
- populateMapListbox( mapList, FALSE, TRUE, TheGameSpyGame->getMap() );
- CustomMatchPreferences pref;
- pref.setUsesSystemMapDir(FALSE);
- pref.write();
- }
- else if( controlID == buttonOK )
- {
- Int selected;
- UnicodeString map;
-
- // get the selected index
- GadgetListBoxGetSelected( winMapWindow, &selected );
-
- if( selected != -1 )
- {
-
- // get text of the map to load
- map = GadgetListBoxGetText( winMapWindow, selected, 0 );
-
-
- // set the map name in the global data map name
- AsciiString asciiMap;
- const char *mapFname = (const char *)GadgetListBoxGetItemData( winMapWindow, selected );
- DEBUG_ASSERTCRASH(mapFname, ("No map item data"));
- if (mapFname)
- asciiMap = mapFname;
- else
- asciiMap.translate( map );
- TheGameSpyGame->setMap(asciiMap);
- asciiMap.toLower();
- std::map::iterator it = TheMapCache->find(asciiMap);
- if (it != TheMapCache->end())
- {
- TheGameSpyGame->getGameSpySlot(0)->setMapAvailability(TRUE);
- TheGameSpyGame->setMapCRC( it->second.m_CRC );
- TheGameSpyGame->setMapSize( it->second.m_filesize );
- }
-
- TheGameSpyGame->adjustSlotsForMap(); // BGC- adjust the slots for the new map.
- TheGameSpyGame->resetAccepted();
- TheGameSpyGame->resetStartSpots();
- TheGameSpyInfo->setGameOptions();
-
- WOLDisplaySlotList();
- WOLDisplayGameOptions();
-
- WOLMapSelectLayout->destroyWindows();
- WOLMapSelectLayout->deleteInstance();
- WOLMapSelectLayout = NULL;
-
- showGameSpyGameOptionsUnderlyingGUIElements( TRUE );
-
- WOLPositionStartSpots();
-
- } // end if
-
- } // end else if
-
- break;
-
- } // end selected
-
- default:
- return MSG_IGNORED;
-
- } // end switch
-
- return MSG_HANDLED;
-
-} // end WOLMapSelectMenuSystem
diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLMessageWindow.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLMessageWindow.cpp
deleted file mode 100644
index 897b3defb8f..00000000000
--- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLMessageWindow.cpp
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////////////
-// FILE: WOLMessageWindow.cpp
-// Author: Chris Huybregts, November 2001
-// Description: Lan Lobby Menu
-///////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/GameEngine.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/Shell.h"
-#include "GameClient/KeyDefs.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/GadgetListBox.h"
-#include "GameClient/GadgetTextEntry.h"
-#include "GameNetwork/IPEnumeration.h"
-//#include "GameNetwork/WOL.h"
-
-
-
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-// window ids ------------------------------------------------------------------------------
-static NameKeyType parentWOLMessageWindowID = NAMEKEY_INVALID;
-static NameKeyType buttonCancelID = NAMEKEY_INVALID;
-
-// Window Pointers ------------------------------------------------------------------------
-static GameWindow *parentWOLMessageWindow = NULL;
-static GameWindow *buttonCancel = NULL;
-
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the WOLMessage Window */
-//-------------------------------------------------------------------------------------------------
-void WOLMessageWindowInit( WindowLayout *layout, void *userData )
-{
- parentWOLMessageWindowID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLMessageWindow.wnd:WOLMessageWindowParent" ) );
- buttonCancelID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLMessageWindow.wnd:ButtonCancel" ) );
- parentWOLMessageWindow = TheWindowManager->winGetWindowFromId( NULL, parentWOLMessageWindowID );
- buttonCancel = TheWindowManager->winGetWindowFromId( NULL, buttonCancelID);
-
-
- // Show Menu
- layout->hide( FALSE );
-
- // Set Keyboard to Main Parent
- TheWindowManager->winSetFocus( parentWOLMessageWindow );
-
-} // WOLMessageWindowInit
-
-//-------------------------------------------------------------------------------------------------
-/** WOLMessage Window shutdown method */
-//-------------------------------------------------------------------------------------------------
-void WOLMessageWindowShutdown( WindowLayout *layout, void *userData )
-{
-
- // hide menu
- layout->hide( TRUE );
-
- // our shutdown is complete
- TheShell->shutdownComplete( layout );
-} // WOLMessageWindowShutdown
-
-
-//-------------------------------------------------------------------------------------------------
-/** WOLMessage Window update method */
-//-------------------------------------------------------------------------------------------------
-void WOLMessageWindowUpdate( WindowLayout * layout, void *userData)
-{
- /*
- if (WOL::TheWOL)
- WOL::TheWOL->update();
- */
-
-}// WOLMessageWindowUpdate
-
-//-------------------------------------------------------------------------------------------------
-/** WOLMessage Window input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLMessageWindowInput( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
- UnsignedByte key = mData1;
- UnsignedByte state = mData2;
-
- switch( key )
- {
-
- // ----------------------------------------------------------------------------------------
- case KEY_ESC:
- {
-
- //
- // send a simulated selected event to the parent window of the
- // back/exit button
- //
- if( BitTest( state, KEY_STATE_UP ) )
- {
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)buttonCancel, buttonCancelID );
-
- } // end if
-
- // don't let key fall through anywhere else
- return MSG_HANDLED;
-
- } // end escape
-
- } // end switch( key )
-
- } // end char
-
- } // end switch( msg )
-
- return MSG_IGNORED;
-}// WOLMessageWindowInput
-
-//-------------------------------------------------------------------------------------------------
-/** WOLMessage Window window system callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLMessageWindowSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- UnicodeString txtInput;
-
- switch( msg )
- {
-
-
- case GWM_CREATE:
- {
-
- break;
- } // case GWM_DESTROY:
-
- case GWM_DESTROY:
- {
- break;
- } // case GWM_DESTROY:
-
- case GWM_INPUT_FOCUS:
- {
- // if we're givin the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
-
- return MSG_HANDLED;
- }//case GWM_INPUT_FOCUS:
-
- case GBM_SELECTED:
- {
- break;
- }// case GBM_SELECTED:
-
- case GEM_EDIT_DONE:
- {
- break;
- }
- default:
- return MSG_IGNORED;
-
- }//Switch
-
- return MSG_HANDLED;
-}// WOLMessageWindowSystem
diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQMScoreScreen.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQMScoreScreen.cpp
deleted file mode 100644
index 26b21f3e7bd..00000000000
--- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQMScoreScreen.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////////////
-// FILE: WOLQMScoreScreen.cpp
-// Author: Matt Campbell, November 2001
-// Description: QuickMatch score screen (different from normal screen in that it has 'QM' and 'Discon' buttons)
-///////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/GameEngine.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/Shell.h"
-#include "GameClient/KeyDefs.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/GadgetListBox.h"
-#include "GameClient/GadgetTextEntry.h"
-//#include "GameNetwork/WOL.h"
-//#include "GameNetwork/WOLmenus.h"
-
-
-
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-// window ids ------------------------------------------------------------------------------
-static NameKeyType parentWOLQMScoreID = NAMEKEY_INVALID;
-static NameKeyType buttonDisconnectID = NAMEKEY_INVALID;
-static NameKeyType buttonQuickmatchID = NAMEKEY_INVALID;
-
-// Window Pointers ------------------------------------------------------------------------
-static GameWindow *parentWOLQMScore = NULL;
-static GameWindow *buttonDisconnect = NULL;
-static GameWindow *buttonQuickmatch = NULL;
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the WOL Status Menu */
-//-------------------------------------------------------------------------------------------------
-void WOLQMScoreScreenInit( WindowLayout *layout, void *userData )
-{
- parentWOLQMScoreID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLQMScoreScreen.wnd:WOLQMScoreScreenParent" ) );
- buttonDisconnectID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLQMScoreScreen.wnd:ButtonDisconnect" ) );
- buttonQuickmatchID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLQMScoreScreen.wnd:ButtonQuickMatch" ) );
- parentWOLQMScore = TheWindowManager->winGetWindowFromId( NULL, parentWOLQMScoreID );
- buttonDisconnect = TheWindowManager->winGetWindowFromId( NULL, buttonDisconnectID);
- buttonQuickmatch = TheWindowManager->winGetWindowFromId( NULL, buttonQuickmatchID);
-
- /*
- if (WOL::TheWOL->getState() == WOL::WOLAPI_FATAL_ERROR)
- {
- // We can get to the score screen even though we've been disconnected. Just hide
- // any buttons that lead back into WOL.
-
- buttonQuickmatch->winHide( TRUE );
- }
- */
-
- // Show Menu
- layout->hide( FALSE );
-
- // Set Keyboard to Main Parent
- TheWindowManager->winSetFocus( parentWOLQMScore );
-
- //progressLayout = TheShell->top();
-
-} // WOLQMScoreScreenInit
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Status Menu shutdown method */
-//-------------------------------------------------------------------------------------------------
-void WOLQMScoreScreenShutdown( WindowLayout *layout, void *userData )
-{
-
- // hide menu
- layout->hide( TRUE );
-
- // our shutdown is complete
- TheShell->shutdownComplete( layout );
-
- //progressLayout = NULL;
-
-} // WOLQMScoreScreenShutdown
-
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Status Menu update method */
-//-------------------------------------------------------------------------------------------------
-void WOLQMScoreScreenUpdate( WindowLayout * layout, void *userData)
-{
- /*
- if (WOL::TheWOL)
- WOL::TheWOL->update();
- */
-}// WOLQMScoreScreenUpdate
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Status Menu input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLQMScoreScreenInput( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
- UnsignedByte key = mData1;
- UnsignedByte state = mData2;
-
- switch( key )
- {
-
- // ----------------------------------------------------------------------------------------
- case KEY_ESC:
- {
-
- //
- // send a simulated selected event to the parent window of the
- // back/exit button
- //
- if( BitTest( state, KEY_STATE_UP ) )
- {
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)buttonDisconnect, buttonDisconnectID );
-
- } // end if
-
- // don't let key fall through anywhere else
- return MSG_HANDLED;
-
- } // end escape
-
- } // end switch( key )
-
- } // end char
-
- } // end switch( msg )
-
- return MSG_IGNORED;
-}// WOLQMScoreScreenInput
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Status Menu window system callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLQMScoreScreenSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- UnicodeString txtInput;
-
- switch( msg )
- {
-
-
- case GWM_CREATE:
- {
-
- break;
- } // case GWM_DESTROY:
-
- case GWM_DESTROY:
- {
- break;
- } // case GWM_DESTROY:
-
- case GWM_INPUT_FOCUS:
- {
- // if we're given the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
-
- return MSG_HANDLED;
- }//case GWM_INPUT_FOCUS:
-
- case GBM_SELECTED:
- {
- /*
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if ( controlID == buttonDisconnectID )
- {
- //TheShell->pop();
- if (WOL::TheWOL->setState( WOL::WOLAPI_FATAL_ERROR ))
- {
- WOL::TheWOL->addCommand( WOL::WOLCOMMAND_RESET ); // don't display an error, log out, or anything
- }
-
- } //if ( controlID == buttonDisconnect )
- else if ( controlID == buttonQuickmatchID )
- {
- //TheShell->pop();
- if (WOL::TheWOL->getState() != WOL::WOLAPI_FATAL_ERROR)
- {
- if (WOL::TheWOL->setState( WOL::WOLAPI_TOURNAMENT ))
- {
- WOL::TheWOL->setScreen( WOL::WOLAPI_MENU_QUICKMATCH );
- WOL::TheWOL->addCommand( WOL::WOLCOMMAND_FIND_MATCH_CHANNEL );
- }
- }
-
- } //if ( controlID == buttonDisconnect )
- */
- break;
- }// case GBM_SELECTED:
-
- case GEM_EDIT_DONE:
- {
- break;
- }
- default:
- return MSG_IGNORED;
-
- }//Switch
-
- return MSG_HANDLED;
-}// WOLQMScoreScreenSystem
diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQuickMatchMenu.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQuickMatchMenu.cpp
deleted file mode 100644
index 2b42682acb8..00000000000
--- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQuickMatchMenu.cpp
+++ /dev/null
@@ -1,1832 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////////////
-// FILE: WOLQuickMatchMenu.cpp
-// Author: Chris Huybregts, November 2001
-// Description: Lan Lobby Menu
-///////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/GameEngine.h"
-#include "Common/QuickmatchPreferences.h"
-#include "Common/LadderPreferences.h"
-#include "Common/MultiplayerSettings.h"
-#include "Common/PlayerTemplate.h"
-#include "GameClient/AnimateWindowManager.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/GameText.h"
-#include "GameClient/InGameUI.h"
-#include "GameClient/Shell.h"
-#include "GameClient/ShellHooks.h"
-#include "GameClient/KeyDefs.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/GadgetComboBox.h"
-#include "GameClient/GadgetPushButton.h"
-#include "GameClient/GadgetListBox.h"
-#include "GameClient/GadgetTextEntry.h"
-#include "GameClient/GadgetStaticText.h"
-#include "GameClient/MapUtil.h"
-#include "GameClient/GameWindowTransitions.h"
-
-#include "GameLogic/GameLogic.h"
-
-#include "GameNetwork/NAT.h"
-#include "GameNetwork/GameSpyOverlay.h"
-#include "GameNetwork/GameSpy/BuddyDefs.h"
-#include "GameNetwork/GameSpy/GSConfig.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpy/PeerThread.h"
-#include "GameNetwork/GameSpy/PersistentStorageDefs.h"
-#include "GameNetwork/GameSpy/PersistentStorageThread.h"
-#include "GameNetwork/RankPointValue.h"
-#include "GameNetwork/GameSpy/LadderDefs.h"
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-
-#ifdef DEBUG_LOGGING
-#include "Common/MiniLog.h"
-//#define PERF_TEST
-static LogClass s_perfLog("QMPerf.txt");
-static Bool s_inQM = FALSE;
-#define PERF_LOG(x) s_perfLog.log x
-#else // DEBUG_LOGGING
-#define PERF_LOG(x) {}
-#endif // DEBUG_LOGGING
-
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-// window ids ------------------------------------------------------------------------------
-static NameKeyType parentWOLQuickMatchID = NAMEKEY_INVALID;
-static NameKeyType buttonBackID = NAMEKEY_INVALID;
-static NameKeyType buttonStartID = NAMEKEY_INVALID;
-static NameKeyType buttonStopID = NAMEKEY_INVALID;
-static NameKeyType buttonWidenID = NAMEKEY_INVALID;
-static NameKeyType buttonBuddiesID = NAMEKEY_INVALID;
-static NameKeyType listboxQuickMatchID = NAMEKEY_INVALID;
-static NameKeyType listboxMapSelectID = NAMEKEY_INVALID;
-static NameKeyType buttonSelectAllMapsID = NAMEKEY_INVALID;
-static NameKeyType buttonSelectNoMapsID = NAMEKEY_INVALID;
-//static NameKeyType textEntryMaxDisconnectsID = NAMEKEY_INVALID;
-//static NameKeyType textEntryMaxPointsID = NAMEKEY_INVALID;
-//static NameKeyType textEntryMinPointsID = NAMEKEY_INVALID;
-static NameKeyType textEntryWaitTimeID = NAMEKEY_INVALID;
-static NameKeyType comboBoxNumPlayersID = NAMEKEY_INVALID;
-static NameKeyType comboBoxMaxPingID = NAMEKEY_INVALID;
-static NameKeyType comboBoxLadderID = NAMEKEY_INVALID;
-static NameKeyType comboBoxMaxDisconnectsID = NAMEKEY_INVALID;
-static NameKeyType staticTextNumPlayersID = NAMEKEY_INVALID;
-static NameKeyType comboBoxSideID = NAMEKEY_INVALID;
-static NameKeyType comboBoxColorID = NAMEKEY_INVALID;
-
-
-// Window Pointers ------------------------------------------------------------------------
-static GameWindow *parentWOLQuickMatch = NULL;
-static GameWindow *buttonBack = NULL;
-static GameWindow *buttonStart = NULL;
-static GameWindow *buttonStop = NULL;
-static GameWindow *buttonWiden = NULL;
-GameWindow *quickmatchTextWindow = NULL;
-static GameWindow *listboxMapSelect = NULL;
-//static GameWindow *textEntryMaxDisconnects = NULL;
-//static GameWindow *textEntryMaxPoints = NULL;
-//static GameWindow *textEntryMinPoints = NULL;
-static GameWindow *textEntryWaitTime = NULL;
-static GameWindow *comboBoxNumPlayers = NULL;
-static GameWindow *comboBoxMaxPing = NULL;
-static GameWindow *comboBoxLadder = NULL;
-static GameWindow *comboBoxDisabledLadder = NULL; // enable and disable this, but never use it. it is a stand-in for comboBoxLadder for when there are no ladders
-static GameWindow *comboBoxMaxDisconnects = NULL;
-static GameWindow *staticTextNumPlayers = NULL;
-static GameWindow *comboBoxSide = NULL;
-static GameWindow *comboBoxColor = NULL;
-
-static Bool isShuttingDown = false;
-static Bool buttonPushed = false;
-static char *nextScreen = NULL;
-static Bool raiseMessageBoxes = false;
-static Bool isInInit = FALSE;
-static const Image *selectedImage = NULL;
-static const Image *unselectedImage = NULL;
-
-static bool isPopulatingLadderBox = false;
-static Int maxPingEntries = 0;
-static Int maxPoints= 100;
-static Int minPoints = 0;
-
-static const LadderInfo * getLadderInfo( void );
-
-
-// [SKB: Jul 01 2003 @ 7:7pm] :
-// German2 now has fewer maps. When trying to do a QM with a Retail version
-// the bool string sent to the QMBot is almost always a different size. This
-// mapping is kept so that we now send a string of all maps instead of just
-// the ones that are visible to the user.
-
-#define VARIABLE_NUMBER_OF_MAPS 1
-
-#if VARIABLE_NUMBER_OF_MAPS
-typedef std::vector MapListboxIndex;
-static MapListboxIndex mapListboxIndex;
-#endif
-
-
-static Bool isInfoShown(void)
-{
- static NameKeyType parentStatsID = NAMEKEY("WOLQuickMatchMenu.wnd:ParentStats");
- GameWindow *parentStats = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, parentStatsID );
- if (parentStats)
- return !parentStats->winIsHidden();
- return FALSE;
-}
-
-static void hideInfoGadgets(Bool doIt)
-{
- static NameKeyType parentStatsID = NAMEKEY("WOLQuickMatchMenu.wnd:ParentStats");
- GameWindow *parentStats = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, parentStatsID );
- if (parentStats)
- {
- parentStats->winHide(doIt);
- }
-}
-
-static void hideOptionsGadgets(Bool doIt)
-{
- static NameKeyType parentOptionsID = NAMEKEY("WOLQuickMatchMenu.wnd:ParentOptions");
- GameWindow *parentOptions = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, parentOptionsID );
- if (parentOptions)
- {
- parentOptions->winHide(doIt);
- if (comboBoxSide)
- comboBoxSide->winHide(doIt);
- if (comboBoxColor)
- comboBoxColor->winHide(doIt);
- if (comboBoxNumPlayers)
- comboBoxNumPlayers->winHide(doIt);
- if (comboBoxLadder)
- comboBoxLadder->winHide(doIt);
- if (comboBoxDisabledLadder)
- comboBoxDisabledLadder->winHide(doIt);
- if (comboBoxMaxPing)
- comboBoxMaxPing->winHide(doIt);
- if (comboBoxMaxDisconnects)
- comboBoxMaxDisconnects->winHide(doIt);
- }
-}
-
-static void enableOptionsGadgets(Bool doIt)
-{
-#ifdef PERF_TEST
- s_inQM = !doIt;
-#endif // PERF_TEST
- static NameKeyType parentOptionsID = NAMEKEY("WOLQuickMatchMenu.wnd:ParentOptions");
- GameWindow *parentOptions = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, parentOptionsID );
- const LadderInfo *li = getLadderInfo();
- if (parentOptions)
- {
- parentOptions->winEnable(doIt);
- if (comboBoxSide)
- comboBoxSide->winEnable(doIt && (!li || !li->randomFactions));
- if (comboBoxColor)
- comboBoxColor->winEnable(doIt);
- if (comboBoxNumPlayers)
- comboBoxNumPlayers->winEnable(doIt);
- if (comboBoxLadder)
- comboBoxLadder->winEnable(doIt);
- if (comboBoxDisabledLadder)
- comboBoxDisabledLadder->winEnable(FALSE);
- if (comboBoxMaxPing)
- comboBoxMaxPing->winEnable(doIt);
- if (comboBoxMaxDisconnects)
- comboBoxMaxDisconnects->winEnable(doIt);
- }
-}
-
-enum
-{
- MAX_DISCONNECTS_ANY = 0,
- MAX_DISCONNECTS_5 = 5,
- MAX_DISCONNECTS_10 = 10,
- MAX_DISCONNECTS_25 = 25,
- MAX_DISCONNECTS_50 = 50,
-};
-enum{ MAX_DISCONNECTS_COUNT = 5 };
-
-static Int MAX_DISCONNECTS[MAX_DISCONNECTS_COUNT] = {MAX_DISCONNECTS_ANY, MAX_DISCONNECTS_5,
- MAX_DISCONNECTS_10, MAX_DISCONNECTS_25,
- MAX_DISCONNECTS_50};
-
-
-void UpdateStartButton(void)
-{
- if (!comboBoxLadder || !buttonStart || !listboxMapSelect)
- return;
-
- Int index;
- Int selected;
- GadgetComboBoxGetSelectedPos( comboBoxLadder, &selected );
- index = (Int)GadgetComboBoxGetItemData( comboBoxLadder, selected );
- const LadderInfo *li = TheLadderList->findLadderByIndex( index );
- if (li)
- {
- buttonStart->winEnable(TRUE);
- return;
- }
-
- Int numMaps = GadgetListBoxGetNumEntries(listboxMapSelect);
- for ( Int i=0; iwinEnable(TRUE);
- return;
- }
- }
- buttonStart->winEnable(FALSE);
-}
-
-// -----------------------------------------------------------------------------
-
-static void populateQMColorComboBox(QuickMatchPreferences& pref)
-{
- Int numColors = TheMultiplayerSettings->getNumColors();
- UnicodeString colorName;
-
- GadgetComboBoxReset(comboBoxColor);
-
- MultiplayerColorDefinition *def = TheMultiplayerSettings->getColor(PLAYERTEMPLATE_RANDOM);
- Int newIndex = GadgetComboBoxAddEntry(comboBoxColor, TheGameText->fetch("GUI:???"), def->getColor());
- GadgetComboBoxSetItemData(comboBoxColor, newIndex, (void *)-1);
-
- for (Int c=0; cgetColor(c);
- if (!def)
- continue;
-
- colorName = TheGameText->fetch(def->getTooltipName().str());
- newIndex = GadgetComboBoxAddEntry(comboBoxColor, colorName, def->getColor());
- GadgetComboBoxSetItemData(comboBoxColor, newIndex, (void *)c);
- }
- GadgetComboBoxSetSelectedPos(comboBoxColor, pref.getColor());
-}
-
-// -----------------------------------------------------------------------------
-
-static void populateQMSideComboBox(Int favSide, const LadderInfo *li = NULL)
-{
- Int numPlayerTemplates = ThePlayerTemplateStore->getPlayerTemplateCount();
- UnicodeString playerTemplateName;
-
- GadgetComboBoxReset(comboBoxSide);
-
- MultiplayerColorDefinition *def = TheMultiplayerSettings->getColor(PLAYERTEMPLATE_RANDOM);
- Int newIndex = GadgetComboBoxAddEntry(comboBoxSide, TheGameText->fetch("GUI:Random"), def->getColor());
- GadgetComboBoxSetItemData(comboBoxSide, newIndex, (void *)PLAYERTEMPLATE_RANDOM);
-
- std::set seenSides;
-
- Int entryToSelect = 0; // select Random by default
-
- for (Int c=0; cgetNthPlayerTemplate(c);
- if (!fac)
- continue;
-
- if (fac->getStartingBuilding().isEmpty())
- continue;
-
- AsciiString side;
- side.format("SIDE:%s", fac->getSide().str());
- if (seenSides.find(side) != seenSides.end())
- continue;
-
- if (li)
- {
- if (std::find(li->validFactions.begin(), li->validFactions.end(), fac->getSide()) == li->validFactions.end())
- continue; // ladder doesn't allow it.
- }
-
- seenSides.insert(side);
-
- newIndex = GadgetComboBoxAddEntry(comboBoxSide, TheGameText->fetch(side), def->getColor());
- GadgetComboBoxSetItemData(comboBoxSide, newIndex, (void *)c);
-
- if (c == favSide)
- entryToSelect = newIndex;
- }
- seenSides.clear();
-
- GadgetComboBoxSetSelectedPos(comboBoxSide, entryToSelect);
- if (li && li->randomFactions)
- comboBoxSide->winEnable(FALSE);
- else
- comboBoxSide->winEnable(TRUE);
-}
-
-void HandleQMLadderSelection(Int ladderID)
-{
- if (!parentWOLQuickMatch)
- return;
-
- QuickMatchPreferences pref;
-
- if (ladderID < 1)
- {
- pref.setLastLadder(AsciiString::TheEmptyString, 0);
- pref.write();
- return;
- }
-
- const LadderInfo *info = TheLadderList->findLadderByIndex(ladderID);
- if (!info)
- {
- pref.setLastLadder(AsciiString::TheEmptyString, 0);
- }
- else
- {
- pref.setLastLadder(info->address, info->port);
- }
-
- pref.write();
-}
-
-static inline Bool isValidLadder( const LadderInfo *lad )
-{
- if (lad && lad->index > 0 && lad->validQM)
- {
- PSPlayerStats stats = TheGameSpyPSMessageQueue->findPlayerStatsByID(TheGameSpyInfo->getLocalProfileID());
- Int numWins = 0;
- PerGeneralMap::iterator it;
- for (it = stats.wins.begin(); it != stats.wins.end(); ++it)
- {
- numWins += it->second;
- }
- if (!lad->maxWins || lad->maxWins >=numWins)
- {
- if (!lad->minWins || lad->minWins<=numWins)
- {
- return TRUE;
- }
- }
- }
- return FALSE;
-}
-
-void PopulateQMLadderListBox( GameWindow *win )
-{
- if (!parentWOLQuickMatch || !comboBoxLadder)
- return;
-
- isPopulatingLadderBox = true;
-
- QuickMatchPreferences pref;
- AsciiString userPrefFilename;
- Int localProfile = TheGameSpyInfo->getLocalProfileID();
-
- Color specialColor = GameSpyColor[GSCOLOR_MAP_SELECTED];
- Color normalColor = GameSpyColor[GSCOLOR_MAP_UNSELECTED];
- Color favoriteColor = GameSpyColor[GSCOLOR_MAP_UNSELECTED];
- Int index;
- GadgetListBoxReset( win );
-
- std::set usedLadders;
-
- // start with "No Ladder"
- index = GadgetListBoxAddEntryText( win, TheGameText->fetch("GUI:NoLadder"), normalColor, -1 );
- GadgetListBoxSetItemData( win, 0, index );
-
- // add the last ladder
- Int selectedPos = 0;
- AsciiString lastLadderAddr = pref.getLastLadderAddr();
- UnsignedShort lastLadderPort = pref.getLastLadderPort();
- const LadderInfo *info = TheLadderList->findLadder( lastLadderAddr, lastLadderPort );
- if (isValidLadder(info))
- {
- usedLadders.insert(info);
- index = GadgetListBoxAddEntryText( win, info->name, favoriteColor, -1 );
- GadgetListBoxSetItemData( win, (void *)(info->index), index );
- selectedPos = index;
- }
-
- // our recent ladders
- LadderPreferences ladPref;
- ladPref.loadProfile( localProfile );
- const LadderPrefMap recentLadders = ladPref.getRecentLadders();
- for (LadderPrefMap::const_iterator cit = recentLadders.begin(); cit != recentLadders.end(); ++cit)
- {
- AsciiString addr = cit->second.address;
- UnsignedShort port = cit->second.port;
- if (addr == lastLadderAddr && port == lastLadderPort)
- continue;
- const LadderInfo *info = TheLadderList->findLadder( addr, port );
- if (isValidLadder(info) && usedLadders.find(info) == usedLadders.end())
- {
- usedLadders.insert(info);
- index = GadgetListBoxAddEntryText( win, info->name, favoriteColor, -1 );
- GadgetListBoxSetItemData( win, (void *)(info->index), index );
- }
- }
-
- // special ladders
- const LadderInfoList *lil = TheLadderList->getSpecialLadders();
- LadderInfoList::const_iterator lit;
- for (lit = lil->begin(); lit != lil->end(); ++lit)
- {
- const LadderInfo *info = *lit;
- if (isValidLadder(info) && usedLadders.find(info) == usedLadders.end())
- {
- usedLadders.insert(info);
- index = GadgetListBoxAddEntryText( win, info->name, specialColor, -1 );
- GadgetListBoxSetItemData( win, (void *)(info->index), index );
- }
- }
-
- // standard ladders
- lil = TheLadderList->getStandardLadders();
- for (lit = lil->begin(); lit != lil->end(); ++lit)
- {
- const LadderInfo *info = *lit;
- if (isValidLadder(info) && usedLadders.find(info) == usedLadders.end())
- {
- usedLadders.insert(info);
- index = GadgetListBoxAddEntryText( win, info->name, normalColor, -1 );
- GadgetListBoxSetItemData( win, (void *)(info->index), index );
- }
- }
-
- GadgetListBoxSetSelected( win, selectedPos );
- isPopulatingLadderBox = false;
-}
-
-static const LadderInfo * getLadderInfo( void )
-{
- Int index;
- Int selected;
- GadgetComboBoxGetSelectedPos( comboBoxLadder, &selected );
- index = (Int)GadgetComboBoxGetItemData( comboBoxLadder, selected );
- const LadderInfo *li = TheLadderList->findLadderByIndex( index );
- return li;
-}
-
-void PopulateQMLadderComboBox( void )
-{
- if (!parentWOLQuickMatch || !comboBoxLadder)
- return;
-
- isPopulatingLadderBox = true;
-
- QuickMatchPreferences pref;
- Int localProfile = TheGameSpyInfo->getLocalProfileID();
-
- Color specialColor = GameSpyColor[GSCOLOR_MAP_SELECTED];
- Color normalColor = GameSpyColor[GSCOLOR_MAP_UNSELECTED];
- Int index;
- GadgetComboBoxReset( comboBoxLadder );
- index = GadgetComboBoxAddEntry( comboBoxLadder, TheGameText->fetch("GUI:NoLadder"), normalColor );
- GadgetComboBoxSetItemData( comboBoxLadder, index, 0 );
-
- std::set usedLadders;
-
- Int selectedPos = 0;
- AsciiString lastLadderAddr = pref.getLastLadderAddr();
- UnsignedShort lastLadderPort = pref.getLastLadderPort();
- const LadderInfo *info = TheLadderList->findLadder( lastLadderAddr, lastLadderPort );
- if (isValidLadder(info))
- {
- usedLadders.insert(info);
- index = GadgetComboBoxAddEntry( comboBoxLadder, info->name, specialColor );
- GadgetComboBoxSetItemData( comboBoxLadder, index, (void *)(info->index) );
- selectedPos = index;
-
- // we selected a ladder? No game size choice for us...
- GadgetComboBoxSetSelectedPos(comboBoxNumPlayers, info->playersPerTeam-1);
- comboBoxNumPlayers->winEnable( FALSE );
- }
- else
- {
- comboBoxNumPlayers->winEnable( TRUE );
- }
-
- LadderPreferences ladPref;
- ladPref.loadProfile( localProfile );
- const LadderPrefMap recentLadders = ladPref.getRecentLadders();
- for (LadderPrefMap::const_iterator cit = recentLadders.begin(); cit != recentLadders.end(); ++cit)
- {
- AsciiString addr = cit->second.address;
- UnsignedShort port = cit->second.port;
- if (addr == lastLadderAddr && port == lastLadderPort)
- continue;
- const LadderInfo *info = TheLadderList->findLadder( addr, port );
- if (isValidLadder(info) && usedLadders.find(info) == usedLadders.end())
- {
- usedLadders.insert(info);
- index = GadgetComboBoxAddEntry( comboBoxLadder, info->name, normalColor );
- GadgetComboBoxSetItemData( comboBoxLadder, index, (void *)(info->index) );
- }
- }
-
- index = GadgetComboBoxAddEntry( comboBoxLadder, TheGameText->fetch("GUI:ChooseLadder"), normalColor );
- GadgetComboBoxSetItemData( comboBoxLadder, index, (void *)-1 );
-
- GadgetComboBoxSetSelectedPos( comboBoxLadder, selectedPos );
- isPopulatingLadderBox = false;
-
- populateQMSideComboBox(pref.getSide(), getLadderInfo()); // this will set side to random and disable if necessary
-}
-
-static void populateQuickMatchMapSelectListbox( QuickMatchPreferences& pref )
-{
- std::list maps = TheGameSpyConfig->getQMMaps();
-
- // enable/disable box based on ladder status
- Int index;
- Int selected;
- GadgetComboBoxGetSelectedPos( comboBoxLadder, &selected );
- index = (Int)GadgetComboBoxGetItemData( comboBoxLadder, selected );
- const LadderInfo *li = TheLadderList->findLadderByIndex( index );
- //listboxMapSelect->winEnable( li == NULL || li->randomMaps == FALSE );
-
- Int numPlayers = 0;
- if (li)
- {
- numPlayers = li->playersPerTeam*2;
-
- maps = li->validMaps;
- }
- else
- {
- GadgetComboBoxGetSelectedPos(comboBoxNumPlayers, &selected);
- if (selected < 0)
- selected = 0;
- numPlayers = (selected+1)*2;
- }
-
- #if VARIABLE_NUMBER_OF_MAPS
- mapListboxIndex.clear();
- #endif
-
- GadgetListBoxReset(listboxMapSelect);
- for (std::list::const_iterator it = maps.begin(); it != maps.end(); ++it)
- {
- AsciiString theMap = *it;
- const MapMetaData *md = TheMapCache->findMap(theMap);
- if (md && md->m_numPlayers >= numPlayers)
- {
- UnicodeString displayName;
- displayName = md->m_displayName;
- Bool isSelected = pref.isMapSelected(theMap);
- if (li && li->randomMaps)
- isSelected = TRUE;
- Int width = 10;
- Int height = 10;
- const Image *img = (isSelected)?selectedImage:unselectedImage;
- if ( img )
- {
- width = min(GadgetListBoxGetColumnWidth(listboxMapSelect, 0), img->getImageWidth());
- height = width;
- }
- Int index = GadgetListBoxAddEntryImage(listboxMapSelect, img, -1, 0, height, width);
- GadgetListBoxAddEntryText(listboxMapSelect, displayName, GameSpyColor[(isSelected)?GSCOLOR_MAP_SELECTED:GSCOLOR_MAP_UNSELECTED], index, 1);
- GadgetListBoxSetItemData(listboxMapSelect, (void *)isSelected, index);
- GadgetListBoxSetItemData(listboxMapSelect, (void *)md, index, 1);
-
- #if VARIABLE_NUMBER_OF_MAPS
- mapListboxIndex.push_back(index);
- #endif
- }
- else
- {
- #if VARIABLE_NUMBER_OF_MAPS
- // [SKB: Jul 01 2003 @ 7:9pm] :
- // Keep track of maps that are not visible right now so
- // they are added to the information sent to the QMBot.
- mapListboxIndex.push_back(-1);
- #endif
- }
- }
-}
-
-static void saveQuickMatchOptions( void )
-{
- if(isInInit)
- return;
- QuickMatchPreferences pref;
-
- std::list maps = TheGameSpyConfig->getQMMaps();
-
- Int index;
- Int selected;
- GadgetComboBoxGetSelectedPos( comboBoxLadder, &selected );
- index = (Int)GadgetComboBoxGetItemData( comboBoxLadder, selected );
- const LadderInfo *li = TheLadderList->findLadderByIndex( index );
- Int numPlayers = 0;
-
- if (li)
- {
- pref.setLastLadder( li->address, li->port );
- numPlayers = li->playersPerTeam*2;
-
- pref.write();
- //return; // don't save our defaults based on the tournament's defaults
- }
- else
- {
- pref.setLastLadder( AsciiString::TheEmptyString, 0 );
- GadgetComboBoxGetSelectedPos(comboBoxNumPlayers, &selected);
- if (selected < 0)
- selected = 0;
- numPlayers = (selected+1)*2;
- }
-
- if (!li || !li->randomMaps) // don't save the map as selected if we couldn't choose
- {
- Int row = 0;
- Int entries = GadgetListBoxGetNumEntries(listboxMapSelect);
- while ( row < entries)
- {
- const MapMetaData *md = (const MapMetaData *)GadgetListBoxGetItemData(listboxMapSelect, row, 1);
- if(md)
- pref.setMapSelected(md->m_fileName, (Bool)GadgetListBoxGetItemData(listboxMapSelect, row));
- row++;
- }
- }
-
- UnicodeString u;
- AsciiString a;
-// u = GadgetTextEntryGetText(textEntryMaxDisconnects);
-// a.translate(u);
-// pref.setMaxDisconnects(atoi(a.str()));
-// u = GadgetTextEntryGetText(textEntryMaxPoints);
-// a.translate(u);
-// pref.setMaxPoints(max(100, atoi(a.str())));
-// u = GadgetTextEntryGetText(textEntryMinPoints);
-// a.translate(u);
-// pref.setMinPoints(min(100, atoi(a.str())));
- //u = GadgetTextEntryGetText(textEntryWaitTime);
- //a.translate(u);
- //pref.setWaitTime(atoi(a.str()));
-
- GadgetComboBoxGetSelectedPos(comboBoxNumPlayers, &selected);
- pref.setNumPlayers(selected);
- GadgetComboBoxGetSelectedPos(comboBoxMaxPing, &selected);
- pref.setMaxPing(selected);
-
- Int item;
- GadgetComboBoxGetSelectedPos(comboBoxSide, &selected);
- item = (Int)GadgetComboBoxGetItemData(comboBoxSide, selected);
- pref.setSide(max(0, item));
- GadgetComboBoxGetSelectedPos(comboBoxColor, &selected);
- pref.setColor(max(0, selected));
-
- GadgetComboBoxGetSelectedPos(comboBoxMaxDisconnects, &selected);
- pref.setMaxDisconnects(selected);
-
-
- pref.write();
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the WOL Quick Match Menu */
-//-------------------------------------------------------------------------------------------------
-void WOLQuickMatchMenuInit( WindowLayout *layout, void *userData )
-{
- isInInit = TRUE;
- if (TheGameSpyGame && TheGameSpyGame->isGameInProgress())
- {
- TheGameSpyGame->setGameInProgress(FALSE);
-
- // check if we were disconnected
- Int disconReason;
- if (TheGameSpyInfo->isDisconnectedAfterGameStart(&disconReason))
- {
- AsciiString disconMunkee;
- disconMunkee.format("GUI:GSDisconReason%d", disconReason);
- UnicodeString title, body;
- title = TheGameText->fetch( "GUI:GSErrorTitle" );
- body = TheGameText->fetch( disconMunkee );
- GameSpyCloseAllOverlays();
- GSMessageBoxOk( title, body );
- TheGameSpyInfo->reset();
- DEBUG_LOG(("WOLQuickMatchMenuInit() - game was in progress, and we were disconnected, so pop immediate back to main menu\n"));
- TheShell->popImmediate();
- return;
- }
- }
-
- nextScreen = NULL;
- buttonPushed = false;
- isShuttingDown = false;
- raiseMessageBoxes = true;
-
- if (TheNAT != NULL) {
- delete TheNAT;
- TheNAT = NULL;
- }
-
- parentWOLQuickMatchID = NAMEKEY( "WOLQuickMatchMenu.wnd:WOLQuickMatchMenuParent" );
- buttonBackID = NAMEKEY( "WOLQuickMatchMenu.wnd:ButtonBack" );
- buttonBuddiesID = NAMEKEY( "WOLQuickMatchMenu.wnd:ButtonBuddies" );
- buttonStartID = NAMEKEY( "WOLQuickMatchMenu.wnd:ButtonStart" );
- buttonStopID = NAMEKEY( "WOLQuickMatchMenu.wnd:ButtonStop" );
- buttonWidenID = NAMEKEY( "WOLQuickMatchMenu.wnd:ButtonWiden" );
- listboxQuickMatchID = NAMEKEY( "WOLQuickMatchMenu.wnd:ListboxQuickMatch" );
- listboxMapSelectID = NAMEKEY( "WOLQuickMatchMenu.wnd:ListBoxMapSelect" );
- buttonSelectAllMapsID = NAMEKEY( "WOLQuickMatchMenu.wnd:ButtonSelectAllMaps" );
- buttonSelectNoMapsID = NAMEKEY( "WOLQuickMatchMenu.wnd:ButtonSelectNoMaps" );
- //textEntryMaxDisconnectsID = NAMEKEY( "WOLQuickMatchMenu.wnd:TextEntryMaxDisconnects" );
- //textEntryMaxPointsID = NAMEKEY( "WOLQuickMatchMenu.wnd:TextEntryMaxPointPercent" );
- //textEntryMinPointsID = NAMEKEY( "WOLQuickMatchMenu.wnd:TextEntryMinPointPercent" );
- textEntryWaitTimeID = NAMEKEY( "WOLQuickMatchMenu.wnd:TextEntryWaitTime" );
- comboBoxMaxPingID = NAMEKEY( "WOLQuickMatchMenu.wnd:ComboBoxMaxPing" );
- comboBoxNumPlayersID = NAMEKEY( "WOLQuickMatchMenu.wnd:ComboBoxNumPlayers" );
- comboBoxLadderID = NAMEKEY( "WOLQuickMatchMenu.wnd:ComboBoxLadder" );
- comboBoxMaxDisconnectsID = NAMEKEY( "WOLQuickMatchMenu.wnd:ComboBoxMaxDisconnects" );
- staticTextNumPlayersID = NAMEKEY( "WOLQuickMatchMenu.wnd:StaticTextNumPlayers" );
- comboBoxSideID = NAMEKEY( "WOLQuickMatchMenu.wnd:ComboBoxSide" );
- comboBoxColorID = NAMEKEY( "WOLQuickMatchMenu.wnd:ComboBoxColor" );
-
- parentWOLQuickMatch = TheWindowManager->winGetWindowFromId( NULL, parentWOLQuickMatchID );
- buttonBack = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, buttonBackID);
- buttonStart = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, buttonStartID);
- buttonStop = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, buttonStopID);
- buttonWiden = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, buttonWidenID);
- quickmatchTextWindow = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, listboxQuickMatchID);
- listboxMapSelect = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, listboxMapSelectID);
- //textEntryMaxDisconnects = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, textEntryMaxDisconnectsID );
- //textEntryMaxPoints = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, textEntryMaxPointsID );
- //textEntryMinPoints = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, textEntryMinPointsID );
- textEntryWaitTime = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, textEntryWaitTimeID );
- comboBoxMaxPing = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, comboBoxMaxPingID );
- comboBoxNumPlayers = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, comboBoxNumPlayersID );
- comboBoxLadder = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, comboBoxLadderID );
- comboBoxMaxDisconnects = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, comboBoxMaxDisconnectsID );
- TheGameSpyInfo->registerTextWindow(quickmatchTextWindow);
- staticTextNumPlayers = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, staticTextNumPlayersID );
- comboBoxSide = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, comboBoxSideID );
- comboBoxColor = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, comboBoxColorID );
-
- if (TheLadderList->getStandardLadders()->size() == 0
- && TheLadderList->getSpecialLadders()->size() == 0
- && TheLadderList->getLocalLadders()->size() == 0)
- {
- // no ladders, so just disable them
- comboBoxDisabledLadder = comboBoxLadder;
- comboBoxLadder = NULL;
-
- isPopulatingLadderBox = TRUE;
-
- Color normalColor = GameSpyColor[GSCOLOR_MAP_UNSELECTED];
- Int index;
- GadgetComboBoxReset( comboBoxDisabledLadder );
- index = GadgetComboBoxAddEntry( comboBoxDisabledLadder, TheGameText->fetch("GUI:NoLadder"), normalColor );
- GadgetComboBoxSetItemData( comboBoxDisabledLadder, index, 0 );
- GadgetComboBoxSetSelectedPos( comboBoxDisabledLadder, index );
-
- isPopulatingLadderBox = FALSE;
-
- /** This code would actually *hide* the combo box, but it doesn't look as good. Left here since someone will want to
- ** see it at some point. :P
- if (comboBoxLadder)
- {
- comboBoxLadder->winHide(TRUE);
- comboBoxLadder->winEnable(FALSE);
- }
- comboBoxLadder = NULL;
- GameWindow *staticTextLadder = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch,
- NAMEKEY("WOLQuickMatchMenu.wnd:StaticTextLadder") );
- if (staticTextLadder)
- staticTextLadder->winHide(TRUE);
- */
- }
-
- GameWindow *buttonBuddies = TheWindowManager->winGetWindowFromId(NULL, buttonBuddiesID);
- if (buttonBuddies)
- buttonBuddies->winEnable(TRUE);
-
- GameWindow *staticTextTitle = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch,
- NAMEKEY("WOLQuickMatchMenu.wnd:StaticTextTitle") );
- if (staticTextTitle)
- {
- UnicodeString tmp;
- tmp.format(TheGameText->fetch("GUI:QuickMatchTitle"), TheGameSpyInfo->getLocalName().str());
- GadgetStaticTextSetText(staticTextTitle, tmp);
- }
-
- // QM is not going yet, so disable the Widen Search button
- buttonWiden->winEnable( FALSE );
- buttonStop->winHide( TRUE );
- buttonStart->winHide( FALSE );
- GadgetListBoxReset(quickmatchTextWindow);
- enableOptionsGadgets(TRUE);
-
- // Show Menu
- layout->hide( FALSE );
-
- // Set Keyboard to Main Parent
- TheWindowManager->winSetFocus( parentWOLQuickMatch );
-
- // fill in preferences
- selectedImage = TheMappedImageCollection->findImageByName("CustomMatch_selected");
- unselectedImage = TheMappedImageCollection->findImageByName("CustomMatch_deselected");
- QuickMatchPreferences pref;
-
-
- UnicodeString s;
-// s.format(L"%d", pref.getMaxDisconnects());
-// GadgetTextEntrySetText(textEntryMaxDisconnects, s);
-// s.format(L"%d", pref.getMaxPoints());
-// GadgetTextEntrySetText(textEntryMaxPoints, s);
-// s.format(L"%d", pref.getMinPoints());
-// GadgetTextEntrySetText(textEntryMinPoints, s);
- //s.format(L"%d", pref.getWaitTime());
- //GadgetTextEntrySetText(textEntryWaitTime, s);
- maxPoints= pref.getMaxPoints();
- minPoints = pref.getMinPoints();
-
- Color c = GameSpyColor[GSCOLOR_DEFAULT];
- GadgetComboBoxReset( comboBoxNumPlayers );
- Int i;
- for (i=1; i<5; ++i)
- {
- s.format(TheGameText->fetch("GUI:PlayersVersusPlayers"), i, i);
- GadgetComboBoxAddEntry( comboBoxNumPlayers, s, c );
- }
- GadgetComboBoxSetSelectedPos( comboBoxNumPlayers, max(0, pref.getNumPlayers()) );
-
- GadgetComboBoxReset(comboBoxMaxDisconnects);
- GadgetComboBoxAddEntry( comboBoxMaxDisconnects, TheGameText->fetch("GUI:Any"), c);
- for( i = 1; i < MAX_DISCONNECTS_COUNT; ++i )
- {
- s.format(L"%d", MAX_DISCONNECTS[i]);
- GadgetComboBoxAddEntry( comboBoxMaxDisconnects, s, c );
- }
- Int maxDisconIndex = max(0, pref.getMaxDisconnects());
- GadgetComboBoxSetSelectedPos(comboBoxMaxDisconnects, maxDisconIndex);
-
- GadgetComboBoxReset( comboBoxMaxPing );
- maxPingEntries = (TheGameSpyConfig->getPingTimeoutInMs() - 1) / 100;
- maxPingEntries++; // need to add the entry for the actual timeout
- for (i=1; i fetch("GUI:TimeInMilliseconds"), i*100);
- GadgetComboBoxAddEntry( comboBoxMaxPing, s, c );
- }
- GadgetComboBoxAddEntry( comboBoxMaxPing, TheGameText->fetch("GUI:ANY"), c );
- i = pref.getMaxPing();
- if( i < 0 )
- i = 0;
- if( i >= maxPingEntries )
- i = maxPingEntries - 1;
- GadgetComboBoxSetSelectedPos( comboBoxMaxPing, i );
-
- populateQMColorComboBox(pref);
- populateQMSideComboBox(pref.getSide(), getLadderInfo());
-
- PopulateQMLadderComboBox();
- TheShell->showShellMap(TRUE);
- TheGameSpyGame->reset();
-
- GadgetListBoxReset(listboxMapSelect);
- populateQuickMatchMapSelectListbox(pref);
-
- UpdateLocalPlayerStats();
- UpdateStartButton();
- TheTransitionHandler->setGroup("WOLQuickMatchMenuFade");
- isInInit= FALSE;
-} // WOLQuickMatchMenuInit
-
-//-------------------------------------------------------------------------------------------------
-/** This is called when a shutdown is complete for this menu */
-//-------------------------------------------------------------------------------------------------
-static void shutdownComplete( WindowLayout *layout )
-{
-
- isShuttingDown = false;
-
- // hide the layout
- layout->hide( TRUE );
-
- // our shutdown is complete
- TheShell->shutdownComplete( layout, (nextScreen != NULL) );
-
- if (nextScreen != NULL)
- {
- TheShell->push(nextScreen);
- }
-
- nextScreen = NULL;
-
-} // end if
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Quick Match Menu shutdown method */
-//-------------------------------------------------------------------------------------------------
-void WOLQuickMatchMenuShutdown( WindowLayout *layout, void *userData )
-{
- TheGameSpyInfo->unregisterTextWindow(quickmatchTextWindow);
-
- if (!TheGameEngine->getQuitting())
- saveQuickMatchOptions();
-
- parentWOLQuickMatch = NULL;
- buttonBack = NULL;
- quickmatchTextWindow = NULL;
- selectedImage = unselectedImage = NULL;
-
- isShuttingDown = true;
-
- // if we are shutting down for an immediate pop, skip the animations
- Bool popImmediate = *(Bool *)userData;
- if( popImmediate )
- {
-
- shutdownComplete( layout );
- return;
-
- } //end if
-
- TheShell->reverseAnimatewindow();
- TheTransitionHandler->reverse("WOLQuickMatchMenuFade");
-
- RaiseGSMessageBox();
-} // WOLQuickMatchMenuShutdown
-
-
-#ifdef PERF_TEST
-static const char* getMessageString(Int t)
-{
- switch(t)
- {
- case PeerResponse::PEERRESPONSE_LOGIN:
- return "login";
- case PeerResponse::PEERRESPONSE_DISCONNECT:
- return "disconnect";
- case PeerResponse::PEERRESPONSE_MESSAGE:
- return "message";
- case PeerResponse::PEERRESPONSE_GROUPROOM:
- return "group room";
- case PeerResponse::PEERRESPONSE_STAGINGROOM:
- return "staging room";
- case PeerResponse::PEERRESPONSE_STAGINGROOMPLAYERINFO:
- return "staging room player info";
- case PeerResponse::PEERRESPONSE_JOINGROUPROOM:
- return "group room join";
- case PeerResponse::PEERRESPONSE_CREATESTAGINGROOM:
- return "staging room create";
- case PeerResponse::PEERRESPONSE_JOINSTAGINGROOM:
- return "staging room join";
- case PeerResponse::PEERRESPONSE_PLAYERJOIN:
- return "player join";
- case PeerResponse::PEERRESPONSE_PLAYERLEFT:
- return "player part";
- case PeerResponse::PEERRESPONSE_PLAYERCHANGEDNICK:
- return "player nick";
- case PeerResponse::PEERRESPONSE_PLAYERINFO:
- return "player info";
- case PeerResponse::PEERRESPONSE_PLAYERCHANGEDFLAGS:
- return "player flags";
- case PeerResponse::PEERRESPONSE_ROOMUTM:
- return "room UTM";
- case PeerResponse::PEERRESPONSE_PLAYERUTM:
- return "player UTM";
- case PeerResponse::PEERRESPONSE_QUICKMATCHSTATUS:
- return "QM status";
- case PeerResponse::PEERRESPONSE_GAMESTART:
- return "game start";
- case PeerResponse::PEERRESPONSE_FAILEDTOHOST:
- return "host failure";
- }
- return "unknown";
-}
-#endif // PERF_TEST
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Quick Match Menu update method */
-//-------------------------------------------------------------------------------------------------
-void WOLQuickMatchMenuUpdate( WindowLayout * layout, void *userData)
-{
- if (TheGameLogic->isInShellGame() && TheGameLogic->getFrame() == 1)
- {
- SignalUIInteraction(SHELL_SCRIPT_HOOK_GENERALS_ONLINE_ENTERED_FROM_GAME);
- }
-
- // We'll only be successful if we've requested to
- if(isShuttingDown && TheShell->isAnimFinished()&& TheTransitionHandler->isFinished())
- shutdownComplete(layout);
-
- if (raiseMessageBoxes)
- {
- RaiseGSMessageBox();
- raiseMessageBoxes = false;
- }
-
- /// @todo: MDC handle disconnects in-game the same way as Custom Match!
-
- if (TheShell->isAnimFinished() && !buttonPushed && TheGameSpyPeerMessageQueue)
- {
- HandleBuddyResponses();
- HandlePersistentStorageResponses();
-
- if (TheGameSpyGame && TheGameSpyGame->isGameInProgress())
- {
- if (TheGameSpyInfo->isDisconnectedAfterGameStart(NULL))
- {
- return; // already been disconnected, so don't worry.
- }
-
- Int allowedMessages = TheGameSpyInfo->getMaxMessagesPerUpdate();
- Bool sawImportantMessage = FALSE;
- PeerResponse resp;
- while (allowedMessages-- && !sawImportantMessage && TheGameSpyPeerMessageQueue->getResponse( resp ))
- {
- switch (resp.peerResponseType)
- {
- case PeerResponse::PEERRESPONSE_DISCONNECT:
- {
- sawImportantMessage = TRUE;
- AsciiString disconMunkee;
- disconMunkee.format("GUI:GSDisconReason%d", resp.discon.reason);
-
- // check for scorescreen
- NameKeyType listboxChatWindowScoreScreenID = NAMEKEY("ScoreScreen.wnd:ListboxChatWindowScoreScreen");
- GameWindow *listboxChatWindowScoreScreen = TheWindowManager->winGetWindowFromId( NULL, listboxChatWindowScoreScreenID );
- if (listboxChatWindowScoreScreen)
- {
- GadgetListBoxAddEntryText(listboxChatWindowScoreScreen, TheGameText->fetch(disconMunkee),
- GameSpyColor[GSCOLOR_DEFAULT], -1);
- }
- else
- {
- // still ingame
- TheInGameUI->message(disconMunkee);
- }
- TheGameSpyInfo->markAsDisconnectedAfterGameStart(resp.discon.reason);
- }
- }
- }
-
- return; // if we're in game, all we care about is if we've been disconnected from the chat server
- }
-
- if (TheNAT != NULL) {
- NATStateType NATState = TheNAT->update();
- if (NATState == NATSTATE_DONE)
- {
- TheGameSpyGame->launchGame();
- if (TheGameSpyInfo) // this can be blown away by a disconnect on the map transfer screen
- TheGameSpyInfo->leaveStagingRoom();
- return; // don't do any more processing this frame, in case the screen goes away
- }
- else if (NATState == NATSTATE_FAILED)
- {
- // delete TheNAT, its no good for us anymore.
- delete TheNAT;
- TheNAT = NULL;
-
- // Just back out. This cleans up some slot list problems
- buttonPushed = true;
- GSMessageBoxOk(TheGameText->fetch("GUI:Error"), TheGameText->fetch("GUI:NATNegotiationFailed"));
- nextScreen = "Menus/WOLWelcomeMenu.wnd";
- TheShell->pop();
- return; // don't do any more processing this frame, in case the screen goes away
- }
- }
-
-#ifdef PERF_TEST
- UnsignedInt start = timeGetTime();
- UnsignedInt end = timeGetTime();
- std::list responses;
- Int numMessages = 0;
-#endif // PERF_TEST
-
- Int allowedMessages = TheGameSpyInfo->getMaxMessagesPerUpdate();
- Bool sawImportantMessage = FALSE;
- PeerResponse resp;
- while (allowedMessages-- && !sawImportantMessage && TheGameSpyPeerMessageQueue->getResponse( resp ))
- {
-#ifdef PERF_TEST
- ++numMessages;
- responses.push_back(resp.peerResponseType);
-#endif // PERF_TEST
- switch (resp.peerResponseType)
- {
- case PeerResponse::PEERRESPONSE_PLAYERUTM:
- {
- if (!stricmp(resp.command.c_str(), "STATS"))
- {
- DEBUG_LOG(("Saw STATS from %s, data was '%s'\n", resp.nick.c_str(), resp.commandOptions.c_str()));
- AsciiString data = resp.commandOptions.c_str();
- AsciiString idStr;
- data.nextToken(&idStr, " ");
- Int id = atoi(idStr.str());
- DEBUG_LOG(("data: %d(%s) - '%s'\n", id, idStr.str(), data.str()));
-
- PSPlayerStats stats = TheGameSpyPSMessageQueue->parsePlayerKVPairs(data.str());
- PSPlayerStats oldStats = TheGameSpyPSMessageQueue->findPlayerStatsByID(id);
- stats.id = id;
- DEBUG_LOG(("Parsed ID is %d, old ID is %d\n", stats.id, oldStats.id));
- if (stats.id && (oldStats.id == 0))
- TheGameSpyPSMessageQueue->trackPlayerStats(stats);
-
- // now fill in the profileID in the game slot
- AsciiString nick = resp.nick.c_str();
- for (Int i=0; igetGameSpySlot(i);
- if (slot && slot->isHuman() && (slot->getLoginName().compareNoCase(nick) == 0))
- {
- slot->setProfileID(id);
- break;
- }
- }
- }
- Int slotNum = TheGameSpyGame->getSlotNum(resp.nick.c_str());
- if ((slotNum >= 0) && (slotNum < MAX_SLOTS) && (!stricmp(resp.command.c_str(), "NAT"))) {
- // this is a command for NAT negotiations, pass if off to TheNAT
- sawImportantMessage = TRUE;
- if (TheNAT != NULL) {
- TheNAT->processGlobalMessage(slotNum, resp.commandOptions.c_str());
- }
- }
- /*
- else if (key == "NAT")
- {
- if ((val >= FirewallHelperClass::FIREWALL_TYPE_SIMPLE) &&
- (val <= FirewallHelperClass::FIREWALL_TYPE_DESTINATION_PORT_DELTA))
- {
- slot->setNATBehavior((FirewallHelperClass::FirewallBehaviorType)val);
- DEBUG_LOG(("Setting NAT behavior to %d for player %d\n", val, slotNum));
- change = true;
- }
- else
- {
- DEBUG_LOG(("Rejecting invalid NAT behavior %d from player %d\n", val, slotNum));
- }
- }
- */
- }
- break;
-
- case PeerResponse::PEERRESPONSE_DISCONNECT:
- {
- sawImportantMessage = TRUE;
- UnicodeString title, body;
- AsciiString disconMunkee;
- disconMunkee.format("GUI:GSDisconReason%d", resp.discon.reason);
- title = TheGameText->fetch( "GUI:GSErrorTitle" );
- body = TheGameText->fetch( disconMunkee );
- GameSpyCloseAllOverlays();
- GSMessageBoxOk( title, body );
- TheGameSpyInfo->reset();
- TheShell->pop();
- }
- case PeerResponse::PEERRESPONSE_QUICKMATCHSTATUS:
- {
- sawImportantMessage = TRUE;
- switch( resp.qmStatus.status )
- {
- case QM_IDLE:
- //TheGameSpyInfo->addText(UnicodeString(L"Status: QM_IDLE"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- break;
- case QM_JOININGQMCHANNEL:
- TheGameSpyInfo->addText(TheGameText->fetch("QM:JOININGQMCHANNEL"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- break;
- case QM_LOOKINGFORBOT:
- TheGameSpyInfo->addText(TheGameText->fetch("QM:LOOKINGFORBOT"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- break;
- case QM_SENTINFO:
- TheGameSpyInfo->addText(TheGameText->fetch("QM:SENTINFO"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- break;
- case QM_WORKING:
- {
- UnicodeString s;
- s.format(TheGameText->fetch("QM:WORKING"), resp.qmStatus.poolSize);
- TheGameSpyInfo->addText(s, GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- }
- buttonWiden->winEnable( TRUE );
- break;
- case QM_POOLSIZE:
- {
- UnicodeString s;
- s.format(TheGameText->fetch("QM:POOLSIZE"), resp.qmStatus.poolSize);
- TheGameSpyInfo->addText(s, GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- }
- break;
- case QM_WIDENINGSEARCH:
- TheGameSpyInfo->addText(TheGameText->fetch("QM:WIDENINGSEARCH"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- buttonWiden->winEnable( FALSE );
- break;
- case QM_MATCHED:
- {
- TheGameSpyInfo->addText(TheGameText->fetch("QM:MATCHED"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- buttonWiden->winEnable( FALSE );
-
- TheGameSpyGame->enterGame();
- TheGameSpyGame->setSeed(resp.qmStatus.seed);
-
- TheGameSpyGame->markGameAsQM();
-
- const LadderInfo *info = getLadderInfo();
- if (!info)
- {
- TheGameSpyGame->setLadderIP("localhost");
- TheGameSpyGame->setLadderPort(0);
- }
- else
- {
- TheGameSpyGame->setLadderIP(info->address);
- TheGameSpyGame->setLadderPort(info->port);
- }
-
- Int i;
- Int numPlayers = 0;
- for (i=0; i maps = TheGameSpyConfig->getQMMaps();
-
- #if VARIABLE_NUMBER_OF_MAPS
- std::list::const_iterator it = maps.begin();
- std::advance(it, resp.qmStatus.mapIdx);
-
- AsciiString theMap = *it;
- theMap.toLower();
- TheGameSpyGame->setMap(theMap);
-
- #else
- for (std::list::const_iterator it = maps.begin(); it != maps.end(); ++it)
- {
- AsciiString theMap = *it;
- theMap.toLower();
- const MapMetaData *md = TheMapCache->findMap(theMap);
-
- if (md && md->m_numPlayers >= numPlayers)
- {
- TheGameSpyGame->setMap(*it);
- if (resp.qmStatus.mapIdx-- == 0)
- break;
- }
- }
- #endif
-
- Int numPlayersPerTeam = numPlayers/2;
- DEBUG_ASSERTCRASH(numPlayersPerTeam, ("0 players per team???"));
- if (!numPlayersPerTeam)
- numPlayersPerTeam = 1;
-
- for (i=0; igetGameSpySlot(i);
- if (resp.stagingRoomPlayerNames[i].empty())
- {
- slot->setState(SLOT_CLOSED);
- }
- else
- {
- AsciiString aName = resp.stagingRoomPlayerNames[i].c_str();
- UnicodeString uName;
- uName.translate(aName);
- slot->setState(SLOT_PLAYER, uName, resp.qmStatus.IP[i]);
- slot->setColor(resp.qmStatus.color[i]);
- slot->setPlayerTemplate(resp.qmStatus.side[i]);
- //slot->setProfileID(0);
- slot->setNATBehavior((FirewallHelperClass::FirewallBehaviorType)resp.qmStatus.nat[i]);
- slot->setLocale("");
- slot->setTeamNumber( i/numPlayersPerTeam );
- if (i==0)
- TheGameSpyGame->setGameName(uName);
- }
- }
-
- DEBUG_LOG(("Starting a QM game: options=[%s]\n", GameInfoToAsciiString(TheGameSpyGame).str()));
- SendStatsToOtherPlayers(TheGameSpyGame);
- TheGameSpyGame->startGame(0);
- GameWindow *buttonBuddies = TheWindowManager->winGetWindowFromId(NULL, buttonBuddiesID);
- if (buttonBuddies)
- buttonBuddies->winEnable(FALSE);
- GameSpyCloseOverlay(GSOVERLAY_BUDDY);
- }
- break;
- case QM_INCHANNEL:
- TheGameSpyInfo->addText(TheGameText->fetch("QM:INCHANNEL"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- break;
- case QM_NEGOTIATINGFIREWALLS:
- TheGameSpyInfo->addText(TheGameText->fetch("QM:NEGOTIATINGFIREWALLS"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- break;
- case QM_STARTINGGAME:
- TheGameSpyInfo->addText(TheGameText->fetch("QM:STARTINGGAME"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- break;
- case QM_COULDNOTFINDBOT:
- TheGameSpyInfo->addText(TheGameText->fetch("QM:COULDNOTFINDBOT"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- buttonWiden->winEnable( FALSE );
- buttonStart->winHide( FALSE );
- buttonStop->winHide( TRUE );
- enableOptionsGadgets(TRUE);
- break;
- case QM_COULDNOTFINDCHANNEL:
- TheGameSpyInfo->addText(TheGameText->fetch("QM:COULDNOTFINDCHANNEL"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- buttonWiden->winEnable( FALSE );
- buttonStart->winHide( FALSE );
- buttonStop->winHide( TRUE );
- enableOptionsGadgets(TRUE);
- break;
- case QM_COULDNOTNEGOTIATEFIREWALLS:
- TheGameSpyInfo->addText(TheGameText->fetch("QM:COULDNOTNEGOTIATEFIREWALLS"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- buttonWiden->winEnable( FALSE );
- buttonStart->winHide( FALSE );
- buttonStop->winHide( TRUE );
- enableOptionsGadgets(TRUE);
- break;
- case QM_STOPPED:
- TheGameSpyInfo->addText(TheGameText->fetch("QM:STOPPED"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- buttonWiden->winEnable( FALSE );
- buttonStart->winHide( FALSE );
- buttonStop->winHide( TRUE );
- enableOptionsGadgets(TRUE);
- break;
- }
- }
- break;
- }
- }
-#ifdef PERF_TEST
- // check performance
- end = timeGetTime();
- UnsignedInt frameTime = end-start;
- if (frameTime > 100 || responses.size() > 20)
- {
- UnicodeString munkee;
- munkee.format(L"inQM:%d %d ms, %d messages", s_inQM, frameTime, responses.size());
- TheGameSpyInfo->addText(munkee, GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- PERF_LOG(("%ls\n", munkee.str()));
-
- std::list::const_iterator it;
- for (it = responses.begin(); it != responses.end(); ++it)
- {
- PERF_LOG((" %s\n", getMessageString(*it)));
- }
- }
-#endif // PERF_TEST
- }
-}// WOLQuickMatchMenuUpdate
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Quick Match Menu input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLQuickMatchMenuInput( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
- UnsignedByte key = mData1;
- UnsignedByte state = mData2;
- if (buttonPushed)
- break;
-
- switch( key )
- {
-
- // ----------------------------------------------------------------------------------------
- case KEY_ESC:
- {
-
- //
- // send a simulated selected event to the parent window of the
- // back/exit button
- //
- if( BitTest( state, KEY_STATE_UP ) )
- {
- if(!buttonBack->winIsHidden())
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)buttonBack, buttonBackID );
-
- } // end if
-
- // don't let key fall through anywhere else
- return MSG_HANDLED;
-
- } // end escape
-
- } // end switch( key )
-
- } // end char
-
- } // end switch( msg )
-
- return MSG_IGNORED;
-}// WOLQuickMatchMenuInput
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Quick Match Menu window system callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLQuickMatchMenuSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- UnicodeString txtInput;
-
- switch( msg )
- {
-
-
- case GWM_CREATE:
- {
-
- break;
- } // case GWM_DESTROY:
-
- case GWM_DESTROY:
- {
- break;
- } // case GWM_DESTROY:
-
- case GWM_INPUT_FOCUS:
- {
- // if we're givin the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
-
- return MSG_HANDLED;
- }//case GWM_INPUT_FOCUS:
-
- case GCM_SELECTED:
- {
- if (buttonPushed)
- break;
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- Int pos = -1;
- GadgetComboBoxGetSelectedPos(control, &pos);
-
- saveQuickMatchOptions();
- if (controlID == comboBoxLadderID && !isPopulatingLadderBox)
- {
- if (pos >= 0)
- {
- QuickMatchPreferences pref;
- Int ladderID = (Int)GadgetComboBoxGetItemData(control, pos);
- if (ladderID == 0)
- {
- // no ladder selected - enable buttons
- GadgetComboBoxSetSelectedPos(comboBoxNumPlayers, max(0, pref.getNumPlayers()/2-1));
- comboBoxNumPlayers->winEnable( TRUE );
- populateQMSideComboBox(pref.getSide()); // this will set side to random and disable if necessary
- }
- else if (ladderID > 0)
- {
- // ladder selected - disable buttons
- const LadderInfo *li = TheLadderList->findLadderByIndex(ladderID);
- if (li)
- GadgetComboBoxSetSelectedPos(comboBoxNumPlayers, li->playersPerTeam-1);
- else
- GadgetComboBoxSetSelectedPos(comboBoxNumPlayers, 0);
- comboBoxNumPlayers->winEnable( FALSE );
-
- populateQMSideComboBox(pref.getSide(), li); // this will set side to random and disable if necessary
- }
- else
- {
- // "Choose a ladder" selected - open overlay
- PopulateQMLadderComboBox(); // this restores the non-"Choose a ladder" selection
- GameSpyOpenOverlay( GSOVERLAY_LADDERSELECT );
- }
- }
- }
- if (!isInInit)
- {
- QuickMatchPreferences pref;
- populateQuickMatchMapSelectListbox(pref);
- UpdateStartButton();
- }
- break;
- } // case GCM_SELECTED
-
- case GBM_SELECTED:
- {
- if (buttonPushed)
- break;
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- static NameKeyType buttonOptionsID = NAMEKEY("WOLQuickMatchMenu.wnd:ButtonOptions");
-
- if ( controlID == buttonStopID )
- {
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_STOPQUICKMATCH;
- TheGameSpyPeerMessageQueue->addRequest(req);
- buttonWiden->winEnable( FALSE );
- buttonStart->winHide( FALSE );
- buttonStop->winHide( TRUE );
- enableOptionsGadgets(TRUE);
- TheGameSpyInfo->addText(TheGameText->fetch("GUI:QMAborted"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- }
- else if ( controlID == buttonOptionsID )
- {
- GameWindow *win =TheWindowManager->winGetWindowFromId(parentWOLQuickMatch,buttonOptionsID);
- if (isInfoShown())
- {
- hideInfoGadgets(TRUE);
- hideOptionsGadgets(FALSE);
- GadgetButtonSetText(win, TheGameText->fetch("GUI:PlayerInfo"));
- }
- else
- {
- hideInfoGadgets(FALSE);
- hideOptionsGadgets(TRUE);
- GadgetButtonSetText(win, TheGameText->fetch("GUI:Setup"));
- }
- }
- else if ( controlID == buttonWidenID )
- {
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_WIDENQUICKMATCHSEARCH;
- TheGameSpyPeerMessageQueue->addRequest(req);
- buttonWiden->winEnable( FALSE );
- }
- else if ( controlID == buttonStartID )
- {
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_STARTQUICKMATCH;
- req.qmMaps.clear();
-
- #if VARIABLE_NUMBER_OF_MAPS
- for (MapListboxIndex::iterator idxIt = mapListboxIndex.begin(); idxIt != mapListboxIndex.end(); ++idxIt) {
- Int index = (*idxIt);
- if (index >= 0)
- {
- req.qmMaps.push_back(GadgetListBoxGetItemData(listboxMapSelect, index, 0));
- }
- else
- {
- req.qmMaps.push_back(false);
- }
- }
- #else
- Int numMaps = GadgetListBoxGetNumEntries(listboxMapSelect);
- for ( Int i=0; i= maxPingEntries - 1)
- {
- req.QM.maxPing = TheGameSpyConfig->getPingTimeoutInMs();
- }
- else
- req.QM.maxPing = (val+1)*100;
-
- PSPlayerStats stats = TheGameSpyPSMessageQueue->findPlayerStatsByID(TheGameSpyInfo->getLocalProfileID());
- req.QM.points = CalculateRank(stats);
-
- Int ladderIndex, index, selected;
- GadgetComboBoxGetSelectedPos( comboBoxLadder, &selected );
- ladderIndex = (Int)GadgetComboBoxGetItemData( comboBoxLadder, selected );
- const LadderInfo *ladderInfo = NULL;
- if (ladderIndex < 0)
- {
- ladderIndex = 0;
- }
- if (ladderIndex)
- {
- ladderInfo = TheLadderList->findLadderByIndex( ladderIndex );
- if (!ladderInfo)
- {
- ladderIndex = 0; // sanity
- }
- }
- req.QM.ladderID = ladderIndex;
-
- req.QM.ladderPassCRC = 0;
-
- index = -1;
- GadgetComboBoxGetSelectedPos( comboBoxSide, &selected );
- if (selected >= 0)
- index = (Int)GadgetComboBoxGetItemData( comboBoxSide, selected );
- req.QM.side = index;
- if (ladderInfo && ladderInfo->randomFactions)
- {
- Int sideNum = GameClientRandomValue(0, ladderInfo->validFactions.size()-1);
- DEBUG_LOG(("Looking for %d out of %d random sides\n", sideNum, ladderInfo->validFactions.size()));
- AsciiStringListConstIterator cit = ladderInfo->validFactions.begin();
- while (sideNum)
- {
- ++cit;
- --sideNum;
- }
- if (cit != ladderInfo->validFactions.end())
- {
- Int numPlayerTemplates = ThePlayerTemplateStore->getPlayerTemplateCount();
- AsciiString sideStr = *cit;
- DEBUG_LOG(("Chose %s as our side... finding\n", sideStr.str()));
- for (Int c=0; cgetNthPlayerTemplate(c);
- if (fac && fac->getSide() == sideStr)
- {
- DEBUG_LOG(("Found %s in index %d\n", sideStr.str(), c));
- req.QM.side = c;
- break;
- }
- }
- }
- }
-
- index = -1;
- GadgetComboBoxGetSelectedPos( comboBoxColor, &selected );
- if (selected >= 0)
- index = (Int)GadgetComboBoxGetItemData( comboBoxColor, selected );
- req.QM.color = index;
-
- OptionPreferences natPref;
- req.QM.NAT = natPref.getFirewallBehavior();
-
- if (ladderIndex)
- {
- req.QM.numPlayers = (ladderInfo)?ladderInfo->playersPerTeam*2 : 2;
- }
- else
- {
- GadgetComboBoxGetSelectedPos(comboBoxNumPlayers, &val);
- if (val < 0)
- val = 0;
- req.QM.numPlayers = (val+1)*2;
- }
-
- Int numDiscons = 0;
- PerGeneralMap::iterator it;
- for(it =stats.discons.begin(); it != stats.discons.end(); ++it)
- {
- numDiscons += it->second;
- }
- for(it =stats.desyncs.begin(); it != stats.desyncs.end(); ++it)
- {
- numDiscons += it->second;
- }
- req.QM.discons = numDiscons;
-
-
- strncpy(req.QM.pings, TheGameSpyInfo->getPingString().str(), 17);
- req.QM.pings[16] = 0;
-
- req.QM.botID = TheGameSpyConfig->getQMBotID();
- req.QM.roomID = TheGameSpyConfig->getQMChannel();
-
- req.QM.exeCRC = TheGlobalData->m_exeCRC;
- req.QM.iniCRC = TheGlobalData->m_iniCRC;
-
- TheGameSpyPeerMessageQueue->addRequest(req);
- buttonWiden->winEnable( FALSE );
- buttonStart->winHide( TRUE );
- buttonStop->winHide( FALSE );
- enableOptionsGadgets(FALSE);
-
- if (ladderIndex > 0)
- {
- // save the ladder as being played upon even if we cancel out of matching early...
- LadderPreferences ladPref;
- ladPref.loadProfile( TheGameSpyInfo->getLocalProfileID() );
- LadderPref p;
- p.lastPlayDate = time(NULL);
- p.address = ladderInfo->address;
- p.port = ladderInfo->port;
- p.name = ladderInfo->name;
- ladPref.addRecentLadder( p );
- ladPref.write();
- }
- }
- else if ( controlID == buttonBuddiesID )
- {
- GameSpyToggleOverlay( GSOVERLAY_BUDDY );
- }
- else if ( controlID == buttonBackID )
- {
- buttonPushed = true;
- TheGameSpyInfo->leaveGroupRoom();
- nextScreen = "Menus/WOLWelcomeMenu.wnd";
- TheShell->pop();
- } //if ( controlID == buttonBack )
- else if ( controlID == buttonSelectAllMapsID )
- {
- Int numMaps = GadgetListBoxGetNumEntries(listboxMapSelect);
- for ( Int i=0; iwinGetWindowId();
- Int selected = (Int)mData2;
-
- if ( controlID == listboxMapSelectID )
- {
- const LadderInfo *li = getLadderInfo();
- if (selected >= 0 && (!li || !li->randomMaps))
- {
- Bool wasSelected = (Bool)GadgetListBoxGetItemData(control, selected, 0);
- GadgetListBoxSetItemData(control, (void *)(!wasSelected), selected, 0);
- Int width = 10;
- Int height = 10;
- const Image *img = (!wasSelected)?selectedImage:unselectedImage;
- if ( img )
- {
- width = min(GadgetListBoxGetColumnWidth(control, 0), img->getImageWidth());
- height = width;
- }
- GadgetListBoxAddEntryImage(control, img, selected, 0, height, width);
- GadgetListBoxAddEntryText(control, GadgetListBoxGetText(control, selected, 1), GameSpyColor[(wasSelected)?GSCOLOR_MAP_UNSELECTED:GSCOLOR_MAP_SELECTED], selected, 1);
- }
- if (selected >= 0)
- GadgetListBoxSetSelected(control, -1);
- }
- UpdateStartButton();
- break;
- }// case GLM_SELECTED
-
- case GEM_EDIT_DONE:
- {
- break;
- }
- default:
- return MSG_IGNORED;
-
- }//Switch
-
- return MSG_HANDLED;
-}// WOLQuickMatchMenuSystem
diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLStatusMenu.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLStatusMenu.cpp
deleted file mode 100644
index 87f13e7dcf1..00000000000
--- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLStatusMenu.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////////////
-// FILE: WOLLoginMenu.cpp
-// Author: Chris Huybregts, November 2001
-// Description: Lan Lobby Menu
-///////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/GameEngine.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/Shell.h"
-#include "GameClient/KeyDefs.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/GadgetListBox.h"
-#include "GameClient/GadgetTextEntry.h"
-//#include "GameNetwork/WOL.h"
-//#include "GameNetwork/WOLmenus.h"
-
-
-
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-// window ids ------------------------------------------------------------------------------
-static NameKeyType parentWOLStatusID = NAMEKEY_INVALID;
-static NameKeyType buttonDisconnectID = NAMEKEY_INVALID;
-
-// Window Pointers ------------------------------------------------------------------------
-static GameWindow *parentWOLStatus = NULL;
-static GameWindow *buttonDisconnect = NULL;
-GameWindow *progressTextWindow = NULL;
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the WOL Status Menu */
-//-------------------------------------------------------------------------------------------------
-void WOLStatusMenuInit( WindowLayout *layout, void *userData )
-{
- parentWOLStatusID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLStatusMenu.wnd:WOLStatusMenuParent" ) );
- buttonDisconnectID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLStatusMenu.wnd:ButtonDisconnect" ) );
- parentWOLStatus = TheWindowManager->winGetWindowFromId( NULL, parentWOLStatusID );
- buttonDisconnect = TheWindowManager->winGetWindowFromId( NULL, buttonDisconnectID);
-
- progressTextWindow = TheWindowManager->winGetWindowFromId( NULL,
- TheNameKeyGenerator->nameToKey( AsciiString( "WOLStatusMenu.wnd:ListboxStatus" ) ) );
-
- // Show Menu
- layout->hide( FALSE );
-
- // Set Keyboard to Main Parent
- TheWindowManager->winSetFocus( parentWOLStatus );
-
- //progressLayout = TheShell->top();
-
- //WOL::raiseWOLMessageBox();
-} // WOLStatusMenuInit
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Status Menu shutdown method */
-//-------------------------------------------------------------------------------------------------
-void WOLStatusMenuShutdown( WindowLayout *layout, void *userData )
-{
-
- // hide menu
- layout->hide( TRUE );
-
- // our shutdown is complete
- TheShell->shutdownComplete( layout );
-
- //progressLayout = NULL;
-
- //WOL::raiseWOLMessageBox();
-} // WOLStatusMenuShutdown
-
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Status Menu update method */
-//-------------------------------------------------------------------------------------------------
-void WOLStatusMenuUpdate( WindowLayout * layout, void *userData)
-{
- //if (WOL::TheWOL)
- //WOL::TheWOL->update();
-}// WOLStatusMenuUpdate
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Status Menu input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLStatusMenuInput( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
- UnsignedByte key = mData1;
- UnsignedByte state = mData2;
-
- switch( key )
- {
-
- // ----------------------------------------------------------------------------------------
- case KEY_ESC:
- {
-
- //
- // send a simulated selected event to the parent window of the
- // back/exit button
- //
- if( BitTest( state, KEY_STATE_UP ) )
- {
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)buttonDisconnect, buttonDisconnectID );
-
- } // end if
-
- // don't let key fall through anywhere else
- return MSG_HANDLED;
-
- } // end escape
-
- } // end switch( key )
-
- } // end char
-
- } // end switch( msg )
-
- return MSG_IGNORED;
-}// WOLStatusMenuInput
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Status Menu window system callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLStatusMenuSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- UnicodeString txtInput;
-
- switch( msg )
- {
-
-
- case GWM_CREATE:
- {
-
- break;
- } // case GWM_DESTROY:
-
- case GWM_DESTROY:
- {
- break;
- } // case GWM_DESTROY:
-
- case GWM_INPUT_FOCUS:
- {
- // if we're givin the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
-
- return MSG_HANDLED;
- }//case GWM_INPUT_FOCUS:
-
- case GBM_SELECTED:
- {
- /*
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if ( controlID == buttonDisconnectID )
- {
- //TheShell->pop();
- if (WOL::TheWOL->setState( WOL::WOLAPI_FATAL_ERROR ))
- {
- WOL::TheWOL->addCommand( WOL::WOLCOMMAND_RESET ); // don't display an error, log out, or anything
- }
-
- } //if ( controlID == buttonDisconnect )
- */
- break;
- }// case GBM_SELECTED:
-
- case GEM_EDIT_DONE:
- {
- break;
- }
- default:
- return MSG_IGNORED;
-
- }//Switch
-
- return MSG_HANDLED;
-}// WOLStatusMenuSystem
diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLWelcomeMenu.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLWelcomeMenu.cpp
deleted file mode 100644
index 9721fee7a36..00000000000
--- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLWelcomeMenu.cpp
+++ /dev/null
@@ -1,893 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////////////
-// FILE: WOLWelcomeMenu.cpp
-// Author: Chris Huybregts, November 2001
-// Description: Lan Lobby Menu
-///////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "GameSpy/peer/peer.h"
-
-#include "Common/GameEngine.h"
-#include "Common/GameSpyMiscPreferences.h"
-#include "Common/CustomMatchPreferences.h"
-#include "Common/GlobalData.h"
-#include "Common/UserPreferences.h"
-
-#include "GameClient/AnimateWindowManager.h"
-#include "GameClient/Display.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/GameText.h"
-#include "GameClient/Shell.h"
-#include "GameClient/KeyDefs.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/GadgetListBox.h"
-#include "GameClient/GadgetTextEntry.h"
-#include "GameClient/GadgetStaticText.h"
-#include "GameClient/MessageBox.h"
-#include "GameClient/GameWindowTransitions.h"
-
-#include "GameNetwork/FirewallHelper.h"
-#include "GameNetwork/GameSpyOverlay.h"
-
-#include "GameNetwork/GameSpy/BuddyDefs.h"
-#include "GameNetwork/GameSpy/BuddyThread.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpy/PeerThread.h"
-#include "GameNetwork/GameSpy/PersistentStorageDefs.h"
-#include "GameNetwork/GameSpy/PersistentStorageThread.h"
-#include "GameNetwork/GameSpy/BuddyThread.h"
-#include "GameNetwork/GameSpy/ThreadUtils.h"
-#include "GameNetwork/GameSpy/MainMenuUtils.h"
-
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-static Bool isShuttingDown = FALSE;
-static Bool buttonPushed = FALSE;
-static char *nextScreen = NULL;
-
-// window ids ------------------------------------------------------------------------------
-static NameKeyType parentWOLWelcomeID = NAMEKEY_INVALID;
-static NameKeyType buttonBackID = NAMEKEY_INVALID;
-static NameKeyType buttonQuickMatchID = NAMEKEY_INVALID;
-static NameKeyType buttonLobbyID = NAMEKEY_INVALID;
-static NameKeyType buttonBuddiesID = NAMEKEY_INVALID;
-static NameKeyType buttonLadderID = NAMEKEY_INVALID;
-static NameKeyType buttonMyInfoID = NAMEKEY_INVALID;
-
-static NameKeyType listboxInfoID = NAMEKEY_INVALID;
-static NameKeyType buttonOptionsID = NAMEKEY_INVALID;
-// Window Pointers ------------------------------------------------------------------------
-static GameWindow *parentWOLWelcome = NULL;
-static GameWindow *buttonBack = NULL;
-static GameWindow *buttonQuickMatch = NULL;
-static GameWindow *buttonLobby = NULL;
-static GameWindow *buttonBuddies = NULL;
-static GameWindow *buttonLadder = NULL;
-static GameWindow *buttonMyInfo = NULL;
-static GameWindow *buttonbuttonOptions = NULL;
-static WindowLayout *welcomeLayout = NULL;
-static GameWindow *listboxInfo = NULL;
-
-static GameWindow *staticTextServerName = NULL;
-static GameWindow *staticTextLastUpdated = NULL;
-
-static GameWindow *staticTextLadderWins = NULL;
-static GameWindow *staticTextLadderLosses = NULL;
-static GameWindow *staticTextLadderRank = NULL;
-static GameWindow *staticTextLadderPoints = NULL;
-static GameWindow *staticTextLadderDisconnects = NULL;
-
-static GameWindow *staticTextHighscoreWins = NULL;
-static GameWindow *staticTextHighscoreLosses = NULL;
-static GameWindow *staticTextHighscoreRank = NULL;
-static GameWindow *staticTextHighscorePoints = NULL;
-
-static UnicodeString gServerName;
-void updateServerDisplay(UnicodeString serverName)
-{
- if (staticTextServerName)
- {
- GadgetStaticTextSetText(staticTextServerName, serverName);
- }
- gServerName = serverName;
-}
-
-/*
-void updateLocalPlayerScores(AsciiString name, const WOL::Ladder *ladder, const WOL::Highscore *highscore)
-{
- if (ladder)
- {
- AsciiString a;
- UnicodeString u;
-
- a.format("%d", ladder->wins);
- u.translate(a);
- GadgetStaticTextSetText(staticTextLadderWins, u);
-
- a.format("%d", ladder->losses);
- u.translate(a);
- GadgetStaticTextSetText(staticTextLadderLosses, u);
-
- a.format("%d", ladder->rank);
- u.translate(a);
- GadgetStaticTextSetText(staticTextLadderRank, u);
-
- a.format("%d", ladder->points);
- u.translate(a);
- GadgetStaticTextSetText(staticTextLadderPoints, u);
-
- a.format("%d", ladder->disconnects);
- u.translate(a);
- GadgetStaticTextSetText(staticTextLadderDisconnects, u);
- }
- if (highscore)
- {
- AsciiString a;
- UnicodeString u;
-
- a.format("%d", highscore->wins);
- u.translate(a);
- GadgetStaticTextSetText(staticTextHighscoreWins, u);
-
- a.format("%d", highscore->losses);
- u.translate(a);
- GadgetStaticTextSetText(staticTextHighscoreLosses, u);
-
- a.format("%d", highscore->rank);
- u.translate(a);
- GadgetStaticTextSetText(staticTextHighscoreRank, u);
-
- a.format("%d", highscore->points);
- u.translate(a);
- GadgetStaticTextSetText(staticTextHighscorePoints, u);
- }
-}
-*/
-
-
-static void enableControls( Bool state )
-{
-#ifndef _PLAYTEST
- if (buttonQuickMatch)
- buttonQuickMatch->winEnable(state);
-#else
- if (buttonQuickMatch)
- buttonQuickMatch->winEnable(FALSE);
-#endif
- if (buttonLobby)
- buttonLobby->winEnable(state);
-}
-
-//-------------------------------------------------------------------------------------------------
-/** This is called when a shutdown is complete for this menu */
-//-------------------------------------------------------------------------------------------------
-static void shutdownComplete( WindowLayout *layout )
-{
-
- isShuttingDown = FALSE;
-
- // hide the layout
- layout->hide( TRUE );
-
- // our shutdown is complete
- TheShell->shutdownComplete( layout, (nextScreen != NULL) );
-
- if (nextScreen != NULL)
- {
- TheShell->push(nextScreen);
- }
-
- nextScreen = NULL;
-
-} // end if
-
-//-------------------------------------------------------------------------------------------------
-/** Handle Num Players Online data */
-//-------------------------------------------------------------------------------------------------
-
-static Int lastNumPlayersOnline = 0;
-
-static UnsignedByte grabUByte(const char *s)
-{
- char tmp[5] = "0xff";
- tmp[2] = s[0];
- tmp[3] = s[1];
- UnsignedByte b = strtol(tmp, NULL, 16);
- return b;
-}
-
-static void updateNumPlayersOnline(void)
-{
- GameWindow *playersOnlineWindow = TheWindowManager->winGetWindowFromId(
- NULL, NAMEKEY("WOLWelcomeMenu.wnd:StaticTextNumPlayersOnline") );
-
- if (playersOnlineWindow)
- {
- UnicodeString valStr;
- valStr.format(TheGameText->fetch("GUI:NumPlayersOnline"), lastNumPlayersOnline);
- GadgetStaticTextSetText(playersOnlineWindow, valStr);
- }
-
- if (listboxInfo && TheGameSpyInfo)
- {
- GadgetListBoxReset(listboxInfo);
- AsciiString aLine;
- UnicodeString line;
- AsciiString aMotd = TheGameSpyInfo->getMOTD();
- UnicodeString headingStr;
- headingStr.format(TheGameText->fetch("MOTD:NumPlayersHeading"), lastNumPlayersOnline);
-
- while (headingStr.nextToken(&line, UnicodeString(L"\n")))
- {
- if (line.getCharAt(line.getLength()-1) == '\r')
- line.removeLastChar(); // there is a trailing '\r'
-
- line.trim();
-
- if (line.isEmpty())
- {
- line = UnicodeString(L" ");
- }
-
- GadgetListBoxAddEntryText(listboxInfo, line, GameSpyColor[GSCOLOR_MOTD_HEADING], -1, -1);
- }
- GadgetListBoxAddEntryText(listboxInfo, UnicodeString(L" "), GameSpyColor[GSCOLOR_MOTD_HEADING], -1, -1);
-
- while (aMotd.nextToken(&aLine, "\n"))
- {
- if (aLine.getCharAt(aLine.getLength()-1) == '\r')
- aLine.removeLastChar(); // there is a trailing '\r'
-
- aLine.trim();
-
- if (aLine.isEmpty())
- {
- aLine = " ";
- }
-
- Color c = GameSpyColor[GSCOLOR_MOTD];
- if (aLine.startsWith("\\\\"))
- {
- aLine = aLine.str()+1;
- }
- else if (aLine.startsWith("\\") && aLine.getLength() > 9)
- {
- // take out the hex value from strings starting as "\ffffffffText"
- UnsignedByte a, r, g, b;
- a = grabUByte(aLine.str()+1);
- r = grabUByte(aLine.str()+3);
- g = grabUByte(aLine.str()+5);
- b = grabUByte(aLine.str()+7);
- c = GameMakeColor(r, g, b, a);
- DEBUG_LOG(("MOTD line '%s' has color %X\n", aLine.str(), c));
- aLine = aLine.str() + 9;
- }
- line = UnicodeString(MultiByteToWideCharSingleLine(aLine.str()).c_str());
-
- GadgetListBoxAddEntryText(listboxInfo, line, c, -1, -1);
- }
- }
-}
-
-void HandleNumPlayersOnline( Int numPlayersOnline )
-{
- lastNumPlayersOnline = numPlayersOnline;
- if (lastNumPlayersOnline < 1)
- lastNumPlayersOnline = 1;
- updateNumPlayersOnline();
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Handle Overall Stats data */
-//-------------------------------------------------------------------------------------------------
-
-static OverallStats s_statsUSA, s_statsChina, s_statsGLA;
-
-OverallStats::OverallStats()
-{
- for (Int i=0; ifetch("GUI:PerSideWinPercentage"), REAL_TO_INT(val), sideStr.str());
-
- /*
- Int totalDenominator = s_statsUSA.wins[n] + s_statsChina.wins[n] + s_statsGLA.wins[n];
- if (!totalDenominator)
- totalDenominator = 1;
-
- UnicodeString s;
- s.format(TheGameText->fetch("GUI:PerSideWinPercentage"), REAL_TO_INT(stats.wins[n]*100/totalDenominator), sideStr.str());
- */
- return s;
-}
-
-static void updateOverallStats(void)
-{
- UnicodeString usa, china, gla;
- GameWindow *win;
-
- usa = calcPercent(s_statsUSA, STATS_LASTWEEK, TheGameText->fetch("SIDE:America"));
- china = calcPercent(s_statsChina, STATS_LASTWEEK, TheGameText->fetch("SIDE:China"));
- gla = calcPercent(s_statsGLA, STATS_LASTWEEK, TheGameText->fetch("SIDE:GLA"));
- DEBUG_LOG(("Last Week: %ls %ls %ls\n", usa.str(), china.str(), gla.str()));
- win = TheWindowManager->winGetWindowFromId( NULL, NAMEKEY("WOLWelcomeMenu.wnd:StaticTextUSALastWeek") );
- GadgetStaticTextSetText(win, usa);
- win = TheWindowManager->winGetWindowFromId( NULL, NAMEKEY("WOLWelcomeMenu.wnd:StaticTextChinaLastWeek") );
- GadgetStaticTextSetText(win, china);
- win = TheWindowManager->winGetWindowFromId( NULL, NAMEKEY("WOLWelcomeMenu.wnd:StaticTextGLALastWeek") );
- GadgetStaticTextSetText(win, gla);
-
- usa = calcPercent(s_statsUSA, STATS_TODAY, TheGameText->fetch("SIDE:America"));
- china = calcPercent(s_statsChina, STATS_TODAY, TheGameText->fetch("SIDE:China"));
- gla = calcPercent(s_statsGLA, STATS_TODAY, TheGameText->fetch("SIDE:GLA"));
- DEBUG_LOG(("Today: %ls %ls %ls\n", usa.str(), china.str(), gla.str()));
- win = TheWindowManager->winGetWindowFromId( NULL, NAMEKEY("WOLWelcomeMenu.wnd:StaticTextUSAToday") );
- GadgetStaticTextSetText(win, usa);
- win = TheWindowManager->winGetWindowFromId( NULL, NAMEKEY("WOLWelcomeMenu.wnd:StaticTextChinaToday") );
- GadgetStaticTextSetText(win, china);
- win = TheWindowManager->winGetWindowFromId( NULL, NAMEKEY("WOLWelcomeMenu.wnd:StaticTextGLAToday") );
- GadgetStaticTextSetText(win, gla);
-}
-
-void HandleOverallStats( const OverallStats& USA, const OverallStats& China, const OverallStats& GLA )
-{
- s_statsUSA = USA;
- s_statsChina = China;
- s_statsGLA = GLA;
- updateOverallStats();
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Handle player stats */
-//-------------------------------------------------------------------------------------------------
-
-void UpdateLocalPlayerStats(void)
-{
-
- GameWindow *welcomeParent = TheWindowManager->winGetWindowFromId( NULL, NAMEKEY("WOLWelcomeMenu.wnd:WOLWelcomeMenuParent") );
-
- if (welcomeParent)
- {
- PopulatePlayerInfoWindows( "WOLWelcomeMenu.wnd" );
- }
- else
- {
- PopulatePlayerInfoWindows( "WOLQuickMatchMenu.wnd" );
- }
-
- return;
-}
-
-static Bool raiseMessageBoxes = FALSE;
-//-------------------------------------------------------------------------------------------------
-/** Initialize the WOL Welcome Menu */
-//-------------------------------------------------------------------------------------------------
-void WOLWelcomeMenuInit( WindowLayout *layout, void *userData )
-{
- nextScreen = NULL;
- buttonPushed = FALSE;
- isShuttingDown = FALSE;
-
- welcomeLayout = layout;
-
- //TheWOL->reset();
-
- parentWOLWelcomeID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLWelcomeMenu.wnd:WOLWelcomeMenuParent" ) );
- buttonBackID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLWelcomeMenu.wnd:ButtonBack" ) );
- parentWOLWelcome = TheWindowManager->winGetWindowFromId( NULL, parentWOLWelcomeID );
- buttonBack = TheWindowManager->winGetWindowFromId( NULL, buttonBackID);
- buttonOptionsID = TheNameKeyGenerator->nameToKey( "WOLWelcomeMenu.wnd:ButtonOptions" );
- buttonbuttonOptions = TheWindowManager->winGetWindowFromId( NULL, buttonOptionsID);
- listboxInfoID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLWelcomeMenu.wnd:InfoListbox" ) );
-
- listboxInfo = TheWindowManager->winGetWindowFromId( NULL, listboxInfoID);
-
- staticTextServerName = TheWindowManager->winGetWindowFromId( parentWOLWelcome,
- TheNameKeyGenerator->nameToKey( "WOLWelcomeMenu.wnd:StaticTextServerName" ));
- staticTextLastUpdated = TheWindowManager->winGetWindowFromId( parentWOLWelcome,
- TheNameKeyGenerator->nameToKey( "WOLWelcomeMenu.wnd:StaticTextLastUpdated" ));
-
- staticTextLadderWins = TheWindowManager->winGetWindowFromId( parentWOLWelcome,
- TheNameKeyGenerator->nameToKey( "WOLWelcomeMenu.wnd:StaticTextLadderWins" ));
- staticTextLadderLosses = TheWindowManager->winGetWindowFromId( parentWOLWelcome,
- TheNameKeyGenerator->nameToKey( "WOLWelcomeMenu.wnd:StaticTextLadderLosses" ));
- staticTextLadderPoints = TheWindowManager->winGetWindowFromId( parentWOLWelcome,
- TheNameKeyGenerator->nameToKey( "WOLWelcomeMenu.wnd:StaticTextLadderPoints" ));
- staticTextLadderRank = TheWindowManager->winGetWindowFromId( parentWOLWelcome,
- TheNameKeyGenerator->nameToKey( "WOLWelcomeMenu.wnd:StaticTextLadderRank" ));
- staticTextLadderDisconnects = TheWindowManager->winGetWindowFromId( parentWOLWelcome,
- TheNameKeyGenerator->nameToKey( "WOLWelcomeMenu.wnd:StaticTextDisconnects" ));
-
- staticTextHighscoreWins = TheWindowManager->winGetWindowFromId( parentWOLWelcome,
- TheNameKeyGenerator->nameToKey( "WOLWelcomeMenu.wnd:StaticTextHighscoreWins" ));
- staticTextHighscoreLosses = TheWindowManager->winGetWindowFromId( parentWOLWelcome,
- TheNameKeyGenerator->nameToKey( "WOLWelcomeMenu.wnd:StaticTextHighscoreLosses" ));
- staticTextHighscorePoints = TheWindowManager->winGetWindowFromId( parentWOLWelcome,
- TheNameKeyGenerator->nameToKey( "WOLWelcomeMenu.wnd:StaticTextHighscorePoints" ));
- staticTextHighscoreRank = TheWindowManager->winGetWindowFromId( parentWOLWelcome,
- TheNameKeyGenerator->nameToKey( "WOLWelcomeMenu.wnd:StaticTextHighscoreRank" ));
-
- if (staticTextServerName)
- {
- GadgetStaticTextSetText(staticTextServerName, gServerName);
- }
-
- GameWindow *staticTextTitle = TheWindowManager->winGetWindowFromId(parentWOLWelcome, NAMEKEY("WOLWelcomeMenu.wnd:StaticTextTitle"));
- if (staticTextTitle && TheGameSpyInfo)
- {
- UnicodeString title;
- title.format(TheGameText->fetch("GUI:WOLWelcome"), TheGameSpyInfo->getLocalBaseName().str());
- GadgetStaticTextSetText(staticTextTitle, title);
- }
-
- // Clear some defaults
- /*
- UnicodeString questionMark = UnicodeString(L"?");
- GadgetStaticTextSetText(staticTextLastUpdated, questionMark);
- GadgetStaticTextSetText(staticTextLadderWins, questionMark);
- GadgetStaticTextSetText(staticTextLadderLosses, questionMark);
- GadgetStaticTextSetText(staticTextLadderPoints, questionMark);
- GadgetStaticTextSetText(staticTextLadderRank, questionMark);
- GadgetStaticTextSetText(staticTextLadderDisconnects, questionMark);
- GadgetStaticTextSetText(staticTextHighscoreWins, questionMark);
- GadgetStaticTextSetText(staticTextHighscoreLosses, questionMark);
- GadgetStaticTextSetText(staticTextHighscorePoints, questionMark);
- GadgetStaticTextSetText(staticTextHighscoreRank, questionMark);
- */
-
- //DEBUG_ASSERTCRASH(listboxInfo, ("No control found!"));
-
- buttonQuickMatchID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLWelcomeMenu.wnd:ButtonQuickMatch" ) );
- buttonQuickMatch = TheWindowManager->winGetWindowFromId( parentWOLWelcome, buttonQuickMatchID );
-
- buttonLobbyID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLWelcomeMenu.wnd:ButtonCustomMatch" ) );
- buttonLobby = TheWindowManager->winGetWindowFromId( parentWOLWelcome, buttonLobbyID );
-
- buttonBuddiesID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLWelcomeMenu.wnd:ButtonBuddies" ) );
- buttonBuddies = TheWindowManager->winGetWindowFromId( parentWOLWelcome, buttonBuddiesID );
-
- buttonMyInfoID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLWelcomeMenu.wnd:ButtonMyInfo" ) );
- buttonMyInfo = TheWindowManager->winGetWindowFromId( parentWOLWelcome, buttonMyInfoID );
-
- buttonLadderID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLWelcomeMenu.wnd:ButtonLadder" ) );
- buttonLadder = TheWindowManager->winGetWindowFromId( parentWOLWelcome, buttonLadderID );
-
- if (TheFirewallHelper == NULL) {
- TheFirewallHelper = createFirewallHelper();
- }
- if (TheFirewallHelper->detectFirewall() == TRUE) {
- // don't need to detect firewall, already been done.
- delete TheFirewallHelper;
- TheFirewallHelper = NULL;
- }
- /*
-
- if (TheGameSpyChat && TheGameSpyChat->isConnected())
- {
- const char *keys[3] = { "locale", "wins", "losses" };
- char valueStrings[3][20];
- char *values[3] = { valueStrings[0], valueStrings[1], valueStrings[2] };
- _snprintf(values[0], 20, "%s", TheGameSpyPlayerInfo->getLocale().str());
- _snprintf(values[1], 20, "%d", TheGameSpyPlayerInfo->getWins());
- _snprintf(values[2], 20, "%d", TheGameSpyPlayerInfo->getLosses());
- peerSetGlobalKeys(TheGameSpyChat->getPeer(), 3, (const char **)keys, (const char **)values);
- peerSetGlobalWatchKeys(TheGameSpyChat->getPeer(), GroupRoom, 3, keys, PEERFalse);
- peerSetGlobalWatchKeys(TheGameSpyChat->getPeer(), StagingRoom, 3, keys, PEERFalse);
- }
- */
-
-// // animate controls
-// TheShell->registerWithAnimateManager(buttonQuickMatch, WIN_ANIMATION_SLIDE_LEFT, TRUE, 800);
-// TheShell->registerWithAnimateManager(buttonLobby, WIN_ANIMATION_SLIDE_LEFT, TRUE, 600);
-// //TheShell->registerWithAnimateManager(NULL, WIN_ANIMATION_SLIDE_LEFT, TRUE, 400);
-// TheShell->registerWithAnimateManager(buttonBuddies, WIN_ANIMATION_SLIDE_LEFT, TRUE, 200);
-// //TheShell->registerWithAnimateManager(NULL, WIN_ANIMATION_SLIDE_LEFT, TRUE, 1);
-// TheShell->registerWithAnimateManager(buttonBack, WIN_ANIMATION_SLIDE_BOTTOM, TRUE, 1);
-
- // Show Menu
- layout->hide( FALSE );
-
- // Set Keyboard to Main Parent
- TheWindowManager->winSetFocus( parentWOLWelcome );
-
- enableControls( TheGameSpyInfo->gotGroupRoomList() );
- TheShell->showShellMap(TRUE);
-
- updateNumPlayersOnline();
- updateOverallStats();
-
- UpdateLocalPlayerStats();
-
- GameSpyMiscPreferences cPref;
- if (cPref.getLocale() < LOC_MIN || cPref.getLocale() > LOC_MAX)
- {
- GameSpyOpenOverlay(GSOVERLAY_LOCALESELECT);
- }
-
- raiseMessageBoxes = TRUE;
- TheTransitionHandler->setGroup("WOLWelcomeMenuFade");
-
-} // WOLWelcomeMenuInit
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Welcome Menu shutdown method */
-//-------------------------------------------------------------------------------------------------
-void WOLWelcomeMenuShutdown( WindowLayout *layout, void *userData )
-{
- listboxInfo = NULL;
-
- if (TheFirewallHelper != NULL) {
- delete TheFirewallHelper;
- TheFirewallHelper = NULL;
- }
-
- isShuttingDown = TRUE;
-
- // if we are shutting down for an immediate pop, skip the animations
- Bool popImmediate = *(Bool *)userData;
- if( popImmediate )
- {
-
- shutdownComplete( layout );
- return;
-
- } //end if
-
- TheShell->reverseAnimatewindow();
- TheTransitionHandler->reverse("WOLWelcomeMenuFade");
-
-
- RaiseGSMessageBox();
-} // WOLWelcomeMenuShutdown
-
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Welcome Menu update method */
-//-------------------------------------------------------------------------------------------------
-void WOLWelcomeMenuUpdate( WindowLayout * layout, void *userData)
-{
- // We'll only be successful if we've requested to
- if(isShuttingDown && TheShell->isAnimFinished() && TheTransitionHandler->isFinished())
- shutdownComplete(layout);
-
- if (raiseMessageBoxes)
- {
- RaiseGSMessageBox();
- raiseMessageBoxes = FALSE;
- }
-
- if (TheFirewallHelper != NULL)
- {
- if (TheFirewallHelper->behaviorDetectionUpdate())
- {
- TheWritableGlobalData->m_firewallBehavior = TheFirewallHelper->getFirewallBehavior();
-
- TheFirewallHelper->writeFirewallBehavior();
-
- TheFirewallHelper->flagNeedToRefresh(FALSE); // 2/19/03 BGC, we're done, so we don't need to refresh the NAT anymore.
-
- // we are now done with the firewall helper
- delete TheFirewallHelper;
- TheFirewallHelper = NULL;
- }
- }
-
- if (TheShell->isAnimFinished() && !buttonPushed && TheGameSpyPeerMessageQueue)
- {
- HandleBuddyResponses();
- HandlePersistentStorageResponses();
-
- Int allowedMessages = TheGameSpyInfo->getMaxMessagesPerUpdate();
- Bool sawImportantMessage = FALSE;
- PeerResponse resp;
- while (allowedMessages-- && !sawImportantMessage && TheGameSpyPeerMessageQueue->getResponse( resp ))
- {
- switch (resp.peerResponseType)
- {
- case PeerResponse::PEERRESPONSE_GROUPROOM:
- {
- GameSpyGroupRoom room;
- room.m_groupID = resp.groupRoom.id;
- room.m_maxWaiting = resp.groupRoom.maxWaiting;
- room.m_name = resp.groupRoomName.c_str();
- room.m_translatedName = UnicodeString(L"TEST");
- room.m_numGames = resp.groupRoom.numGames;
- room.m_numPlaying = resp.groupRoom.numPlaying;
- room.m_numWaiting = resp.groupRoom.numWaiting;
- TheGameSpyInfo->addGroupRoom( room );
- if (room.m_groupID == 0)
- {
- enableControls( TRUE );
- }
- }
- break;
- case PeerResponse::PEERRESPONSE_JOINGROUPROOM:
- {
- sawImportantMessage = TRUE;
- enableControls( TRUE );
- if (resp.joinGroupRoom.ok)
- {
- //buttonPushed = TRUE;
- TheGameSpyInfo->setCurrentGroupRoom(resp.joinGroupRoom.id);
- //GSMessageBoxOk( TheGameText->fetch("GUI:GSErrorTitle"), TheGameText->fetch("GUI:GSGroupRoomJoinOK") );
-
- buttonPushed = TRUE;
- nextScreen = "Menus/WOLCustomLobby.wnd";
- TheShell->pop();
- //TheShell->push( "Menus/WOLCustomLobby.wnd" );
- }
- else
- {
- GSMessageBoxOk( TheGameText->fetch("GUI:GSErrorTitle"), TheGameText->fetch("GUI:GSGroupRoomJoinFail") );
- }
- }
- break;
- case PeerResponse::PEERRESPONSE_DISCONNECT:
- {
- sawImportantMessage = TRUE;
- UnicodeString title, body;
- AsciiString disconMunkee;
- disconMunkee.format("GUI:GSDisconReason%d", resp.discon.reason);
- title = TheGameText->fetch( "GUI:GSErrorTitle" );
- body = TheGameText->fetch( disconMunkee );
- GameSpyCloseAllOverlays();
- GSMessageBoxOk( title, body );
- TheShell->pop();
- }
- break;
- }
- }
- }
-
-}// WOLWelcomeMenuUpdate
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Welcome Menu input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLWelcomeMenuInput( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
- UnsignedByte key = mData1;
- UnsignedByte state = mData2;
- if (buttonPushed)
- break;
-
- switch( key )
- {
-
- // ----------------------------------------------------------------------------------------
- case KEY_ESC:
- {
-
- //
- // send a simulated selected event to the parent window of the
- // back/exit button
- //
- if( BitTest( state, KEY_STATE_UP ) )
- {
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)buttonBack, buttonBackID );
-
- } // end if
-
- // don't let key fall through anywhere else
- return MSG_HANDLED;
-
- } // end escape
-
- } // end switch( key )
-
- } // end char
-
- } // end switch( msg )
-
- return MSG_IGNORED;
-}// WOLWelcomeMenuInput
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Welcome Menu window system callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLWelcomeMenuSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- UnicodeString txtInput;
-
- switch( msg )
- {
-
-
- case GWM_CREATE:
- {
-
- break;
- } // case GWM_DESTROY:
-
- case GWM_DESTROY:
- {
- break;
- } // case GWM_DESTROY:
-
- case GWM_INPUT_FOCUS:
- {
- // if we're givin the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
-
- return MSG_HANDLED;
- }//case GWM_INPUT_FOCUS:
-
- case GBM_SELECTED:
- {
- if (buttonPushed)
- break;
-
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if ( controlID == buttonBackID )
- {
- //DEBUG_ASSERTCRASH(TheGameSpyChat->getPeer(), ("No GameSpy Peer object!"));
- //TheGameSpyChat->disconnectFromChat();
-
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_LOGOUT;
- TheGameSpyPeerMessageQueue->addRequest( req );
- BuddyRequest breq;
- breq.buddyRequestType = BuddyRequest::BUDDYREQUEST_LOGOUT;
- TheGameSpyBuddyMessageQueue->addRequest( breq );
-
- DEBUG_LOG(("Tearing down GameSpy from WOLWelcomeMenuSystem(GBM_SELECTED)\n"));
- TearDownGameSpy();
-
- /*
- if (TheGameSpyChat->getPeer())
- {
- peerDisconnect(TheGameSpyChat->getPeer());
- }
- */
-
- buttonPushed = TRUE;
-
- TheShell->pop();
-
- /// @todo: log out instead of disconnecting
- //TheWOL->addCommand( WOL::WOLCOMMAND_LOGOUT );
- /**
- closeAllOverlays();
- TheShell->pop();
- delete TheWOL;
- TheWOL = NULL;
- delete TheWOLGame;
- TheWOLGame = NULL;
- **/
-
- } //if ( controlID == buttonBack )
- else if (controlID == buttonOptionsID)
- {
- GameSpyOpenOverlay( GSOVERLAY_OPTIONS );
- }
- else if (controlID == buttonQuickMatchID)
- {
- GameSpyMiscPreferences mPref;
- if ((TheDisplay->getWidth() != 800 || TheDisplay->getHeight() != 600) && mPref.getQuickMatchResLocked())
- {
- GSMessageBoxOk(TheGameText->fetch("GUI:GSErrorTitle"), TheGameText->fetch("GUI:QuickMatch800x600"));
- }
- else
- {
- buttonPushed = TRUE;
- nextScreen = "Menus/WOLQuickMatchMenu.wnd";
- TheShell->pop();
- }
- }// else if
- else if (controlID == buttonMyInfoID )
- {
- SetLookAtPlayer(TheGameSpyInfo->getLocalProfileID(), TheGameSpyInfo->getLocalName());
- GameSpyToggleOverlay(GSOVERLAY_PLAYERINFO);
- }
- else if (controlID == buttonLobbyID)
- {
- //TheGameSpyChat->clearGroupRoomList();
- //peerListGroupRooms(TheGameSpyChat->getPeer(), ListGroupRoomsCallback, NULL, PEERTrue);
- TheGameSpyInfo->joinBestGroupRoom();
- enableControls( FALSE );
-
-
- /*
- TheWOL->setScreen(WOL::WOLAPI_MENU_CUSTOMLOBBY);
- TheWOL->setGameMode(WOL::WOLTYPE_CUSTOM);
- TheWOL->setState( WOL::WOLAPI_LOBBY );
- TheWOL->addCommand( WOL::WOLCOMMAND_REFRESH_CHANNELS );
- */
- }// else if
- else if (controlID == buttonBuddiesID)
- {
- GameSpyToggleOverlay( GSOVERLAY_BUDDY );
- /*
- Bool joinedRoom = FALSE;
- ClearGroupRoomList();
- peerJoinTitleRoom(TheGameSpyChat->getPeer(), JoinRoomCallback, &joinedRoom, PEERTrue);
- if (joinedRoom)
- {
- GameSpyUsingGroupRooms = FALSE;
- GameSpyCurrentGroupRoomID = 0;
- TheShell->pop();
- TheShell->push("Menus/WOLCustomLobby.wnd");
- }
- else
- {
- GameSpyCurrentGroupRoomID = 0;
- GSMessageBoxOk(UnicodeString(L"Oops"), UnicodeString(L"Unable to join title room"), NULL);
- }
- */
- }
- else if (controlID == buttonLadderID)
- {
- TheShell->push(AsciiString("Menus/WOLLadderScreen.wnd"));
- }
- break;
- }// case GBM_SELECTED:
-
- case GEM_EDIT_DONE:
- {
- break;
- }
- default:
- return MSG_IGNORED;
-
- }//Switch
-
- return MSG_HANDLED;
-}// WOLWelcomeMenuSystem
diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/LoadScreen.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/LoadScreen.cpp
index d7a48d406e4..16fcdc80557 100644
--- a/Generals/Code/GameEngine/Source/GameClient/GUI/LoadScreen.cpp
+++ b/Generals/Code/GameEngine/Source/GameClient/GUI/LoadScreen.cpp
@@ -84,8 +84,6 @@
#include "GameLogic/FPUControl.h"
#include "GameLogic/GameLogic.h"
#include "GameNetwork/NetworkInterface.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpy/PersistentStorageThread.h"
#include "GameClient/CampaignManager.h"
#include "GameNetwork/RankPointValue.h"
#include "GameClient/GameWindowTransitions.h"
@@ -885,327 +883,6 @@ void MultiPlayerLoadScreen::processProgress(Int playerId, Int percentage)
GadgetProgressBarSetProgress(m_progressBars[m_playerLookup[playerId]], percentage );
}
-// GameSpyLoadScreen Class //////////////////////////////////////////////////
-//-----------------------------------------------------------------------------
-GameSpyLoadScreen::GameSpyLoadScreen( void )
-{
-
- // Added By Sadullah Nader
- // Initializations missing and needed
- m_mapPreview = NULL;
- //
-
- for(Int i = 0; i < MAX_SLOTS; ++i)
- {
-
- // Added By Sadullah Nader
- // Initializations missing and needed
- m_buttonMapStartPosition[i] = NULL;
- m_playerRank[i] = NULL;
- //
-
- m_playerOfficerMedal[i] = NULL;
- m_progressBars[i] = NULL;
- m_playerNames[i] = NULL;
- m_playerSide[i]= NULL;
- m_playerLookup[i] = -1;
- m_playerFavoriteFactions[i]= NULL;
- m_playerTotalDisconnects[i]= NULL;
- m_playerWin[i]= NULL;
- m_playerWinLosses[i]= NULL;
- }
-}
-
-GameSpyLoadScreen::~GameSpyLoadScreen( void )
-{
- for(Int i = 0; i < MAX_SLOTS; ++i)
- {
- m_progressBars[i] = NULL;
- m_playerNames[i] = NULL;
- m_playerSide[i]= NULL;
- m_playerLookup[i] = -1;
- m_playerFavoriteFactions[i]= NULL;
- m_playerTotalDisconnects[i]= NULL;
- m_playerWin[i]= NULL;
- m_playerWinLosses[i]= NULL;
- }
-}
-
-extern Int GetAdditionalDisconnectsFromUserFile(Int playerID);
-
-void GameSpyLoadScreen::init( GameInfo *game )
-{
- // create the layout of the load screen
- m_loadScreen = TheWindowManager->winCreateFromScript( AsciiString( "Menus/GameSpyLoadScreen.wnd" ) );
- DEBUG_ASSERTCRASH(m_loadScreen, ("Can't initialize the Multiplayer loadscreen"));
- m_loadScreen->winHide(FALSE);
- m_loadScreen->winBringToTop();
- m_mapPreview = TheWindowManager->winGetWindowFromId( m_loadScreen,TheNameKeyGenerator->nameToKey( "GameSpyLoadScreen.wnd:WinMapPreview"));
- DEBUG_ASSERTCRASH(TheNetwork, ("Where the Heck is the Network!!!!"));
- DEBUG_LOG(("NumPlayers %d\n", TheNetwork->getNumPlayers()));
-GameSlot *lSlot = game->getSlot(game->getLocalSlotNum());
- const PlayerTemplate* pt;
- if (lSlot->getPlayerTemplate() >= 0)
- pt = ThePlayerTemplateStore->getNthPlayerTemplate(lSlot->getPlayerTemplate());
- else
- pt = ThePlayerTemplateStore->findPlayerTemplate( TheNameKeyGenerator->nameToKey("FactionObserver") );
- const Image *loadScreenImage = TheMappedImageCollection->findImageByName(pt->getLoadScreen());
- if(loadScreenImage)
- m_loadScreen->winSetEnabledImage(0, loadScreenImage);
-
- GameWindow *teamWin[MAX_SLOTS];
- for (Int i = 0; i < MAX_SLOTS; ++i)
- {
- teamWin[i] = NULL;
- }
-
- Int netSlot = 0;
- // Loop through and make the loadscreen look all good.
- for (i = 0; i < MAX_SLOTS; ++i)
- {
- // Load the Progress Bar
- AsciiString winName;
- winName.format( "GameSpyLoadScreen.wnd:ProgressLoad%d",i);
- m_progressBars[i] = TheWindowManager->winGetWindowFromId( m_loadScreen,TheNameKeyGenerator->nameToKey( winName ));
- DEBUG_ASSERTCRASH(m_progressBars[i], ("Can't initialize the progressbars for the GameSpyLoadScreen loadscreen"));
- // set the progressbar to zero
- GadgetProgressBarSetProgress(m_progressBars[i], 0 );
-
- // Load the Player's name
- winName.format( "GameSpyLoadScreen.wnd:StaticTextPlayer%d",i);
- m_playerNames[i] = TheWindowManager->winGetWindowFromId( m_loadScreen,TheNameKeyGenerator->nameToKey( winName ));
- DEBUG_ASSERTCRASH(m_playerNames[i], ("Can't initialize the Names for the GameSpyLoadScreen loadscreen"));
-
- // Load MapStart Positions
- winName.format( "GameSpyLoadScreen.wnd:ButtonMapStartPosition%d",i);
- m_buttonMapStartPosition[i] = TheWindowManager->winGetWindowFromId( m_loadScreen,TheNameKeyGenerator->nameToKey( winName ));
- DEBUG_ASSERTCRASH(m_buttonMapStartPosition[i], ("Can't initialize the MapStart Positions for the GameSpyLoadScreen loadscreen"));
-
-
- // Load the Player's Side
- winName.format( "GameSpyLoadScreen.wnd:StaticTextSide%d",i);
- m_playerSide[i] = TheWindowManager->winGetWindowFromId( m_loadScreen,TheNameKeyGenerator->nameToKey( winName ));
- DEBUG_ASSERTCRASH(m_playerSide[i], ("Can't initialize the Sides for the GameSpyLoadScreen loadscreen"));
-
- // Load the Player's window
- winName.format( "GameSpyLoadScreen.wnd:WinPlayer%d",i);
- m_playerWin[i] = TheWindowManager->winGetWindowFromId( m_loadScreen,TheNameKeyGenerator->nameToKey( winName ));
- DEBUG_ASSERTCRASH(m_playerWin[i], ("Can't initialize the WinPlayer for the GameSpyLoadScreen loadscreen"));
-
- // Load the Player's m_playerTotalDisconnects
- winName.format( "GameSpyLoadScreen.wnd:StaticTextTotalDisconnects%d",i);
- m_playerTotalDisconnects[i] = TheWindowManager->winGetWindowFromId( m_loadScreen,TheNameKeyGenerator->nameToKey( winName ));
- DEBUG_ASSERTCRASH(m_playerTotalDisconnects[i], ("Can't initialize the m_playerTotalDisconnects for the GameSpyLoadScreen loadscreen"));
-
-// // Load the Player's m_playerFavoriteFactions
-// winName.format( "GameSpyLoadScreen.wnd:StaticTextFavoriteFaction%d",i);
-// m_playerFavoriteFactions[i] = TheWindowManager->winGetWindowFromId( m_loadScreen,TheNameKeyGenerator->nameToKey( winName ));
-// DEBUG_ASSERTCRASH(m_playerFavoriteFactions[i], ("Can't initialize the StaticTextFavoriteFaction for the GameSpyLoadScreen loadscreen"));
-
- // Load the Player's m_playerWinLosses
- winName.format( "GameSpyLoadScreen.wnd:StaticTextWinLoss%d",i);
- m_playerWinLosses[i] = TheWindowManager->winGetWindowFromId( m_loadScreen,TheNameKeyGenerator->nameToKey( winName ));
- DEBUG_ASSERTCRASH(m_playerWinLosses[i], ("Can't initialize the m_playerWinLosses for the GameSpyLoadScreen loadscreen"));
-
- // Load the Player's m_playerWinLosses
- winName.format( "GameSpyLoadScreen.wnd:WinRank%d",i);
- m_playerRank[i] = TheWindowManager->winGetWindowFromId( m_loadScreen,TheNameKeyGenerator->nameToKey( winName ));
- DEBUG_ASSERTCRASH(m_playerRank[i], ("Can't initialize the m_playerRank for the GameSpyLoadScreen loadscreen"));
-
- // Load the Player's m_playerOfficerMedal
- winName.format( "GameSpyLoadScreen.wnd:WinOfficer%d",i);
- m_playerOfficerMedal[i] = TheWindowManager->winGetWindowFromId( m_loadScreen,TheNameKeyGenerator->nameToKey( winName ));
- DEBUG_ASSERTCRASH(m_playerOfficerMedal[i], ("Can't initialize the m_playerOfficerMedal for the GameSpyLoadScreen loadscreen"));
-
- winName.format( "MultiplayerLoadScreen.wnd:StaticTextTeam%d",i);
- teamWin[i] = TheWindowManager->winGetWindowFromId( m_loadScreen,TheNameKeyGenerator->nameToKey( winName ));
-
- // get the slot man!
- GameSpyGameSlot *slot = (GameSpyGameSlot *)game->getSlot(i);
- if (!slot || !slot->isOccupied())
- continue;
- Color houseColor = TheMultiplayerSettings->getColor(slot->getApparentColor())->getColor();
- GadgetProgressBarSetEnabledBarColor(m_progressBars[netSlot],houseColor );
-
- UnicodeString name = slot->getName();
- GadgetStaticTextSetText(m_playerNames[netSlot], name );
- m_playerNames[netSlot]->winSetEnabledTextColors(houseColor, m_playerNames[netSlot]->winGetEnabledTextBorderColor());
-
- // Get the stats for the player
- PSPlayerStats stats = TheGameSpyPSMessageQueue->findPlayerStatsByID(slot->getProfileID());
- DEBUG_LOG(("LoadScreen - populating info for %ls(%d) - stats returned id %d\n",
- slot->getName().str(), slot->getProfileID(), stats.id));
-
- Bool isPreorder = TheGameSpyInfo->didPlayerPreorder(stats.id);
- Int rankPoints = CalculateRank(stats);
- Int favSide = GetFavoriteSide(stats);
- const Image *preorderImg = TheMappedImageCollection->findImageByName("OfficersClubsmall");
- if (!isPreorder)
- preorderImg = NULL;
- const Image *rankImg = LookupSmallRankImage(favSide, rankPoints);
- m_playerOfficerMedal[i]->winSetEnabledImage(0, preorderImg);
- m_playerRank[i]->winSetEnabledImage(0, rankImg);
-
- UnicodeString formatString;
-
- // pop wins and losses
- Int numLosses = 0;
- PerGeneralMap::iterator it;
- for(it = stats.losses.begin(); it != stats.losses.end(); ++it)
- {
- numLosses += it->second;
- }
- Int numWins = 0;
- for(it =stats.wins.begin(); it != stats.wins.end(); ++it)
- {
- numWins += it->second;
- }
- formatString.format(L"%d/%d", numWins, numLosses);
- GadgetStaticTextSetText(m_playerWinLosses[netSlot], formatString);
- m_playerWinLosses[netSlot]->winSetEnabledTextColors(houseColor, m_playerWinLosses[netSlot]->winGetEnabledTextBorderColor());
- // favoriteFaction
- Int numGames = 0;
- Int favorite = 0;
- for(it =stats.games.begin(); it != stats.games.end(); ++it)
- {
- if(it->second >= numGames)
- {
- numGames = it->second;
- favorite = it->first;
- }
- }
-// if(numGames == 0)
-// GadgetStaticTextSetText(m_playerFavoriteFactions[netSlot], TheGameText->fetch("GUI:None"));
-// else if( stats.gamesAsRandom > numGames )
-// GadgetStaticTextSetText(m_playerFavoriteFactions[netSlot], TheGameText->fetch("GUI:Random"));
-// else
-// {
-// const PlayerTemplate *fac = ThePlayerTemplateStore->getNthPlayerTemplate(favorite);
-// if (fac)
-// {
-// AsciiString side;
-// side.format("SIDE:%s", fac->getSide().str());
-//
-// GadgetStaticTextSetText(m_playerFavoriteFactions[netSlot], TheGameText->fetch(side));
-// }
-// }
-// m_playerFavoriteFactions[netSlot]->winSetEnabledTextColors(houseColor, m_playerFavoriteFactions[netSlot]->winGetEnabledTextBorderColor());
- // disconnects
- numGames = 0;
- for(it =stats.discons.begin(); it != stats.discons.end(); ++it)
- {
- numGames += it->second;
- }
- for(it =stats.desyncs.begin(); it != stats.desyncs.end(); ++it)
- {
- numGames += it->second;
- }
- numGames += GetAdditionalDisconnectsFromUserFile(stats.id);
-
- formatString.format(L"%d", numGames);
- GadgetStaticTextSetText(m_playerTotalDisconnects[netSlot], formatString);
- m_playerTotalDisconnects[netSlot]->winSetEnabledTextColors(houseColor, m_playerTotalDisconnects[netSlot]->winGetEnabledTextBorderColor());
- GadgetStaticTextSetText(m_playerSide[netSlot], slot->getApparentPlayerTemplateDisplayName() );
- m_playerSide[netSlot]->winSetEnabledTextColors(houseColor, m_playerSide[netSlot]->winGetEnabledTextBorderColor());
-
- if (slot->isAI())
- {
- if (m_progressBars[netSlot])
- m_progressBars[netSlot]->winHide(TRUE);
- if (m_playerTotalDisconnects[netSlot])
- m_playerTotalDisconnects[netSlot]->winHide(TRUE);
-// if (m_playerFavoriteFactions[netSlot])
-// m_playerFavoriteFactions[netSlot]->winHide(TRUE);
- if (m_playerWinLosses[netSlot])
- m_playerWinLosses[netSlot]->winHide(TRUE);
- if (m_playerRank[netSlot])
- m_playerRank[netSlot]->winHide(TRUE);
- if (m_playerOfficerMedal[netSlot])
- m_playerOfficerMedal[netSlot]->winHide(TRUE);
- }
-
- if (teamWin[netSlot])
- {
- AsciiString teamStr;
- teamStr.format("Team:%d", slot->getTeamNumber() + 1);
- if (slot->isAI() && slot->getTeamNumber() == -1)
- teamStr = "Team:AI";
- GadgetStaticTextSetText(teamWin[netSlot], TheGameText->fetch(teamStr));
- teamWin[netSlot]->winSetEnabledTextColors(houseColor, m_playerNames[netSlot]->winGetEnabledTextBorderColor());
- }
-
- m_playerLookup[i] = netSlot; // save our mapping so we can update progress correctly
-
- netSlot++;
- }
-
- for(i = netSlot; i < MAX_SLOTS; ++i)
- {
- m_playerWin[i]->winHide(TRUE);
- //m_playerNames[i]->winHide(TRUE);
- //m_playerSide[i]->winHide(TRUE);
- }
-
- if(m_mapPreview)
- {
- const MapMetaData *mmd = TheMapCache->findMap(game->getMap());
- Image *image = getMapPreviewImage(game->getMap());
- m_mapPreview->winSetUserData((void *)mmd);
-
- positionStartSpots( game, m_buttonMapStartPosition, m_mapPreview);
- updateMapStartSpots( game, m_buttonMapStartPosition, TRUE );
- //positionAdditionalImages((MapMetaData *)mmd, m_mapPreview, TRUE);
- if(image)
- {
- m_mapPreview->winSetStatus(WIN_STATUS_IMAGE);
- m_mapPreview->winSetEnabledImage(0, image);
- }
- else
- {
- m_mapPreview->winClearStatus(WIN_STATUS_IMAGE);
- }
- }
-
- TheGameLogic->initTimeOutValues();
-}
-
-void GameSpyLoadScreen::reset( void )
-{
- setLoadScreen(NULL);
- for(Int i = 0; i < MAX_SLOTS; ++i)
- {
- m_progressBars[i] = NULL;
- m_playerNames[i] = NULL;
- m_playerSide[i]= NULL;
- }
-}
-
-void GameSpyLoadScreen::update( Int percent )
-{
- if(percent <= 100)
- TheNetwork->updateLoadProgress( percent );
- TheNetwork->liteupdate();
-
- //GadgetProgressBarSetProgress(m_progressBars[TheNetwork->getLocalPlayerID()], percent );
-
- TheMouse->setCursorTooltip(UnicodeString::TheEmptyString);
-
- // Do this last!
- LoadScreen::update( percent );
-}
-
-void GameSpyLoadScreen::processProgress(Int playerId, Int percentage)
-{
-
- if( percentage < 0 || percentage > 100 || playerId >= MAX_SLOTS || playerId < 0 || m_playerLookup[playerId] == -1)
- {
- DEBUG_ASSERTCRASH(FALSE, ("Percentage %d was passed in for Player %d\n", percentage, playerId));
- }
- //DEBUG_LOG(("Percentage %d was passed in for Player %d (in loadscreen position %d)\n", percentage, playerId, m_playerLookup[playerId]));
- if(m_progressBars[m_playerLookup[playerId]])
- GadgetProgressBarSetProgress(m_progressBars[m_playerLookup[playerId]], percentage );
-}
-
// MapTransferLoadScreen Class //////////////////////////////////////////////////
//-----------------------------------------------------------------------------
MapTransferLoadScreen::MapTransferLoadScreen( void )
diff --git a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy.cpp b/Generals/Code/GameEngine/Source/GameNetwork/GameSpy.cpp
deleted file mode 100644
index 21c7e05934c..00000000000
--- a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy.cpp
+++ /dev/null
@@ -1,1417 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: GameSpy.cpp //////////////////////////////////////////////////////
-// GameSpy callbacks, etc
-// Author: Matthew D. Campbell, February 2002
-
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "GameSpy/GP/GP.h"
-#include "GameSpy/gstats/gpersist.h"
-
-#include "GameNetwork/FirewallHelper.h"
-#include "GameNetwork/GameSpy.h"
-#include "GameNetwork/GameSpyChat.h"
-#include "GameNetwork/GameSpyGameInfo.h"
-#include "GameNetwork/GameSpyOverlay.h"
-#include "GameNetwork/GameSpyGP.h"
-#include "GameNetwork/GameSpyPersistentStorage.h"
-#include "GameNetwork/GameSpyThread.h"
-#include "GameNetwork/NAT.h"
-#include "GameClient/Shell.h"
-#include "GameClient/MessageBox.h"
-#include "GameClient/GameText.h"
-#include "GameClient/MapUtil.h"
-#include "Common/Version.h"
-#include "Common/MultiplayerSettings.h"
-#include "Common/PlayerTemplate.h"
-#include "Common/RandomValue.h"
-#include "Common/GlobalData.h"
-#include "Common/UserPreferences.h"
-#include "GameLogic/ScriptEngine.h"
-
-MutexClass TheGameSpyMutex;
-static UnsignedInt mainThreadID = 0;
-static Bool inThread = false;
-#define ISMAINTHREAD ( ThreadClass::_Get_Current_Thread_ID() == mainThreadID )
-GameSpyThreadClass *TheGameSpyThread = NULL;
-
-/// polling/update thread function
-
-void GameSpyThreadClass::Thread_Function()
-{
-
- //poll network and update GameSpy object
-
- while (running)
- {
- inThread = true;
- if (m_doLogin)
- {
- m_doLogin = false;
- TheGameSpyChat->login(m_nick, m_pass, m_email);
- }
- if (m_readStats)
- {
- m_readStats = false;
- TheGameSpyPlayerInfo->threadReadFromServer();
- }
- if (m_updateLocale)
- {
- m_updateLocale = false;
- TheGameSpyPlayerInfo->threadSetLocale(m_locale);
- }
- if (m_updateWins)
- {
- m_updateWins = false;
- TheGameSpyPlayerInfo->threadSetLocale(m_wins);
- }
- if (m_updateLosses)
- {
- m_updateLosses = false;
- TheGameSpyPlayerInfo->threadSetLocale(m_losses);
- }
- inThread = false;
- Switch_Thread();
- }
-}
-
-AsciiString GameSpyThreadClass::getNextShellScreen( void )
-{
- MutexClass::LockClass m(TheGameSpyMutex, 0);
- if (m.Failed())
- return AsciiString::TheEmptyString;
- return m_nextShellScreen;
-}
-
-Bool GameSpyThreadClass::showLocaleSelect( void )
-{
- MutexClass::LockClass m(TheGameSpyMutex, 0);
- if (m.Failed())
- return false;
- return m_showLocaleSelect;
-}
-
-void GameSpyThreadClass::setNextShellScreen( AsciiString nextShellScreen )
-{
- MutexClass::LockClass m(TheGameSpyMutex);
- m_nextShellScreen = nextShellScreen;
-}
-
-void GameSpyThreadClass::setShowLocaleSelect( Bool val )
-{
- MutexClass::LockClass m(TheGameSpyMutex);
- m_showLocaleSelect = val;
-}
-
-void createRoomCallback(PEER peer, PEERBool success, PEERJoinResult result, RoomType roomType, void *param);
-
-
-class GameSpyChat : public GameSpyChatInterface
-{
-public:
- GameSpyChat();
- virtual ~GameSpyChat();
-
- virtual void init( void );
- virtual void reset( void );
- virtual void update( void );
-
- virtual Bool isConnected( void );
- virtual void login(AsciiString loginName, AsciiString password = AsciiString::TheEmptyString, AsciiString email = AsciiString::TheEmptyString);
- virtual void reconnectProfile( void );
- virtual void disconnectFromChat( void );
-
- virtual void UTMRoom( RoomType roomType, const char *key, const char *val, Bool authenticate = FALSE );
- virtual void UTMPlayer( const char *name, const char *key, const char *val, Bool authenticate = FALSE );
- virtual void startGame( void );
- virtual void leaveRoom( RoomType roomType );
- virtual void setReady( Bool ready );
- virtual void enumPlayers( RoomType roomType, peerEnumPlayersCallback callback, void *userData );
- virtual void startListingGames( peerListingGamesCallback callback );
- virtual void stopListingGames( void );
-
- virtual void joinGroupRoom( Int ID );
- virtual void joinStagingRoom( GServer server, AsciiString password );
- virtual void createStagingRoom( AsciiString gameName, AsciiString password, Int maxPlayers );
- virtual void joinBestGroupRoom( void );
-
- void loginQuick(AsciiString loginName);
- void loginProfile(AsciiString loginName, AsciiString password, AsciiString email);
- void setProfileID( Int ID ) { m_profileID = ID; }
-
- void _connectCallback(PEER peer, PEERBool success, void * param);
- void _nickErrorCallback(PEER peer, int type, const char * nick, void * param);
- void _GPConnectCallback(GPConnection * pconnection, GPConnectResponseArg * arg, void * param);
- void _GPReconnectCallback(GPConnection * pconnection, GPConnectResponseArg * arg, void * param);
-
- inline void finishJoiningGroupRoom( void ) { m_joiningGroupRoom = false; }
- inline void finishJoiningStagingRoom( void ) { m_joiningStagingRoom = false; }
-
-private:
- UnsignedInt m_loginTimeoutPeriod; // in ms
- UnsignedInt m_loginTimeout;
-
- Bool m_joiningGroupRoom;
- Bool m_joiningStagingRoom;
-
- GameSpyThreadClass thread;
-};
-
-GameSpyChatInterface *TheGameSpyChat;
-GameSpyChatInterface *createGameSpyChat( void )
-{
- mainThreadID = ThreadClass::_Get_Current_Thread_ID();
- return NEW GameSpyChat;
-}
-
-void GameSpyChatInterface::clearGroupRoomList(void)
-{
- m_groupRooms.clear();
-}
-
-GameSpyChat::GameSpyChat()
-{
- m_peer = NULL;
-}
-
-GameSpyChat::~GameSpyChat()
-{
- reset();
- if (thread.Is_Running())
- thread.Stop();
- TheGameSpyThread = NULL;
-}
-
-void GameSpyChat::init( void )
-{
- reset();
-
- DEBUG_ASSERTCRASH(!thread.Is_Running(), ("Thread is running"));
-
- thread.Execute();
- thread.Set_Priority(0);
- TheGameSpyThread = &thread;
-}
-
-void GameSpyChat::reset( void )
-{
- MutexClass::LockClass m(TheGameSpyMutex);
- m_loginName.clear();
- m_password.clear();
- m_email.clear();
- m_usingProfiles = false;
- m_profileID = 0;
- if (m_peer)
- peerShutdown(m_peer);
- m_peer = NULL;
- m_groupRooms.clear();
- m_currentGroupRoomID = 0;
-
- m_loginTimeoutPeriod = 5000;
- m_loginTimeout = 0;
-
- m_joiningGroupRoom = false;
- m_joiningStagingRoom = false;
-
- //if (thread.Is_Running())
- //thread.Stop();
-}
-
-void GameSpyChat::update( void )
-{
- MutexClass::LockClass m(TheGameSpyMutex, 0);
- if (!m.Failed() && m_peer)
- {
- if (!TheGameSpyThread->getNextShellScreen().isEmpty())
- {
- TheShell->pop();
- TheShell->push(TheGameSpyThread->getNextShellScreen());
- TheGameSpyThread->setNextShellScreen( AsciiString.TheEmptyString );
- }
-
- if (TheGameSpyThread->showLocaleSelect())
- {
- TheGameSpyThread->setShowLocaleSelect(false);
- WindowLayout *layout = NULL;
- layout = TheWindowManager->winCreateLayout( AsciiString( "Menus/PopupLocaleSelect.wnd" ) );
- layout->runInit();
- layout->hide( FALSE );
- layout->bringForward();
- TheWindowManager->winSetModal( layout->getFirstWindow() );
- }
-
- //if (!isConnected())
- //return;
-
- peerThink(m_peer);
-
- gpProcess(TheGPConnection);
-
- if (TheNAT != NULL) {
- NATStateType NATState = TheNAT->update();
- if (NATState == NATSTATE_DONE)
- {
- GameSpyLaunchGame();
- }
- else if (NATState == NATSTATE_FAILED)
- {
- GameSpyLaunchGame();
- }
- }
-
- if (TheFirewallHelper != NULL) {
- if (TheFirewallHelper->behaviorDetectionUpdate()) {
- TheGlobalData->m_firewallBehavior = TheFirewallHelper->getFirewallBehavior();
- OptionPreferences *pref = NEW OptionPreferences;
- char num[16];
- num[0] = 0;
- itoa(TheGlobalData->m_firewallBehavior, num, 10);
- AsciiString numstr;
- numstr = num;
- (*pref)["FirewallBehavior"] = numstr;
- pref->write();
-
- // we are now done with the firewall helper
- delete TheFirewallHelper;
- TheFirewallHelper = NULL;
- }
- }
-
- UnsignedInt now = timeGetTime();
- if (m_loginTimeout && now > m_loginTimeout)
- {
- // login timed out
- m_loginTimeout = 0;
- GSMessageBoxOk(UnicodeString(L"Error connecting"), UnicodeString(L"Timed out connecting"), NULL);
-
- // Enable controls again
- //EnableLoginControls(TRUE);
-
- if (TheGameSpyGame)
- delete TheGameSpyGame;
- TheGameSpyGame = NULL;
-
- if (m_peer)
- peerShutdown(m_peer);
- m_peer = NULL;
-
- gpDisconnect(TheGPConnection);
- gpDestroy(TheGPConnection);
- }
- }
-}
-
-Bool GameSpyChat::isConnected( void )
-{
- return m_peer && peerIsConnected(m_peer);
-}
-
-void GameSpyChat::UTMRoom( RoomType roomType, const char *key, const char *val, Bool authenticate )
-{
- peerUTMRoom( m_peer, roomType, key, val, (authenticate)?PEERTrue:PEERFalse );
-}
-
-void GameSpyChat::UTMPlayer( const char *name, const char *key, const char *val, Bool authenticate )
-{
- peerUTMPlayer( m_peer, name, key, val, (authenticate)?PEERTrue:PEERFalse );
-}
-
-void GameSpyChat::startGame( void )
-{
- peerStartGame( m_peer, NULL, PEER_STOP_REPORTING );
-}
-
-void GameSpyChat::leaveRoom( RoomType roomType )
-{
- peerLeaveRoom( m_peer, roomType, NULL );
-}
-
-void GameSpyChat::setReady( Bool ready )
-{
- peerSetReady( m_peer, (ready)?PEERTrue:PEERFalse );
-}
-
-void GameSpyChat::enumPlayers( RoomType roomType, peerEnumPlayersCallback callback, void *userData )
-{
- peerEnumPlayers( m_peer, roomType, callback, userData );
-}
-
-void GameSpyChat::startListingGames( peerListingGamesCallback callback )
-{
- peerSetUpdatesRoomChannel( m_peer, "#gmtest_updates" );
- peerStartListingGames( m_peer, NULL, callback, NULL );
-}
-
-void GameSpyChat::stopListingGames( void )
-{
- peerStopListingGames( m_peer );
-}
-
-void GameSpyChat::joinGroupRoom( Int ID )
-{
- if (m_joiningGroupRoom || m_joiningStagingRoom)
- return;
-
- m_joiningGroupRoom = true;
-
- if (getCurrentGroupRoomID())
- {
- leaveRoom(GroupRoom);
- setCurrentGroupRoomID(0);
- }
- peerJoinGroupRoom(m_peer, ID, JoinRoomCallback, (void *)ID, PEERFalse);
-}
-
-void GameSpyChat::joinStagingRoom( GServer server, AsciiString password )
-{
- if (m_joiningGroupRoom || m_joiningStagingRoom)
- return;
-
- m_joiningStagingRoom = true;
-
- peerJoinStagingRoom(m_peer, server, password.str(), JoinRoomCallback, server, PEERFalse);
-}
-
-void GameSpyChat::createStagingRoom( AsciiString gameName, AsciiString password, Int maxPlayers )
-{
- if (m_joiningGroupRoom || m_joiningStagingRoom)
- return;
-
- m_joiningStagingRoom = true;
-
- Int oldGroupID = TheGameSpyChat->getCurrentGroupRoomID();
-
- TheGameSpyChat->leaveRoom(GroupRoom);
- TheGameSpyChat->setCurrentGroupRoomID(0);
-
- DEBUG_LOG(("GameSpyChat::createStagingRoom - creating staging room, name is %s\n", m_loginName.str()));
-
- peerCreateStagingRoom(m_peer, m_loginName.str(), maxPlayers, password.str(), createRoomCallback, (void *)oldGroupID, PEERFalse);
-}
-
-void GameSpyChat::joinBestGroupRoom( void )
-{
- if (m_groupRooms.size())
- {
- int minID = -1;
- int minPlayers = 1000;
- GroupRoomMap::iterator iter = m_groupRooms.begin();
- while (iter != m_groupRooms.end())
- {
- GameSpyGroupRoom room = iter->second;
- DEBUG_LOG(("Group room %d: %s (%d, %d, %d, %d)\n", room.m_groupID, room.m_name.str(), room.m_numWaiting, room.m_maxWaiting,
- room.m_numGames, room.m_numPlaying));
-
- if (minPlayers > 25 && room.m_numWaiting < minPlayers)
- {
- minID = room.m_groupID;
- minPlayers = room.m_numWaiting;
- }
-
- ++iter;
- }
-
- if (minID > 0)
- {
- joinGroupRoom(minID);
- }
- else
- {
- GSMessageBoxOk(UnicodeString(L"Oops"), UnicodeString(L"No empty group rooms"), NULL);
- }
- }
- else
- {
- GSMessageBoxOk(UnicodeString(L"Oops"), UnicodeString(L"No group rooms"), NULL);
- }
-}
-
-void GameSpyChat::disconnectFromChat( void )
-{
- TheScriptEngine->signalUIInteract("GameSpyLogout");
-
- if (m_peer)
- {
- peerShutdown(m_peer);
- m_peer = NULL;
- }
- if (TheGameSpyGame)
- delete TheGameSpyGame;
- TheGameSpyGame = NULL;
-}
-
-
-
-
-
-
-//-----------------------------------------------------------------------
-
-void DisconnectedCallback(PEER peer, const char * reason,
- void * param)
-{
- TheScriptEngine->signalUIInteract("GameSpyLogout");
-
- if (TheGameSpyGame)
- delete TheGameSpyGame;
- TheGameSpyGame = NULL;
-
- GSMessageBoxOk(TheGameText->fetch("GUI:GSErrorTitle"), TheGameText->fetch("GUI:GSDisconnected"), NULL);
-
- WindowLayout * mainMenu = TheShell->findScreenByFilename("Menus/MainMenu.wnd");
- if (mainMenu)
- {
- while (TheShell->top() != mainMenu)
- {
- TheShell->pop();
- }
- }
-}
-
-void ReadyChangedCallback(PEER peer, const char * nick,
- PEERBool ready, void * param)
-{
- if (TheGameSpyGame)
- {
- Int slotNum = TheGameSpyGame->getSlotNum(nick);
- if (slotNum >= 0)
- {
- GameSlot *slot = TheGameSpyGame->getSlot(slotNum);
- if (slot)
- {
- if (ready) {
- slot->setAccept();
- } else {
- slot->unAccept();
- }
-
- if (TheGameSpyGame->amIHost())
- {
- peerUTMRoom(TheGameSpyChat->getPeer(), StagingRoom, "SL/", GameInfoToAsciiString(TheGameSpyGame).str(), PEERFalse);
- }
-
- WOLDisplaySlotList();
- }
- }
- }
-}
-
-void GameStartedCallback(PEER peer, unsigned int IP,
- const char * message, void * param)
-{
- GameSpyStartGame();
-}
-
-void populateLobbyPlayerListbox(void);
-void PlayerJoinedCallback(PEER peer, RoomType roomType,
- const char * nick, void * param)
-{
- if (roomType == GroupRoom && TheGameSpyChat->getCurrentGroupRoomID())
- {
- populateLobbyPlayerListbox();
- }
- if (roomType == StagingRoom && TheGameSpyGame)
- {
- DEBUG_LOG(("StagingRoom, Game OK\n"));
- for (Int i=1; igetSlot(i);
- if (slot && slot->getState() == SLOT_OPEN)
- {
- DEBUG_LOG(("Putting %s in slot %d\n", nick, i));
- UnicodeString uName;
- uName.translate(nick);
- slot->setState(SLOT_PLAYER, uName);
- slot->setColor(-1);
- slot->setPlayerTemplate(-1);
- slot->setStartPos(-1);
- slot->setTeamNumber(-1);
- TheGameSpyGame->resetAccepted();
- Int id;
- UnsignedInt ip;
- PEERBool success = peerGetPlayerInfoNoWait(TheGameSpyChat->getPeer(), nick, &ip, &id);
- DEBUG_LOG(("PlayerJoinedCallback - result from peerGetPlayerInfoNoWait, %d: ip=%d.%d.%d.%d, id=%d\n", success,
- (ip >> 24) & 0xff,
- (ip >> 16) & 0xff,
- (ip >> 8) & 0xff,
- ip & 0xff,
- id));
- success = PEERFalse; // silence compiler warnings in release build
- slot->setIP(ip);
- if (TheGameSpyGame->amIHost())
- {
- peerUTMRoom(TheGameSpyChat->getPeer(), StagingRoom, "SL/", GameInfoToAsciiString(TheGameSpyGame).str(), PEERFalse);
- }
-
- WOLDisplaySlotList();
- break;
- }
- }
- if (i == MAX_SLOTS)
- {
- // we got all the way through without room for him - kick him
- if (TheGameSpyGame->amIHost())
- {
- peerUTMRoom(TheGameSpyChat->getPeer(), StagingRoom, "SL/", GameInfoToAsciiString(TheGameSpyGame).str(), PEERFalse);
- }
- }
- }
-}
-
-void PlayerLeftCallback(PEER peer, RoomType roomType,
- const char * nick, const char * reason,
- void * param)
-{
- if (roomType == GroupRoom && TheGameSpyChat->getCurrentGroupRoomID())
- {
- populateLobbyPlayerListbox();
- }
-
- if (roomType == StagingRoom && TheGameSpyGame)
- {
- Int slotNum = TheGameSpyGame->getSlotNum(nick);
- if (slotNum >= 0)
- {
- GameSlot *slot = TheGameSpyGame->getSlot(slotNum);
- if (slot)
- {
- slot->setState(SLOT_OPEN);
- DEBUG_LOG(("Removing %s from slot %d\n", nick, slotNum));
- if (TheGameSpyGame->amIHost())
- {
- peerUTMRoom(TheGameSpyChat->getPeer(), StagingRoom, "SL/", GameInfoToAsciiString(TheGameSpyGame).str(), PEERFalse);
- }
- TheGameSpyGame->resetAccepted();
-
- WOLDisplaySlotList();
- }
- }
- }
-}
-
-void PlayerChangedNickCallback(PEER peer, RoomType roomType,
- const char * oldNick,
- const char * newNick, void * param)
-{
- if (TheGameSpyChat->getCurrentGroupRoomID())
- {
- populateLobbyPlayerListbox();
- }
-}
-
-void PingCallback(PEER peer, const char * nick, int ping,
- void * param)
-{
- DEBUG_LOG(("PingCallback\n"));
-}
-
-void CrossPingCallback(PEER peer, const char * nick1,
- const char * nick2, int crossPing,
- void * param)
-{
- DEBUG_LOG(("CrossPingCallback\n"));
-}
-
-static void RoomUTMCallback(PEER peer, RoomType roomType, const char * nick,
- const char * command, const char * parameters,
- PEERBool authenticated, void * param)
-{
- DEBUG_LOG(("RoomUTMCallback: %s says %s = [%s]\n", nick, command, parameters));
- if (roomType == StagingRoom && TheGameSpyGame)
- {
- Int slotNum = TheGameSpyGame->getSlotNum(nick);
- if (slotNum == 0 && !TheGameSpyGame->amIHost())
- {
- if (!strcmp(command, "SL"))
- {
- AsciiString options = parameters;
- options.trim();
- ParseAsciiStringToGameInfo(TheGameSpyGame, options.str());
- WOLDisplaySlotList();
- }
- else if (!strcmp(command, "HWS")) // HostWantsStart
- {
- Int slotNum = TheGameSpyGame->getLocalSlotNum();
- GameSlot *slot = TheGameSpyGame->getSlot(slotNum);
- if (slot->isAccepted() == false)
- {
- GameSpyAddText(TheGameText->fetch("GUI:HostWantsToStart"), GSCOLOR_DEFAULT);
- }
- }
- }
- }
-}
-
-static void PlayerUTMCallback(PEER peer, const char * nick,
- const char * command, const char * parameters,
- PEERBool authenticated, void * param)
-{
- DEBUG_LOG(("PlayerUTMCallback: %s says %s = [%s]\n", nick, command, parameters));
- if (TheGameSpyGame)
- {
- Int slotNum = TheGameSpyGame->getSlotNum(nick);
- if (slotNum != 0 && TheGameSpyGame->amIHost())
- {
- if (!strcmp(command, "REQ"))
- {
- AsciiString options = parameters;
- options.trim();
-
-
- Bool change = false;
- Bool shouldUnaccept = false;
- AsciiString key;
- options.nextToken(&key, "=");
- Int val = atoi(options.str()+1);
- UnsignedInt uVal = atoi(options.str()+1);
- DEBUG_LOG(("GameOpt request: key=%s, val=%s from player %d\n", key.str(), options.str(), slotNum));
-
- GameSlot *slot = TheGameSpyGame->getSlot(slotNum);
- if (!slot)
- return;
-
- if (key == "Color")
- {
- if (val >= -1 && val < TheMultiplayerSettings->getNumColors() && val != slot->getColor())
- {
- Bool colorAvailable = TRUE;
- if(val != -1 )
- {
- for(Int i=0; i getSlot(i);
- if(val == checkSlot->getColor() && slot != checkSlot)
- {
- colorAvailable = FALSE;
- break;
- }
- }
- }
- if(colorAvailable)
- slot->setColor(val);
- change = true;
- }
- else
- {
- DEBUG_LOG(("Rejecting invalid color %d\n", val));
- }
- }
- else if (key == "PlayerTemplate")
- {
- if (val >= PLAYERTEMPLATE_MIN && val < ThePlayerTemplateStore->getPlayerTemplateCount() && val != slot->getPlayerTemplate())
- {
- slot->setPlayerTemplate(val);
- change = true;
- shouldUnaccept = true;
- }
- else
- {
- DEBUG_LOG(("Rejecting invalid PlayerTemplate %d\n", val));
- }
- }
- else if (key == "StartPos")
- {
- if (val >= -1 && val < MAX_SLOTS && val != slot->getStartPos())
- {
- slot->setStartPos(val);
- change = true;
- shouldUnaccept = true;
- }
- else
- {
- DEBUG_LOG(("Rejecting invalid startPos %d\n", val));
- }
- }
- else if (key == "Team")
- {
- if (val >= -1 && val < MAX_SLOTS/2 && val != slot->getTeamNumber())
- {
- slot->setTeamNumber(val);
- change = true;
- shouldUnaccept = true;
- }
- else
- {
- DEBUG_LOG(("Rejecting invalid team %d\n", val));
- }
- }
- else if (key == "IP")
- {
- if (uVal != slot->getIP())
- {
- slot->setIP(uVal);
- change = true;
- shouldUnaccept = true;
- }
- else
- {
- DEBUG_LOG(("Rejecting invalid IP %d\n", uVal));
- }
- }
- else if (key == "NAT")
- {
- if ((val >= FirewallHelperClass::FIREWALL_TYPE_SIMPLE) &&
- (val <= FirewallHelperClass::FIREWALL_TYPE_DESTINATION_PORT_DELTA))
- {
- slot->setNATBehavior((FirewallHelperClass::FirewallBehaviorType)val);
- DEBUG_LOG(("Setting NAT behavior to %d for player %d\n", val, slotNum));
- change = true;
- }
- else
- {
- DEBUG_LOG(("Rejecting invalid NAT behavior %d from player %d\n", val, slotNum));
- }
- }
-
- if (change)
- {
- if (shouldUnaccept)
- TheGameSpyGame->resetAccepted();
- peerUTMRoom(TheGameSpyChat->getPeer(), StagingRoom, "SL/", GameInfoToAsciiString(TheGameSpyGame).str(), PEERFalse);
- WOLDisplaySlotList();
- DEBUG_LOG(("Slot value is color=%d, PlayerTemplate=%d, startPos=%d, team=%d, IP=0x%8.8X\n",
- slot->getColor(), slot->getPlayerTemplate(), slot->getStartPos(), slot->getTeamNumber(), slot->getIP()));
- DEBUG_LOG(("Slot list updated to %s\n", GameInfoToAsciiString(TheGameSpyGame).str()));
- }
-
-
- }
- }
- }
-}
-
-void GOABasicCallback(PEER peer, PEERBool playing, char * outbuf,
- int maxlen, void * param)
-{
- _snprintf(outbuf, maxlen, "\\gamename\\c&cgenerals\\gamever\\%s\\location\\%d",
- TheVersion->getAsciiVersion().str(), 0);
- outbuf[maxlen-1] = 0;
- DEBUG_LOG(("GOABasicCallback: [%s]\n", outbuf));
- TheGameSpyGame->gotGOACall();
-}
-
-void GOAInfoCallback(PEER peer, PEERBool playing, char * outbuf,
- int maxlen, void * param)
-{
- _snprintf(outbuf, maxlen, "\\hostname\\%s\\hostport\\%d\\mapname\\%s\\gametype\\%s\\numplayers\\%d\\maxplayers\\%d\\gamemode\\%s",
- TheGameSpyChat->getLoginName().str(), 0, TheGameSpyGame->getMap().str(), "battle", TheGameSpyGame->getNumPlayers(), TheGameSpyGame->getMaxPlayers(), "wait");
- outbuf[maxlen-1] = 0;
- DEBUG_LOG(("GOAInfoCallback: [%s]\n", outbuf));
- TheGameSpyGame->gotGOACall();
-}
-
-void GOARulesCallback(PEER peer, PEERBool playing, char * outbuf,
- int maxlen, void * param)
-{
- _snprintf(outbuf, maxlen, "\\password\\0\\seed\\%d",
- TheGameSpyGame->getSeed());
- outbuf[maxlen-1] = 0;
- DEBUG_LOG(("GOARulesCallback: [%s]\n", outbuf));
- TheGameSpyGame->gotGOACall();
-}
-
-void GOAPlayersCallback(PEER peer, PEERBool playing, char * outbuf,
- int maxlen, void * param)
-{
- AsciiString buf, tmp;
- for (Int i=0; igetSlot(i);
- AsciiString name;
- switch (slot->getState())
- {
- case SLOT_OPEN:
- name = "O";
- break;
- case SLOT_CLOSED:
- name = "X";
- break;
- case SLOT_EASY_AI:
- name = "CE";
- break;
- case SLOT_MED_AI:
- name = "CM";
- break;
- case SLOT_BRUTAL_AI:
- name = "CB";
- break;
- case SLOT_PLAYER:
- {
- AsciiString tmp;
- tmp.translate(slot->getName());
- name.format("H%s", tmp.str());
- }
- break;
- default:
- name = "?";
- break;
- }
- tmp.format("\\player_%d\\%s\\color_%d\\%d\\faction_%d\\%d\\team_%d\\%d\\pos_%d\\%d",
- i, name.str(),
- i, slot->getColor(),
- i, slot->getPlayerTemplate(),
- i, slot->getTeamNumber(),
- i, slot->getStartPos());
- buf.concat(tmp);
- }
- _snprintf(outbuf, maxlen, buf.str());
- outbuf[maxlen-1] = 0;
- DEBUG_LOG(("GOAPlayersCallback: [%s]\n", outbuf));
- TheGameSpyGame->gotGOACall();
-}
-
-void JoinRoomCallback(PEER peer, PEERBool success, PEERJoinResult result, RoomType roomType, void *param)
-{
- DEBUG_LOG(("JoinRoomCallback: success==%d, result==%d\n", success, result));
- switch (roomType)
- {
- case GroupRoom:
- {
- ((GameSpyChat *)TheGameSpyChat)->finishJoiningGroupRoom();
- if (success)
- {
- // update our internal group room ID
- TheGameSpyChat->setCurrentGroupRoomID((Int)param);
-
- // see if we need to change screens
- WindowLayout *layout = TheShell->top();
- AsciiString windowFile = layout->getFilename();
- DEBUG_LOG(("Joined group room, active screen was %s\n", windowFile.str()));
- if (windowFile.compareNoCase("Menus/WOLCustomLobby.wnd") == 0)
- {
- // already on the right screen - just refresh it
- //GroupRoomJoinLobbyRefresh();
- }
- else
- {
- // change to the right screen
- TheShell->pop();
- TheShell->push("Menus/WOLCustomLobby.wnd");
- }
- }
- else
- {
- // failed to join lobby - bail to welcome screen
- WindowLayout *layout = TheShell->top();
- AsciiString windowFile = layout->getFilename();
- DEBUG_LOG(("Joined group room, active screen was %s\n", windowFile.str()));
- if (windowFile.compareNoCase("Menus/WOLWelcomeMenu.wnd") != 0)
- {
- TheShell->pop();
- TheShell->push("Menus/WOLWelcomeMenu.wnd");
- }
- GSMessageBoxOk(UnicodeString(L"Oops"), UnicodeString(L"Unable to join group room"), NULL);
- }
-
- // Update buddy location
- if (TheGameSpyChat->getUsingProfile())
- {
- if (TheGameSpyChat->getCurrentGroupRoomID())
- {
- AsciiString s;
- s.format("c&cgenerals://0.0.0.0:0/%d", TheGameSpyChat->getCurrentGroupRoomID());
- gpSetStatus(TheGPConnection, GP_CHATTING, "Chatting", s.str());
- }
- else
- {
- gpSetStatus(TheGPConnection, GP_ONLINE, "Online", "");
- }
- }
- }
- break;
- case StagingRoom:
- {
- ((GameSpyChat *)TheGameSpyChat)->finishJoiningStagingRoom();
- if (success)
- {
- DEBUG_LOG(("JoinRoomCallback - Joined staging room\n"));
- GServer server = (GServer)param;
-
- // leave any chat channels
- TheGameSpyChat->leaveRoom(GroupRoom);
- TheGameSpyChat->setCurrentGroupRoomID(0);
-
- // set up game info
- TheGameSpyGame->enterGame();
- TheGameSpyGame->setServer(server);
- GameSlot *slot = TheGameSpyGame->getSlot(0);
- AsciiString options, hostName;
- hostName = ServerGetPlayerStringValue(server, 0, "player", "");
- UnicodeString uHostName;
- uHostName.translate(hostName.str() + 1); // go past the 'H'
- slot->setState(SLOT_PLAYER, uHostName);
- UnsignedInt localIP = peerGetLocalIP(TheGameSpyChat->getPeer());
- GetLocalChatConnectionAddress("peerchat.gamespy.com", 6667, localIP);
- localIP = ntohl(localIP); // The IP returned from GetLocalChatConnectionAddress is in network byte order.
- options.format("IP=%d", localIP);
- peerUTMPlayer(TheGameSpyChat->getPeer(), hostName.str(), "REQ/", options.str(), PEERFalse);
- options.format("NAT=%d", TheFirewallHelper->getFirewallBehavior());
- peerUTMPlayer(TheGameSpyChat->getPeer(), hostName.str(), "REQ/", options.str(), PEERFalse);
-
- // refresh the map cache
- TheMapCache->updateCache();
-
- // switch screens
- TheShell->pop();
- TheShell->push("Menus/GameSpyGameOptionsMenu.wnd");
- }
- else
- {
- // let the user know
- GSMessageBoxOk(UnicodeString(L"Oops"), UnicodeString(L"Unable to join game"), NULL);
- DEBUG_LOG(("JoinRoomCallback - Failed to join staging room.\n"));
- }
-
- // Update buddy location
- if (TheGameSpyChat->getUsingProfile())
- {
- if (TheGameSpyChat->getCurrentGroupRoomID())
- {
- AsciiString s;
- s.format("c&cgenerals://0.0.0.0:0/%d", TheGameSpyChat->getCurrentGroupRoomID());
- gpSetStatus(TheGPConnection, GP_CHATTING, "Chatting", s.str());
- }
- else
- {
- gpSetStatus(TheGPConnection, GP_ONLINE, "Online", "");
- }
- }
- break;
- }
- }
-
- //*didJoin = (success == PEERJoinSuccess || success == PEERTrue);
-}
-
-void createRoomCallback(PEER peer, PEERBool success, PEERJoinResult result, RoomType roomType, void *param)
-{
- DEBUG_LOG(("CreateRoomCallback: success==%d, result==%d\n", success, result));
-
- if (roomType != StagingRoom)
- {
- DEBUG_CRASH(("Non-staging room create!"));
- return;
- }
-
- ((GameSpyChat *)TheGameSpyChat)->finishJoiningStagingRoom();
-
- Int oldGroupID = (Int)param;
-
- if (success)
- {
- // set up the game info
- UnsignedInt localIP = peerGetLocalIP(TheGameSpyChat->getPeer());
- DEBUG_LOG(("createRoomCallback - peerGetLocalIP returned %d.%d.%d.%d as the local IP\n",
- localIP >> 24, (localIP >> 16) & 0xff, (localIP >> 8) & 0xff, localIP & 0xff));
-// GetLocalChatConnectionAddress("peerchat.gamespy.com", 6667, localIP);
-// DEBUG_LOG(("createRoomCallback - GetLocalChatConnectionAddress returned %d.%d.%d.%d as the local IP\n",
-// localIP >> 24, (localIP >> 16) & 0xff, (localIP >> 8) & 0xff, localIP & 0xff));
- localIP = ntohl(localIP); // The IP returned from GetLocalChatConnectionAddress is in network byte order.
- TheGameSpyGame->setLocalIP(localIP);
-
- UnicodeString name;
- name.translate(TheGameSpyChat->getLoginName());
- TheGameSpyGame->enterGame();
-// TheGameSpyGame->setSeed(GameClientRandomValue(0, INT_MAX - 1));
- TheGameSpyGame->setSeed(GetTickCount());
- GameSlot newSlot;
- newSlot.setState(SLOT_PLAYER, name);
- newSlot.setIP(localIP);
- TheGameSpyGame->setSlot(0,newSlot);
-
- TheMapCache->updateCache();
-
- TheGameSpyGame->setMap(TheGlobalData->m_mapName);
- AsciiString asciiMap;
- asciiMap = TheGlobalData->m_mapName;
-
- asciiMap.toLower();
- std::map::iterator it = TheMapCache->find(asciiMap);
- if (it != TheMapCache->end())
- {
- TheGameSpyGame->getSlot(0)->setMapAvailability(true);
- TheGameSpyGame->setMapCRC( it->second.m_CRC );
- TheGameSpyGame->setMapSize( it->second.m_filesize );
-
- TheGameSpyGame->adjustSlotsForMap(); // BGC- adjust the slots for the new map.
- }
-
-
- // change to the proper screen
- TheShell->pop();
- TheShell->push("Menus/GameSpyGameOptionsMenu.wnd");
- }
- else
- {
- // join the lobby again
- TheGameSpyChat->joinGroupRoom(oldGroupID);
- GSMessageBoxOk(UnicodeString(L"Oops"), UnicodeString(L"Unable to create game"), NULL);
- }
-
- // Update buddy location
- if (TheGameSpyChat->getUsingProfile())
- {
- if (TheGameSpyChat->getCurrentGroupRoomID())
- {
- AsciiString s;
- s.format("c&cgenerals://0.0.0.0:0/%d", TheGameSpyChat->getCurrentGroupRoomID());
- gpSetStatus(TheGPConnection, GP_CHATTING, "Chatting", s.str());
- }
- else
- {
- gpSetStatus(TheGPConnection, GP_ONLINE, "Online", "");
- }
- }
-}
-
-// Gets called once for each group room when listing group rooms.
-// After this has been called for each group room, it will be
-// called one more time with groupID==0 and name==NULL.
-/////////////////////////////////////////////////////////////////
-void ListGroupRoomsCallback(PEER peer, PEERBool success,
- int groupID, GServer server,
- const char * name, int numWaiting,
- int maxWaiting, int numGames,
- int numPlaying, void * param)
-{
- DEBUG_LOG(("ListGroupRoomsCallback\n"));
- if (success)
- {
- if (groupID)
- {
- GroupRoomMap *grMap = TheGameSpyChat->getGroupRooms();
- (*grMap)[groupID].m_name = name;
- (*grMap)[groupID].m_numWaiting = numWaiting;
- (*grMap)[groupID].m_maxWaiting = maxWaiting;
- (*grMap)[groupID].m_numGames = numGames;
- (*grMap)[groupID].m_numPlaying = numPlaying;
- (*grMap)[groupID].m_groupID = groupID;
- }
- else
- {
- // we've got the complete list.
- UpdateGroupRoomList();
- }
- }
-}
-
-// Called when peerConnect completes.
-static void connectCallback(PEER peer, PEERBool success, void * param)
-{
- ((GameSpyChat *)TheGameSpyChat)->_connectCallback(peer, success, param);
-}
-
-static void nickErrorCallback(PEER peer, int type, const char * nick, void * param)
-{
- ((GameSpyChat *)TheGameSpyChat)->_nickErrorCallback(peer, type, nick, param);
-}
-
-static void GPConnectCallback(GPConnection * pconnection, GPConnectResponseArg * arg, void * param)
-{
- ((GameSpyChat *)TheGameSpyChat)->_GPConnectCallback(pconnection, arg, param);
-}
-
-static void GPReconnectCallback(GPConnection * pconnection, GPConnectResponseArg * arg, void * param)
-{
- ((GameSpyChat *)TheGameSpyChat)->_GPReconnectCallback(pconnection, arg, param);
-}
-
-void GameSpyChat::_connectCallback(PEER peer, PEERBool success, void * param)
-{
- m_loginTimeout = 0;
-
- if (!success) {
- GSMessageBoxOk(UnicodeString(L"Error connecting"), UnicodeString(L"Failed to connect"), NULL);
- DEBUG_LOG(("GameSpyChat::_connectCallback - failed to connect.\n"));
- }
-
- if(!success)
- {
- peerShutdown(m_peer);
- m_peer = NULL;
- gpDisconnect(TheGPConnection);
- gpDestroy(TheGPConnection);
-
- // Enable controls again
- //EnableLoginControls(TRUE);
- return;
- }
-
- DEBUG_LOG(("Connected as profile %d (%s)\n", m_profileID, m_loginName.str()));
-
- TheGameSpyGame = NEW GameSpyGameInfo;
-
- // Enable controls again
- //EnableLoginControls(TRUE);
-
- // the readFromServer() call will set the screen
- if (m_profileID)
- {
- TheGameSpyPlayerInfo->readFromServer();
- }
-
- TheScriptEngine->signalUIInteract("GameSpyLogin");
-
- TheShell->popImmediate();
- TheShell->push("Menus/WOLWelcomeMenu.wnd");
-
- clearGroupRoomList();
- peerListGroupRooms(m_peer, ListGroupRoomsCallback, NULL, PEERFalse);
-}
-
-// Called if there's an error with the nick.
-void GameSpyChat::_nickErrorCallback(PEER peer, int type, const char * nick, void * param)
-{
- // Let the user know.
- /////////////////////
- if(type == PEER_IN_USE)
- {
- AsciiString nickStr = nick;
- AsciiString origName, appendedVal;
- nickStr.nextToken(&origName, "{}");
- nickStr.nextToken(&appendedVal, "{}");
- Int intVal = 1;
- if (!appendedVal.isEmpty())
- {
- intVal = atoi(appendedVal.str()) + 1;
- }
- DEBUG_LOG(("Nickname taken: origName=%s, tries=%d\n", origName.str(), intVal));
-
- if (intVal < 10)
- {
- nickStr.format("%s{%d}", origName.str(), intVal);
- // Retry the connect with a similar nick.
- DEBUG_LOG(("GameSpyChat::_nickErrorCallback - nick was taken, setting to %s\n", nickStr.str()));
- m_loginName = nickStr;
- peerRetryWithNick(peer, nickStr.str());
- }
- else
- {
- GSMessageBoxOk(UnicodeString(L"Error connecting"), UnicodeString(L"That nickname is already taken; please choose another one."), NULL);
- // Cancel the connect.
- peerRetryWithNick(peer, NULL);
-
- // Enable controls again
- //EnableLoginControls(TRUE);
- m_loginTimeout = 0;
- }
- }
- else
- {
- GSMessageBoxOk(UnicodeString(L"Error connecting"), UnicodeString(L"That nickname contains at least 1 invalid character, please choose another one."), NULL);
- // Cancel the connect.
- peerRetryWithNick(peer, NULL);
-
- // Enable controls again
- //EnableLoginControls(TRUE);
- m_loginTimeout = 0;
- }
-}
-
-void GameSpyChat::_GPConnectCallback(GPConnection * pconnection, GPConnectResponseArg * arg, void * param)
-{
- DEBUG_LOG(("GPConnectCallback:\n"));
- GPResult *res = (GPResult *)param;
- *res = arg->result;
-
- setProfileID(arg->profile);
-
- if (*res != GP_NO_ERROR)
- {
- // couldn't connect. bummer.
- GSMessageBoxOk(UnicodeString(L"Error connecting"), UnicodeString(L"Error connecting to buddy server"), NULL);
- gpDisconnect(TheGPConnection);
- gpDestroy(TheGPConnection);
- m_loginTimeout = 0;
- return;
- }
-
- // Connect to chat.
- ///////////////////
- peerConnect(m_peer, m_loginName.str(), m_profileID, nickErrorCallback, connectCallback, NULL, PEERFalse);
-}
-
-static Bool inGPReconnect = false;
-void GameSpyChat::_GPReconnectCallback(GPConnection * pconnection, GPConnectResponseArg * arg, void * param)
-{
- inGPReconnect = false;
- DEBUG_LOG(("GPConnectCallback:\n"));
-
- setProfileID(arg->profile);
-
- if (arg->result != GP_NO_ERROR)
- {
- // couldn't connect. bummer.
- GSMessageBoxOk(UnicodeString(L"Error connecting"), UnicodeString(L"Error connecting to buddy server"), NULL);
- gpDisconnect(TheGPConnection);
- gpDestroy(TheGPConnection);
- return;
- }
- else
- {
- // yay! we're back in!
- GSMessageBoxOk(UnicodeString(L"Connected!"), UnicodeString(L"Reonnected to buddy server"), NULL);
- }
-}
-
-void GameSpyChat::loginProfile(AsciiString loginName, AsciiString password, AsciiString email)
-{
- // Connect to GP.
- ///////////////////
- m_profileID = 0;
- gpInitialize(TheGPConnection, 0);
- gpSetCallback(TheGPConnection, GP_ERROR, (GPCallback)GPErrorCallback, NULL);
- gpSetCallback(TheGPConnection, GP_RECV_BUDDY_REQUEST, (GPCallback)GPRecvBuddyRequestCallback, NULL);
- gpSetCallback(TheGPConnection, GP_RECV_BUDDY_MESSAGE, (GPCallback)GPRecvBuddyMessageCallback, NULL);
- gpSetCallback(TheGPConnection, GP_RECV_BUDDY_STATUS, (GPCallback)GPRecvBuddyStatusCallback, NULL);
-
- GPResult res = GP_PARAMETER_ERROR;
- m_loginName = loginName;
- DEBUG_LOG(("GameSpyChat::loginProfile - m_loginName set to %s\n", m_loginName.str()));
- m_password = password;
- m_email = email;
- gpConnect(TheGPConnection, loginName.str(), email.str(), password.str(), GP_FIREWALL, GP_NON_BLOCKING, (GPCallback)GPConnectCallback, &res);
- /*
- if (res != GP_NO_ERROR)
- {
- // couldn't connect. bummer.
- GSMessageBoxOk(UnicodeString(L"Error connecting"), UnicodeString(L"Error connecting to buddy server"), NULL);
- gpDisconnect(TheGPConnection);
- gpDestroy(TheGPConnection);
- loginTimeout = 0;
- return;
- }
-
- // Connect to chat.
- ///////////////////
- GameSpyLocalNickname = loginName;
- peerConnect(TheGameSpyChat->getPeer(), loginName.str(), GameSpyLocalProfile, nickErrorCallback, connectCallback, NULL, PEERFalse);
- */
-}
-
-void GameSpyChat::reconnectProfile( void )
-{
- if (inGPReconnect)
- return;
-
- inGPReconnect = true;
-
- gpInitialize(TheGPConnection, 0);
- gpSetCallback(TheGPConnection, GP_ERROR, (GPCallback)GPErrorCallback, NULL);
- gpSetCallback(TheGPConnection, GP_RECV_BUDDY_REQUEST, (GPCallback)GPRecvBuddyRequestCallback, NULL);
- gpSetCallback(TheGPConnection, GP_RECV_BUDDY_MESSAGE, (GPCallback)GPRecvBuddyMessageCallback, NULL);
- gpSetCallback(TheGPConnection, GP_RECV_BUDDY_STATUS, (GPCallback)GPRecvBuddyStatusCallback, NULL);
-
- gpConnect(TheGPConnection, m_loginName.str(), m_email.str(), m_password.str(), GP_FIREWALL, GP_NON_BLOCKING, (GPCallback)GPReconnectCallback, NULL);
-}
-
-void GameSpyChat::loginQuick(AsciiString login)
-{
- m_profileID = 0; // no buddy stuff
-
- // Connect to chat.
- ///////////////////
- m_loginName = login;
- DEBUG_LOG(("GameSpyChat::loginQuick - setting login to %s\n", m_loginName));
- peerConnect(m_peer, login.str(), 0, nickErrorCallback, connectCallback, NULL, PEERFalse);
-}
-
-void GameSpyChat::login(AsciiString loginName, AsciiString password, AsciiString email)
-{
- MutexClass::LockClass m(TheGameSpyMutex);
- if ( ISMAINTHREAD )
- {
- thread.queueLogin(loginName, password, email);
- return;
- }
-
- // Setup the callbacks.
- ///////////////////////
- PEERCallbacks callbacks;
- memset(&callbacks, 0, sizeof(PEERCallbacks));
- callbacks.disconnected = DisconnectedCallback;
- callbacks.readyChanged = ReadyChangedCallback;
- callbacks.roomMessage = RoomMessageCallback;
- callbacks.playerMessage = PlayerMessageCallback;
- callbacks.gameStarted = GameStartedCallback;
- callbacks.playerJoined = PlayerJoinedCallback;
- callbacks.playerLeft = PlayerLeftCallback;
- callbacks.playerChangedNick = PlayerChangedNickCallback;
- callbacks.ping = PingCallback;
- callbacks.crossPing = CrossPingCallback;
- callbacks.roomUTM = RoomUTMCallback;
- callbacks.playerUTM = PlayerUTMCallback;
- callbacks.GOABasic = GOABasicCallback;
- callbacks.GOAInfo = GOAInfoCallback;
- callbacks.GOARules = GOARulesCallback;
- callbacks.GOAPlayers = GOAPlayersCallback;
- //callbacks.globalKeyChanged = GlobalKeyChanged;
- callbacks.param = NULL;
-
- // Init peer.
- /////////////
- m_peer = peerInitialize(&callbacks);
- if(!m_peer)
- {
- GSMessageBoxOk(UnicodeString(L"No Peer"), UnicodeString(L"No Peer"), NULL);
- return;
- }
-
- // Setup which rooms to do pings and cross-pings in.
- ////////////////////////////////////////////////////
- PEERBool pingRooms[NumRooms];
- PEERBool crossPingRooms[NumRooms];
- pingRooms[TitleRoom] = PEERTrue;
- pingRooms[GroupRoom] = PEERTrue;
- pingRooms[StagingRoom] = PEERFalse;
- crossPingRooms[TitleRoom] = PEERFalse;
- crossPingRooms[GroupRoom] = PEERFalse;
- crossPingRooms[StagingRoom] = PEERTrue;
-
- // Set the title.
- /////////////////
- if(!peerSetTitle(m_peer, "gmtest", "HA6zkS", "gmtest", "HA6zkS", 15, pingRooms, crossPingRooms))
- {
- GSMessageBoxOk(UnicodeString(L"Error setting title"), UnicodeString(L"Error setting title"), NULL);
- peerShutdown(m_peer);
- m_peer = NULL;
- return;
- }
-
- //EnableLoginControls( FALSE );
- m_loginTimeout = timeGetTime() + m_loginTimeoutPeriod;
- if (!loginName.isEmpty() && !email.isEmpty() && !password.isEmpty())
- {
- m_usingProfiles = true;
- loginProfile(loginName, password, email);
- }
- else
- {
- m_usingProfiles = false;
- loginQuick(loginName);
- }
-}
diff --git a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Chat.cpp b/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Chat.cpp
deleted file mode 100644
index 69e7b659790..00000000000
--- a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Chat.cpp
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: Chat.cpp //////////////////////////////////////////////////////
-// Generals GameSpy chat-related code
-// Author: Matthew D. Campbell, July 2002
-
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/AudioEventRTS.h"
-#include "Common/INI.h"
-#include "GameClient/GameText.h"
-#include "GameClient/GadgetListBox.h"
-#include "GameClient/LanguageFilter.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameNetwork/GameSpy/PeerDefsImplementation.h"
-#include "GameNetwork/GameSpy/PeerThread.h"
-#include "GameClient/InGameUI.h"
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-
-#define OFFSET(x) (sizeof(Int) * (x))
-static const FieldParse GameSpyColorFieldParse[] =
-{
-
- { "Default", INI::parseColorInt, NULL, OFFSET(GSCOLOR_DEFAULT) },
- { "CurrentRoom", INI::parseColorInt, NULL, OFFSET(GSCOLOR_CURRENTROOM) },
- { "ChatRoom", INI::parseColorInt, NULL, OFFSET(GSCOLOR_ROOM) },
- { "Game", INI::parseColorInt, NULL, OFFSET(GSCOLOR_GAME) },
- { "GameFull", INI::parseColorInt, NULL, OFFSET(GSCOLOR_GAME_FULL) },
- { "GameCRCMismatch", INI::parseColorInt, NULL, OFFSET(GSCOLOR_GAME_CRCMISMATCH) },
- { "PlayerNormal", INI::parseColorInt, NULL, OFFSET(GSCOLOR_PLAYER_NORMAL) },
- { "PlayerOwner", INI::parseColorInt, NULL, OFFSET(GSCOLOR_PLAYER_OWNER) },
- { "PlayerBuddy", INI::parseColorInt, NULL, OFFSET(GSCOLOR_PLAYER_BUDDY) },
- { "PlayerSelf", INI::parseColorInt, NULL, OFFSET(GSCOLOR_PLAYER_SELF) },
- { "PlayerIgnored", INI::parseColorInt, NULL, OFFSET(GSCOLOR_PLAYER_IGNORED) },
- { "ChatNormal", INI::parseColorInt, NULL, OFFSET(GSCOLOR_CHAT_NORMAL) },
- { "ChatEmote", INI::parseColorInt, NULL, OFFSET(GSCOLOR_CHAT_EMOTE) },
- { "ChatOwner", INI::parseColorInt, NULL, OFFSET(GSCOLOR_CHAT_OWNER) },
- { "ChatOwnerEmote", INI::parseColorInt, NULL, OFFSET(GSCOLOR_CHAT_OWNER_EMOTE) },
- { "ChatPriv", INI::parseColorInt, NULL, OFFSET(GSCOLOR_CHAT_PRIVATE) },
- { "ChatPrivEmote", INI::parseColorInt, NULL, OFFSET(GSCOLOR_CHAT_PRIVATE_EMOTE) },
- { "ChatPrivOwner", INI::parseColorInt, NULL, OFFSET(GSCOLOR_CHAT_PRIVATE_OWNER) },
- { "ChatPrivOwnerEmote", INI::parseColorInt, NULL, OFFSET(GSCOLOR_CHAT_PRIVATE_OWNER_EMOTE) },
- { "ChatBuddy", INI::parseColorInt, NULL, OFFSET(GSCOLOR_CHAT_BUDDY) },
- { "ChatSelf", INI::parseColorInt, NULL, OFFSET(GSCOLOR_CHAT_SELF) },
- { "AcceptTrue", INI::parseColorInt, NULL, OFFSET(GSCOLOR_ACCEPT_TRUE) },
- { "AcceptFalse", INI::parseColorInt, NULL, OFFSET(GSCOLOR_ACCEPT_FALSE) },
- { "MapSelected", INI::parseColorInt, NULL, OFFSET(GSCOLOR_MAP_SELECTED) },
- { "MapUnselected", INI::parseColorInt, NULL, OFFSET(GSCOLOR_MAP_UNSELECTED) },
- { "MOTD", INI::parseColorInt, NULL, OFFSET(GSCOLOR_MOTD) },
- { "MOTDHeading", INI::parseColorInt, NULL, OFFSET(GSCOLOR_MOTD_HEADING) },
-
- { NULL, NULL, NULL, 0 } // keep this last
-
-};
-
-void INI::parseOnlineChatColorDefinition( INI* ini )
-{
- // parse the ini definition
- ini->initFromINI( GameSpyColor, GameSpyColorFieldParse );
-}
-
-
-Color GameSpyColor[GSCOLOR_MAX] =
-{
- GameMakeColor(255,255,255,255), // GSCOLOR_DEFAULT
- GameMakeColor(255,255, 0,255), // GSCOLOR_CURRENTROOM
- GameMakeColor(255,255,255,255), // GSCOLOR_ROOM
- GameMakeColor(128,128,0,255), // GSCOLOR_GAME
- GameMakeColor(128,128,128,255), // GSCOLOR_GAME_FULL
- GameMakeColor(128,128,128,255), // GSCOLOR_GAME_CRCMISMATCH
- GameMakeColor(255, 0, 0,255), // GSCOLOR_PLAYER_NORMAL
- GameMakeColor(255, 0,255,255), // GSCOLOR_PLAYER_OWNER
- GameMakeColor(255, 0,128,255), // GSCOLOR_PLAYER_BUDDY
- GameMakeColor(255, 0, 0,255), // GSCOLOR_PLAYER_SELF
- GameMakeColor(128,128,128,255), // GSCOLOR_PLAYER_IGNORED
- GameMakeColor(255,0,0,255), // GSCOLOR_CHAT_NORMAL
- GameMakeColor(255,128,0,255), // GSCOLOR_CHAT_EMOTE,
- GameMakeColor(255,255,0,255), // GSCOLOR_CHAT_OWNER,
- GameMakeColor(128,255,0,255), // GSCOLOR_CHAT_OWNER_EMOTE,
- GameMakeColor(0,0,255,255), // GSCOLOR_CHAT_PRIVATE,
- GameMakeColor(0,255,255,255), // GSCOLOR_CHAT_PRIVATE_EMOTE,
- GameMakeColor(255,0,255,255), // GSCOLOR_CHAT_PRIVATE_OWNER,
- GameMakeColor(255,128,255,255), // GSCOLOR_CHAT_PRIVATE_OWNER_EMOTE,
- GameMakeColor(255, 0,255,255), // GSCOLOR_CHAT_BUDDY,
- GameMakeColor(255, 0,128,255), // GSCOLOR_CHAT_SELF,
- GameMakeColor( 0,255, 0,255), // GSCOLOR_ACCEPT_TRUE,
- GameMakeColor(255, 0, 0,255), // GSCOLOR_ACCEPT_FALSE,
- GameMakeColor(255,255, 0,255), // GSCOLOR_MAP_SELECTED,
- GameMakeColor(255,255,255,255), // GSCOLOR_MAP_UNSELECTED,
- GameMakeColor(255,255,255,255), // GSCOLOR_MOTD,
- GameMakeColor(255,255, 0,255), // GSCOLOR_MOTD_HEADING,
-};
-
-Bool GameSpyInfo::sendChat( UnicodeString message, Bool isAction, GameWindow *playerListbox )
-{
- RoomType roomType = StagingRoom;
- if (getCurrentGroupRoom())
- roomType = GroupRoom;
-
- PeerRequest req;
- req.text = message.str();
-
- message.trim();
- // Echo the user's input to the chat window
- if (!message.isEmpty())
- {
- if (!playerListbox)
- {
- // Public message
- req.message.isAction = isAction;
- req.peerRequestType = PeerRequest::PEERREQUEST_MESSAGEROOM;
- TheGameSpyPeerMessageQueue->addRequest(req);
- return false;
- }
-
- // Get the selections (is this a private message?)
- Int maxSel = GadgetListBoxGetListLength(playerListbox);
- Int *selections;
- GadgetListBoxGetSelected(playerListbox, (Int *)&selections);
-
- if (selections[0] == -1)
- {
- // Public message
- req.message.isAction = isAction;
- req.peerRequestType = PeerRequest::PEERREQUEST_MESSAGEROOM;
- TheGameSpyPeerMessageQueue->addRequest(req);
- return false;
- }
- else
- {
- // Private message
-
- // Construct a list
- AsciiString names = AsciiString::TheEmptyString;
- AsciiString tmp = AsciiString::TheEmptyString;
- AsciiString aStr; // AsciiString buf for translating Unicode entries
- names.format("%s", TheGameSpyInfo->getLocalName().str());
- for (int i=0; igetLocalName()))
- {
- tmp.format(",%s", aStr.str());
- names.concat(tmp);
- }
- }
- else
- {
- break;
- }
- }
-
- if (!names.isEmpty())
- {
- req.nick = names.str();
- req.message.isAction = isAction;
- req.peerRequestType = PeerRequest::PEERREQUEST_MESSAGEPLAYER;
- TheGameSpyPeerMessageQueue->addRequest(req);
- }
-
- return true;
- }
- }
- return false;
-}
-
-void GameSpyInfo::addChat( AsciiString nick, Int profileID, UnicodeString msg, Bool isPublic, Bool isAction, GameWindow *win )
-{
- PlayerInfoMap::iterator it = getPlayerInfoMap()->find(nick);
- if (it != getPlayerInfoMap()->end())
- {
- addChat( it->second, msg, isPublic, isAction, win );
- }
- else
- {
- }
-}
-
-void GameSpyInfo::addChat( PlayerInfo p, UnicodeString msg, Bool isPublic, Bool isAction, GameWindow *win )
-{
- Int style;
- if(isSavedIgnored(p.m_profileID) || isIgnored(p.m_name))
- return;
-
- Bool isOwner = p.m_flags & PEER_FLAG_OP;
- Bool isBuddy = getBuddyMap()->find(p.m_profileID) != getBuddyMap()->end();
-
- Bool isMe = p.m_name.compare(TheGameSpyInfo->getLocalName()) == 0;
-
- if(!isMe)
- {
- if(m_disallowAsainText)
- {
- const WideChar *buff = msg.str();
- Int length = msg.getLength();
- for(Int i = 0; i < length; ++i)
- {
- if(buff[i] >= 256)
- return;
- }
- }
- else if(m_disallowNonAsianText)
- {
- const WideChar *buff = msg.str();
- Int length = msg.getLength();
- Bool hasUnicode = FALSE;
- for(Int i = 0; i < length; ++i)
- {
- if(buff[i] >= 256)
- {
- hasUnicode = TRUE;
- break;
- }
- }
- if(!hasUnicode)
- return;
- }
-
- if (!isPublic)
- {
- AudioEventRTS privMsgAudio("GUIMessageReceived");
-
- if( TheAudio )
- {
- TheAudio->addAudioEvent( &privMsgAudio );
- } // end if
- }
- }
-
-
- if (isBuddy)
- {
- style = GSCOLOR_CHAT_BUDDY;
- }
- else if (isPublic && isAction)
- {
- style = (isOwner)?GSCOLOR_CHAT_OWNER_EMOTE:GSCOLOR_CHAT_EMOTE;
- }
- else if (isPublic)
- {
- style = (isOwner)?GSCOLOR_CHAT_OWNER:GSCOLOR_CHAT_NORMAL;
- }
- else if (isAction)
- {
- style = (isOwner)?GSCOLOR_CHAT_PRIVATE_OWNER_EMOTE:GSCOLOR_CHAT_PRIVATE_EMOTE;
- }
- else
- {
- style = (isOwner)?GSCOLOR_CHAT_PRIVATE_OWNER:GSCOLOR_CHAT_PRIVATE;
- }
-
- UnicodeString name;
- name.translate(p.m_name);
-
- // filters language
-// if( TheGlobalData->m_languageFilterPref )
-// {
- TheLanguageFilter->filterLine(msg);
-// }
-
- UnicodeString fullMsg;
- if (isAction)
- {
- fullMsg.format( L"%ls %ls", name.str(), msg.str() );
- }
- else
- {
- fullMsg.format( L"[%ls] %ls", name.str(), msg.str() );
- }
-
- Int index = addText(fullMsg, GameSpyColor[style], win);
- if (index >= 0)
- {
- GadgetListBoxSetItemData(win, (void *)p.m_profileID, index);
- }
-}
-
-Int GameSpyInfo::addText( UnicodeString message, Color c, GameWindow *win )
-{
- if (TheGameSpyGame && TheGameSpyGame->isInGame() && TheGameSpyGame->isGameInProgress())
- {
- static AudioEventRTS messageFromChatSound("GUIMessageReceived");
- TheAudio->addAudioEvent(&messageFromChatSound);
-
- TheInGameUI->message(message);
- }
-
- if (!win)
- {
- // try to pick up a registered text window
- if (m_textWindows.empty())
- return -1;
-
- win = *(m_textWindows.begin());
- }
- Int index = GadgetListBoxAddEntryText(win, message, c, -1, -1);
- GadgetListBoxSetItemData(win, (void *)-1, index);
-
- return index;
-}
-
-void GameSpyInfo::registerTextWindow( GameWindow *win )
-{
- m_textWindows.insert(win);
-}
-
-void GameSpyInfo::unregisterTextWindow( GameWindow *win )
-{
- m_textWindows.erase(win);
-}
-
diff --git a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/GSConfig.cpp b/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/GSConfig.cpp
deleted file mode 100644
index 60be316d5e7..00000000000
--- a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/GSConfig.cpp
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////////////
-// FILE: GSConfig.cpp
-// Author: Matthew D. Campbell, Sept 2002
-// Description: GameSpy online config
-///////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/GameState.h"
-#include "GameClient/MapUtil.h"
-#include "GameNetwork/GameSpy/GSConfig.h"
-#include "GameNetwork/RankPointValue.h"
-
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-GameSpyConfigInterface *TheGameSpyConfig = NULL;
-
-class GameSpyConfig : public GameSpyConfigInterface
-{
-public:
- GameSpyConfig( AsciiString config );
- ~GameSpyConfig() {}
-
- // Pings
- std::list getPingServers(void) { return m_pingServers; }
- Int getNumPingRepetitions(void) { return m_pingReps; }
- Int getPingTimeoutInMs(void) { return m_pingTimeout; }
- virtual Int getPingCutoffGood( void ) { return m_pingCutoffGood; }
- virtual Int getPingCutoffBad( void ) { return m_pingCutoffBad; }
-
- // QM
- std::list getQMMaps(void) { return m_qmMaps; }
- Int getQMBotID(void) { return m_qmBotID; }
- Int getQMChannel(void) { return m_qmChannel; }
- void setQMChannel(Int channel) { m_qmChannel = channel; }
-
- // Player Info
- Int getPointsForRank(Int rank);
- virtual Bool isPlayerVIP(Int id);
-
- virtual Bool getManglerLocation(Int index, AsciiString& host, UnsignedShort& port);
-
- // Ladder / Any other external parsing
- AsciiString getLeftoverConfig(void) { return m_leftoverConfig; }
-
- // NAT Timeouts
- virtual Int getTimeBetweenRetries() { return m_natRetryInterval; }
- virtual Int getMaxManglerRetries() { return m_natMaxManglerRetries; }
- virtual time_t getRetryInterval() { return m_natManglerRetryInterval; }
- virtual time_t getKeepaliveInterval() { return m_natKeepaliveInterval; }
- virtual time_t getPortTimeout() { return m_natPortTimeout; }
- virtual time_t getRoundTimeout() { return m_natRoundTimeout; }
-
- // Custom match
- virtual Bool restrictGamesToLobby() { return m_restrictGamesToLobby; }
-
-protected:
- std::list m_pingServers;
- Int m_pingReps;
- Int m_pingTimeout;
- Int m_pingCutoffGood;
- Int m_pingCutoffBad;
-
- Int m_natRetryInterval;
- Int m_natMaxManglerRetries;
- time_t m_natManglerRetryInterval;
- time_t m_natKeepaliveInterval;
- time_t m_natPortTimeout;
- time_t m_natRoundTimeout;
-
- std::vector m_manglerHosts;
- std::vector m_manglerPorts;
-
- std::list m_qmMaps;
- Int m_qmBotID;
- Int m_qmChannel;
-
- Bool m_restrictGamesToLobby;
-
- std::set m_vip; // VIP people
-
- Int m_rankPoints[MAX_RANKS];
-
- AsciiString m_leftoverConfig;
-};
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-GameSpyConfigInterface* GameSpyConfigInterface::create(AsciiString config)
-{
- return NEW GameSpyConfig(config);
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-class SectionChecker
-{
-public:
- typedef std::list SectionList;
- void addVar(const Bool *var) { m_bools.push_back(var); }
- Bool isInSection();
-protected:
- SectionList m_bools;
-};
-Bool SectionChecker::isInSection() {
- Bool ret = FALSE;
- for (SectionList::const_iterator it = m_bools.begin(); it != m_bools.end(); ++it)
- {
- ret = ret || **it;
- }
- return ret;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-GameSpyConfig::GameSpyConfig( AsciiString config ) :
-m_natRetryInterval(1000),
-m_natMaxManglerRetries(25),
-m_natManglerRetryInterval(300),
-m_natKeepaliveInterval(15000),
-m_natPortTimeout(10000),
-m_natRoundTimeout(10000),
-m_pingReps(1),
-m_pingTimeout(1000),
-m_pingCutoffGood(300),
-m_pingCutoffBad(600),
-m_restrictGamesToLobby(FALSE),
-m_qmBotID(0),
-m_qmChannel(0)
-{
- m_rankPoints[0] = 0;
- m_rankPoints[1] = 5;
- m_rankPoints[2] = 10;
- m_rankPoints[3] = 20;
- m_rankPoints[4] = 50;
- m_rankPoints[5] = 100;
- m_rankPoints[6] = 200;
- m_rankPoints[7] = 500;
- m_rankPoints[8] = 1000;
- m_rankPoints[9] = 2000;
-
- AsciiString line;
- Bool inPingServers = FALSE;
- Bool inPingDuration = FALSE;
- Bool inQMMaps = FALSE;
- Bool inQMBot = FALSE;
- Bool inManglers = FALSE;
- Bool inVIP = FALSE;
- Bool inNAT = FALSE;
- Bool inCustom = FALSE;
-
- SectionChecker sections;
- sections.addVar(&inPingServers);
- sections.addVar(&inPingDuration);
- sections.addVar(&inQMMaps);
- sections.addVar(&inQMBot);
- sections.addVar(&inManglers);
- sections.addVar(&inVIP);
- sections.addVar(&inNAT);
- sections.addVar(&inCustom);
-
- while (config.nextToken(&line, "\n"))
- {
- if (line.getCharAt(line.getLength()-1) == '\r')
- line.removeLastChar(); // there is a trailing '\r'
-
- line.trim();
-
- if (line.isEmpty())
- continue;
-
- if (!sections.isInSection() && line.compare("") == 0)
- {
- inPingServers = TRUE;
- }
- else if (inPingServers && line.compare("") == 0)
- {
- inPingServers = FALSE;
- }
- else if (!sections.isInSection() && line.compare("") == 0)
- {
- inPingDuration = TRUE;
- }
- else if (inPingDuration && line.compare("") == 0)
- {
- inPingDuration = FALSE;
- }
- else if (!sections.isInSection() && line.compare("") == 0)
- {
- inQMMaps = TRUE;
- }
- else if (inQMMaps && line.compare("") == 0)
- {
- inQMMaps = FALSE;
- }
- else if (!sections.isInSection() && line.compare("") == 0)
- {
- inManglers = TRUE;
- }
- else if (inManglers && line.compare("") == 0)
- {
- inManglers = FALSE;
- }
- else if (!sections.isInSection() && line.compare("") == 0)
- {
- inQMBot = TRUE;
- }
- else if (inQMBot && line.compare("") == 0)
- {
- inQMBot = FALSE;
- }
- else if (!sections.isInSection() && line.compare("") == 0)
- {
- inVIP = TRUE;
- }
- else if (inVIP && line.compare("") == 0)
- {
- inVIP = FALSE;
- }
- else if (!sections.isInSection() && line.compare("") == 0)
- {
- inNAT = TRUE;
- }
- else if (inNAT && line.compare("") == 0)
- {
- inNAT = FALSE;
- }
- else if (!sections.isInSection() && line.compare("") == 0)
- {
- inCustom = TRUE;
- }
- else if (inCustom && line.compare("") == 0)
- {
- inCustom = FALSE;
- }
- else if (inVIP)
- {
- line.toLower();
- if (line.getLength())
- {
- Int val = atoi(line.str());
- if (val > 0)
- m_vip.insert(val);
- }
- }
- else if (inPingServers)
- {
- line.toLower();
- m_pingServers.push_back(line);
- }
- else if (inPingDuration)
- {
- line.toLower();
- AsciiString key, val;
- if (line.nextToken(&key, " ="))
- {
- if (key == "reps")
- {
- if (line.nextToken(&val, " ="))
- {
- m_pingReps = atoi(val.str());
- }
- }
- else if (key == "timeout")
- {
- if (line.nextToken(&val, " ="))
- {
- m_pingTimeout = atoi(val.str());
- }
- }
- else if (key == "low")
- {
- if (line.nextToken(&val, " ="))
- {
- m_pingCutoffGood = atoi(val.str());
- }
- }
- else if (key == "med")
- {
- if (line.nextToken(&val, " ="))
- {
- m_pingCutoffBad = atoi(val.str());
- }
- }
- }
- }
- else if (inManglers)
- {
- line.trim();
- line.toLower();
- AsciiString hostStr;
- AsciiString portStr;
- line.nextToken(&hostStr, ":");
- line.nextToken(&portStr, ":\n\r");
- if (hostStr.isNotEmpty() && portStr.isNotEmpty())
- {
- m_manglerHosts.push_back(hostStr);
- m_manglerPorts.push_back(atoi(portStr.str()));
- }
- }
- else if (inQMMaps)
- {
- line.toLower();
- AsciiString mapName;
- mapName.format("%s\\%s\\%s.map", TheMapCache->getMapDir().str(), line.str(), line.str());
- mapName = TheGameState->portableMapPathToRealMapPath(TheGameState->realMapPathToPortableMapPath(mapName));
- mapName.toLower();
-
- // [SKB: Jul 01 2003 @ 6:43pm] :
- // German2 is missing some maps because of content. But, we need the m_qmMaps
- // to contain same number of strings as the Retail version so that the
- // QM Bot thinks that they have the same number of maps.
- #if 1
- m_qmMaps.push_back(mapName);
- #else
- const MapMetaData *md = TheMapCache->findMap(mapName);
- if (md)
- {
- m_qmMaps.push_back(mapName);
- }
- #endif
- }
- else if (inQMBot)
- {
- line.toLower();
- AsciiString key, val;
- if (line.nextToken(&key, " ="))
- {
- if (key == "id")
- {
- if (line.nextToken(&val, " ="))
- {
- m_qmBotID = atoi(val.str());
- }
- }
- }
- }
- else if (inNAT)
- {
- line.toLower();
- AsciiString key, val;
- if (line.nextToken(&key, " ="))
- {
- if (key == "retryinterval")
- {
- if (line.nextToken(&val, " ="))
- {
- m_natRetryInterval = atoi(val.str());
- }
- }
- else if (key == "manglerretries")
- {
- if (line.nextToken(&val, " ="))
- {
- m_natMaxManglerRetries = atoi(val.str());
- }
- }
- else if (key == "manglerinterval")
- {
- if (line.nextToken(&val, " ="))
- {
- m_natManglerRetryInterval = atoi(val.str());
- }
- }
- else if (key == "keepaliveinterval")
- {
- if (line.nextToken(&val, " ="))
- {
- m_natKeepaliveInterval = atoi(val.str());
- }
- }
- else if (key == "porttimeout")
- {
- if (line.nextToken(&val, " ="))
- {
- m_natPortTimeout = atoi(val.str());
- }
- }
- else if (key == "roundtimeout")
- {
- if (line.nextToken(&val, " ="))
- {
- m_natRoundTimeout = atoi(val.str());
- }
- }
- else
- {
- DEBUG_LOG(("Unknown key '%s' = '%s' in NAT block of GameSpy Config\n", key.str(), val.str()));
- }
- }
- else
- {
- DEBUG_LOG(("Key '%s' missing val in NAT block of GameSpy Config\n", key.str()));
- }
- }
- else if (inCustom)
- {
- line.toLower();
- AsciiString key, val;
- if (line.nextToken(&key, " =") && line.nextToken(&val, " ="))
- {
- if (key == "restricted")
- {
- m_restrictGamesToLobby = atoi(val.str());
- }
- else
- {
- DEBUG_LOG(("Unknown key '%s' = '%s' in Custom block of GameSpy Config\n", key.str(), val.str()));
- }
- }
- else
- {
- DEBUG_LOG(("Key '%s' missing val in Custom block of GameSpy Config\n", key.str()));
- }
- }
- else
- {
- m_leftoverConfig.concat(line);
- m_leftoverConfig.concat('\n');
- }
- }
-
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-Int GameSpyConfig::getPointsForRank(Int rank)
-{
- if (rank >= MAX_RANKS) rank = MAX_RANKS-1;
- if (rank < 0) rank = 0;
- return m_rankPoints[rank];
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-Bool GameSpyConfig::getManglerLocation(Int index, AsciiString& host, UnsignedShort& port)
-{
- if (index < 0 || index >= m_manglerHosts.size())
- {
- return FALSE;
- }
-
- host = m_manglerHosts[index];
- port = m_manglerPorts[index];
- return TRUE;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-Bool GameSpyConfig::isPlayerVIP(Int id)
-{
- std::set::const_iterator it = std::find(m_vip.begin(), m_vip.end(), id);
- return it != m_vip.end();
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
diff --git a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/LadderDefs.cpp b/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/LadderDefs.cpp
deleted file mode 100644
index b7635ac0dd8..00000000000
--- a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/LadderDefs.cpp
+++ /dev/null
@@ -1,527 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: LadderDefs.cpp //////////////////////////////////////////////////////
-// Generals ladder code
-// Author: Matthew D. Campbell, August 2002
-
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "GameNetwork/GameSpy/ThreadUtils.h"
-#include "GameNetwork/GameSpy/LadderDefs.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpy/GSConfig.h"
-#include "Common/GameState.h"
-#include "Common/File.h"
-#include "Common/FileSystem.h"
-#include "Common/PlayerTemplate.h"
-#include "GameClient/GameText.h"
-#include "GameClient/MapUtil.h"
-
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-
-LadderList *TheLadderList = NULL;
-
-LadderInfo::LadderInfo()
-{
- playersPerTeam = 1;
- minWins = 0;
- maxWins = 0;
- randomMaps = TRUE;
- randomFactions = TRUE;
- validQM = TRUE;
- validCustom = FALSE;
- port = 0;
- submitReplay = FALSE;
- index = -1;
-}
-
-static LadderInfo *parseLadder(AsciiString raw)
-{
- DEBUG_LOG(("Looking at ladder:\n%s\n", raw.str()));
- LadderInfo *lad = NULL;
- AsciiString line;
- while (raw.nextToken(&line, "\n"))
- {
- if (line.getCharAt(line.getLength()-1) == '\r')
- line.removeLastChar(); // there is a trailing '\r'
-
- line.trim();
-
- if (line.isEmpty())
- continue;
-
- // woohoo! got a line!
- line.trim();
- if ( !lad && line.startsWith("'
- line = line.str() + 7; // the "name = MultiByteToWideCharSingleLine(tokenName.str()).c_str();
- while (lad->name.getLength() > 20)
- lad->name.removeLastChar(); // Per Harvard's request, ladder names are limited to 20 chars
- lad->address = tokenAddr;
- lad->port = atoi(tokenPort.str());
- lad->homepageURL = tokenHomepage;
- }
- else if ( lad && line.startsWith("Name ") )
- {
- lad->name = MultiByteToWideCharSingleLine(line.str() + 5).c_str();
- }
- else if ( lad && line.startsWith("Desc ") )
- {
- lad->description = MultiByteToWideCharSingleLine(line.str() + 5).c_str();
- }
- else if ( lad && line.startsWith("Loc ") )
- {
- lad->location = MultiByteToWideCharSingleLine(line.str() + 4).c_str();
- }
- else if ( lad && line.startsWith("TeamSize ") )
- {
- lad->playersPerTeam = atoi(line.str() + 9);
- }
- else if ( lad && line.startsWith("RandomMaps ") )
- {
- lad->randomMaps = atoi(line.str() + 11);
- }
- else if ( lad && line.startsWith("RandomFactions ") )
- {
- lad->randomFactions = atoi(line.str() + 15);
- }
- else if ( lad && line.startsWith("Faction ") )
- {
- AsciiString faction = line.str() + 8;
- AsciiStringList outStringList;
- ThePlayerTemplateStore->getAllSideStrings(&outStringList);
-
- AsciiStringList::iterator aIt = std::find(outStringList.begin(), outStringList.end(), faction);
- if (aIt != outStringList.end())
- {
- // valid faction - now check for dupes
- aIt = std::find(lad->validFactions.begin(), lad->validFactions.end(), faction);
- if (aIt == lad->validFactions.end())
- {
- lad->validFactions.push_back(faction);
- }
- }
- }
- /*
- else if ( lad && line.startsWith("QM ") )
- {
- lad->validQM = atoi(line.str() + 3);
- }
- else if ( lad && line.startsWith("Custom ") )
- {
- lad->validCustom = atoi(line.str() + 7);
- }
- */
- else if ( lad && line.startsWith("MinWins ") )
- {
- lad->minWins = atoi(line.str() + 8);
- }
- else if ( lad && line.startsWith("MaxWins ") )
- {
- lad->maxWins = atoi(line.str() + 8);
- }
- else if ( lad && line.startsWith("CryptedPass ") )
- {
- lad->cryptedPassword = line.str() + 12;
- }
- else if ( lad && line.compare("") == 0 )
- {
- DEBUG_LOG(("Saw a ladder: name=%ls, addr=%s:%d, players=%dv%d, pass=%s, replay=%d, homepage=%s\n",
- lad->name.str(), lad->address.str(), lad->port, lad->playersPerTeam, lad->playersPerTeam, lad->cryptedPassword.str(),
- lad->submitReplay, lad->homepageURL.str()));
- // end of a ladder
- if (lad->playersPerTeam >= 1 && lad->playersPerTeam <= MAX_SLOTS/2)
- {
- if (lad->validFactions.size() == 0)
- {
- DEBUG_LOG(("No factions specified. Using all.\n"));
- lad->validFactions.push_back("America");
- lad->validFactions.push_back("China");
- lad->validFactions.push_back("GLA");
- }
- else
- {
- AsciiStringList validFactions = lad->validFactions;
- for (AsciiStringListIterator it = validFactions.begin(); it != validFactions.end(); ++it)
- {
- AsciiString faction = *it;
- AsciiString marker;
- marker.format("INI:Faction%s", faction.str());
- DEBUG_LOG(("Faction %s has marker %s corresponding to str %ls\n", faction.str(), marker.str(), TheGameText->fetch(marker).str()));
- }
- }
-
- if (lad->validMaps.size() == 0)
- {
- DEBUG_LOG(("No maps specified. Using all.\n"));
- std::list qmMaps = TheGameSpyConfig->getQMMaps();
- for (std::list::const_iterator it = qmMaps.begin(); it != qmMaps.end(); ++it)
- {
- AsciiString mapName = *it;
-
- // check sizes on the maps before allowing them
- const MapMetaData *md = TheMapCache->findMap(mapName);
- if (md && md->m_numPlayers >= lad->playersPerTeam*2)
- {
- lad->validMaps.push_back(mapName);
- }
- }
- }
- return lad;
- }
- else
- {
- // no maps? don't play on it!
- delete lad;
- lad = NULL;
- return NULL;
- }
- }
- else if ( lad && line.startsWith("Map ") )
- {
- // valid map
- AsciiString mapName = line.str() + 4;
- mapName.trim();
- if (mapName.isNotEmpty())
- {
- mapName.format("%s\\%s\\%s.map", TheMapCache->getMapDir().str(), mapName.str(), mapName.str());
- mapName = TheGameState->portableMapPathToRealMapPath(TheGameState->realMapPathToPortableMapPath(mapName));
- mapName.toLower();
- std::list qmMaps = TheGameSpyConfig->getQMMaps();
- if (std::find(qmMaps.begin(), qmMaps.end(), mapName) != qmMaps.end())
- {
- // check sizes on the maps before allowing them
- const MapMetaData *md = TheMapCache->findMap(mapName);
- if (md && md->m_numPlayers >= lad->playersPerTeam*2)
- lad->validMaps.push_back(mapName);
- }
- }
- }
- else
- {
- // bad ladder - kill it
- delete lad;
- lad = NULL;
- }
- }
-
- if (lad)
- {
- delete lad;
- lad = NULL;
- }
- return NULL;
-}
-
-LadderList::LadderList()
-{
- //Int profile = TheGameSpyInfo->getLocalProfileID();
-
- AsciiString rawMotd = TheGameSpyConfig->getLeftoverConfig();
- AsciiString line;
- Bool inLadders = FALSE;
- Bool inSpecialLadders = FALSE;
- Bool inLadder = FALSE;
- LadderInfo *lad = NULL;
- Int index = 1;
- AsciiString rawLadder;
-
- while (rawMotd.nextToken(&line, "\n"))
- {
- if (line.getCharAt(line.getLength()-1) == '\r')
- line.removeLastChar(); // there is a trailing '\r'
-
- line.trim();
-
- if (line.isEmpty())
- continue;
-
- if (!inLadders && line.compare("") == 0)
- {
- inLadders = TRUE;
- rawLadder.clear();
- }
- else if (inLadders && line.compare("") == 0)
- {
- inLadders = FALSE;
- }
- else if (!inSpecialLadders && line.compare("") == 0)
- {
- inSpecialLadders = TRUE;
- rawLadder.clear();
- }
- else if (inSpecialLadders && line.compare("") == 0)
- {
- inSpecialLadders = FALSE;
- }
- else if (inLadders || inSpecialLadders)
- {
- if (line.startsWith("") == 0 && inLadder)
- {
- inLadder = FALSE;
- rawLadder.concat(line);
- rawLadder.concat('\n');
- if ((lad = parseLadder(rawLadder)) != NULL)
- {
- lad->index = index++;
- if (inLadders)
- {
- DEBUG_LOG(("Adding to standard ladders\n"));
- m_standardLadders.push_back(lad);
- }
- else
- {
- DEBUG_LOG(("Adding to special ladders\n"));
- m_specialLadders.push_back(lad);
- }
- }
- rawLadder.clear();
- }
- else if (inLadder)
- {
- rawLadder.concat(line);
- rawLadder.concat('\n');
- }
- }
- }
-
- // look for local ladders
- loadLocalLadders();
-
- DEBUG_LOG(("After looking for ladders, we have %d local, %d special && %d normal\n", m_localLadders.size(), m_specialLadders.size(), m_standardLadders.size()));
-}
-
-LadderList::~LadderList()
-{
- LadderInfoList::iterator it;
- for (it = m_specialLadders.begin(); it != m_specialLadders.end(); it = m_specialLadders.begin())
- {
- delete *it;
- m_specialLadders.pop_front();
- }
- for (it = m_standardLadders.begin(); it != m_standardLadders.end(); it = m_standardLadders.begin())
- {
- delete *it;
- m_standardLadders.pop_front();
- }
- for (it = m_localLadders.begin(); it != m_localLadders.end(); it = m_localLadders.begin())
- {
- delete *it;
- m_localLadders.pop_front();
- }
-}
-
-const LadderInfo* LadderList::findLadder( const AsciiString& addr, UnsignedShort port )
-{
- LadderInfoList::const_iterator cit;
-
- for (cit = m_specialLadders.begin(); cit != m_specialLadders.end(); ++cit)
- {
- const LadderInfo *li = *cit;
- if (li->address == addr && li->port == port)
- {
- return li;
- }
- }
-
- for (cit = m_standardLadders.begin(); cit != m_standardLadders.end(); ++cit)
- {
- const LadderInfo *li = *cit;
- if (li->address == addr && li->port == port)
- {
- return li;
- }
- }
-
- for (cit = m_localLadders.begin(); cit != m_localLadders.end(); ++cit)
- {
- const LadderInfo *li = *cit;
- if (li->address == addr && li->port == port)
- {
- return li;
- }
- }
-
- return NULL;
-}
-
-const LadderInfo* LadderList::findLadderByIndex( Int index )
-{
- if (index == 0)
- return NULL;
-
- LadderInfoList::const_iterator cit;
-
- for (cit = m_specialLadders.begin(); cit != m_specialLadders.end(); ++cit)
- {
- const LadderInfo *li = *cit;
- if (li->index == index)
- {
- return li;
- }
- }
-
- for (cit = m_standardLadders.begin(); cit != m_standardLadders.end(); ++cit)
- {
- const LadderInfo *li = *cit;
- if (li->index == index)
- {
- return li;
- }
- }
-
- for (cit = m_localLadders.begin(); cit != m_localLadders.end(); ++cit)
- {
- const LadderInfo *li = *cit;
- if (li->index == index)
- {
- return li;
- }
- }
-
- return NULL;
-}
-
-const LadderInfoList* LadderList::getSpecialLadders( void )
-{
- return &m_specialLadders;
-}
-
-const LadderInfoList* LadderList::getStandardLadders( void )
-{
- return &m_standardLadders;
-}
-
-const LadderInfoList* LadderList::getLocalLadders( void )
-{
- return &m_localLadders;
-}
-
-void LadderList::loadLocalLadders( void )
-{
- AsciiString dirname;
- dirname.format("%sGeneralsOnline\\Ladders\\", TheGlobalData->getPath_UserData().str());
- FilenameList filenameList;
- TheFileSystem->getFileListInDirectory(dirname, AsciiString("*.ini"), filenameList, TRUE);
-
- Int index = -1;
-
- FilenameList::iterator it = filenameList.begin();
- while (it != filenameList.end())
- {
- AsciiString filename = *it;
- DEBUG_LOG(("Looking at possible ladder info file '%s'\n", filename.str()));
- filename.toLower();
- checkLadder( filename, index-- );
- ++it;
- }
-}
-
-void LadderList::checkLadder( AsciiString fname, Int index )
-{
- File *fp = TheFileSystem->openFile(fname.str(), File::READ | File::TEXT);
- char buf[1024];
- AsciiString rawData;
- if (fp)
- {
- Int len;
- while (!fp->eof())
- {
- len = fp->read(buf, 1023);
- buf[len] = 0;
- buf[1023] = 0;
- rawData.concat(buf);
- }
- fp->close();
- fp = NULL;
- }
-
- DEBUG_LOG(("Read %d bytes from '%s'\n", rawData.getLength(), fname.str()));
- if (rawData.isEmpty())
- return;
-
- LadderInfo *li = parseLadder(rawData);
- if (!li)
- {
- return;
- }
-
- // sanity check
- if (li->address.isEmpty())
- {
- DEBUG_LOG(("Bailing because of li->address.isEmpty()\n"));
- delete li;
- return;
- }
-
- if (!li->port)
- {
- DEBUG_LOG(("Bailing because of !li->port\n"));
- delete li;
- return;
- }
-
- if (li->validMaps.size() == 0)
- {
- DEBUG_LOG(("Bailing because of li->validMaps.size() == 0\n"));
- delete li;
- return;
- }
-
- li->index = index;
-
- // ladders are QM-only at this point, which kinda invalidates the whole concept of local ladders. Oh well.
- li->validQM = FALSE; // no local ladders in QM
- li->validCustom = FALSE;
-
- //for (Int i=0; i<4; ++i)
- // fname.removeLastChar(); // remove .lad
- //li->name = UnicodeString(MultiByteToWideCharSingleLine(fname.reverseFind('\\')+1).c_str());
-
- DEBUG_LOG(("Adding local ladder %ls\n", li->name.str()));
- m_localLadders.push_back(li);
-}
diff --git a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/LobbyUtils.cpp b/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/LobbyUtils.cpp
deleted file mode 100644
index 1c54e1ac6c1..00000000000
--- a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/LobbyUtils.cpp
+++ /dev/null
@@ -1,859 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////////////
-// FILE: LobbyUtils.cpp
-// Author: Matthew D. Campbell, Sept 2002
-// Description: GameSpy lobby utils
-///////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/GameEngine.h"
-#include "Common/MultiplayerSettings.h"
-#include "Common/PlayerTemplate.h"
-#include "Common/Version.h"
-#include "GameClient/AnimateWindowManager.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/Image.h"
-#include "GameClient/Shell.h"
-#include "GameClient/KeyDefs.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/GadgetComboBox.h"
-#include "GameClient/GadgetListBox.h"
-#include "GameClient/GadgetTextEntry.h"
-#include "GameClient/GameText.h"
-#include "GameClient/MapUtil.h"
-#include "GameClient/MessageBox.h"
-#include "GameClient/Mouse.h"
-#include "GameNetwork/GameSpyOverlay.h"
-
-#include "GameClient/LanguageFilter.h"
-#include "GameNetwork/GameSpy/BuddyDefs.h"
-#include "GameNetwork/GameSpy/LadderDefs.h"
-#include "GameNetwork/GameSpy/LobbyUtils.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpy/PeerThread.h"
-#include "GameNetwork/GameSpy/PersistentStorageDefs.h"
-#include "GameNetwork/GameSpy/GSConfig.h"
-
-#include "Common/STLTypedefs.h"
-
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-static enum {
- COLUMN_NAME = 0,
- COLUMN_MAP,
- COLUMN_LADDER,
- COLUMN_NUMPLAYERS,
- COLUMN_PASSWORD,
- COLUMN_OBSERVER,
- COLUMN_PING,
-};
-
-static NameKeyType buttonSortAlphaID = NAMEKEY_INVALID;
-static NameKeyType buttonSortPingID = NAMEKEY_INVALID;
-static NameKeyType buttonSortBuddiesID = NAMEKEY_INVALID;
-static NameKeyType windowSortAlphaID = NAMEKEY_INVALID;
-static NameKeyType windowSortPingID = NAMEKEY_INVALID;
-static NameKeyType windowSortBuddiesID = NAMEKEY_INVALID;
-
-static GameWindow *buttonSortAlpha = NULL;
-static GameWindow *buttonSortPing = NULL;
-static GameWindow *buttonSortBuddies = NULL;
-static GameWindow *windowSortAlpha = NULL;
-static GameWindow *windowSortPing = NULL;
-static GameWindow *windowSortBuddies = NULL;
-
-static GameSortType theGameSortType = GAMESORT_ALPHA_ASCENDING;
-static Bool sortBuddies = TRUE;
-static void showSortIcons(void)
-{
- if (windowSortAlpha && windowSortPing)
- {
- switch(theGameSortType)
- {
- case GAMESORT_ALPHA_ASCENDING:
- windowSortAlpha->winHide(FALSE);
- windowSortAlpha->winEnable(TRUE);
- windowSortPing->winHide(TRUE);
- break;
- case GAMESORT_ALPHA_DESCENDING:
- windowSortAlpha->winHide(FALSE);
- windowSortAlpha->winEnable(FALSE);
- windowSortPing->winHide(TRUE);
- break;
- case GAMESORT_PING_ASCENDING:
- windowSortPing->winHide(FALSE);
- windowSortPing->winEnable(TRUE);
- windowSortAlpha->winHide(TRUE);
- break;
- case GAMESORT_PING_DESCENDING:
- windowSortPing->winHide(FALSE);
- windowSortPing->winEnable(FALSE);
- windowSortAlpha->winHide(TRUE);
- break;
- }
- }
-
- if (sortBuddies)
- {
- if (windowSortBuddies)
- {
- windowSortBuddies->winHide(FALSE);
- }
- }
- else
- {
- if (windowSortBuddies)
- {
- windowSortBuddies->winHide(TRUE);
- }
- }
-}
-void setSortMode( GameSortType sortType ) { theGameSortType = sortType; showSortIcons(); RefreshGameListBoxes(); }
-void sortByBuddies( Bool doSort ) { sortBuddies = doSort; showSortIcons(); RefreshGameListBoxes(); }
-
-Bool HandleSortButton( NameKeyType sortButton )
-{
- if (sortButton == buttonSortBuddiesID)
- {
- sortByBuddies( !sortBuddies );
- return TRUE;
- }
- else if (sortButton == buttonSortAlphaID)
- {
- if (theGameSortType == GAMESORT_ALPHA_ASCENDING)
- {
- setSortMode(GAMESORT_ALPHA_DESCENDING);
- }
- else
- {
- setSortMode(GAMESORT_ALPHA_ASCENDING);
- }
- return TRUE;
- }
- else if (sortButton == buttonSortPingID)
- {
- if (theGameSortType == GAMESORT_PING_ASCENDING)
- {
- setSortMode(GAMESORT_PING_DESCENDING);
- }
- else
- {
- setSortMode(GAMESORT_PING_ASCENDING);
- }
- return TRUE;
- }
- return FALSE;
-}
-
-// window ids ------------------------------------------------------------------------------
-static NameKeyType parentID = NAMEKEY_INVALID;
-//static NameKeyType parentGameListSmallID = NAMEKEY_INVALID;
-static NameKeyType parentGameListLargeID = NAMEKEY_INVALID;
-static NameKeyType listboxLobbyGamesSmallID = NAMEKEY_INVALID;
-static NameKeyType listboxLobbyGamesLargeID = NAMEKEY_INVALID;
-//static NameKeyType listboxLobbyGameInfoID = NAMEKEY_INVALID;
-
-// Window Pointers ------------------------------------------------------------------------
-static GameWindow *parent = NULL;
-//static GameWindow *parentGameListSmall = NULL;
-static GameWindow *parentGameListLarge = NULL;
- //GameWindow *listboxLobbyGamesSmall = NULL;
- GameWindow *listboxLobbyGamesLarge = NULL;
- //GameWindow *listboxLobbyGameInfo = NULL;
-
-static const Image *pingImages[3] = { NULL, NULL, NULL };
-
-static void gameTooltip(GameWindow *window,
- WinInstanceData *instData,
- UnsignedInt mouse)
-{
- Int x, y, row, col;
- x = LOLONGTOSHORT(mouse);
- y = HILONGTOSHORT(mouse);
-
- GadgetListBoxGetEntryBasedOnXY(window, x, y, row, col);
-
- if (row == -1 || col == -1)
- {
- TheMouse->setCursorTooltip( UnicodeString::TheEmptyString);//TheGameText->fetch("TOOLTIP:GamesBeingFormed") );
- return;
- }
-
- Int gameID = (Int)GadgetListBoxGetItemData(window, row, 0);
- GameSpyStagingRoom *room = TheGameSpyInfo->findStagingRoomByID(gameID);
- if (!room)
- {
- TheMouse->setCursorTooltip( TheGameText->fetch("TOOLTIP:UnknownGame") );
- return;
- }
-
- if (col == COLUMN_PING)
- {
-#ifdef DEBUG_LOGGING
- UnicodeString s;
- s.format(L"Ping is %d ms (cutoffs are %d ms and %d ms\n%hs local pings\n%hs remote pings",
- room->getPingAsInt(), TheGameSpyConfig->getPingCutoffGood(), TheGameSpyConfig->getPingCutoffBad(),
- TheGameSpyInfo->getPingString().str(), room->getPingString().str()
- );
- TheMouse->setCursorTooltip( s, 10, NULL, 2.0f ); // the text and width are the only params used. the others are the default values.
-#else
- TheMouse->setCursorTooltip( TheGameText->fetch("TOOLTIP:PingInfo"), 10, NULL, 2.0f ); // the text and width are the only params used. the others are the default values.
-#endif
- return;
- }
- if (col == COLUMN_NUMPLAYERS)
- {
- TheMouse->setCursorTooltip( TheGameText->fetch("TOOLTIP:NumberOfPlayers"), 10, NULL, 2.0f ); // the text and width are the only params used. the others are the default values.
- return;
- }
- if (col == COLUMN_PASSWORD)
- {
- if (room->getHasPassword())
- {
- UnicodeString checkTooltip =TheGameText->fetch("TOOTIP:Password");
- if(!checkTooltip.compare(L"Password required to joing game"))
- checkTooltip.set(L"Password required to join game");
- TheMouse->setCursorTooltip( checkTooltip, 10, NULL, 2.0f ); // the text and width are the only params used. the others are the default values.
- }
- else
- TheMouse->setCursorTooltip( UnicodeString::TheEmptyString );
- return;
- }
-
- UnicodeString tooltip;
-
- UnicodeString mapName;
- const MapMetaData *md = TheMapCache->findMap(room->getMap());
- if (md)
- {
- mapName = md->m_displayName;
- }
- else
- {
- const char *start = room->getMap().reverseFind('\\');
- if (start)
- {
- ++start;
- }
- else
- {
- start = room->getMap().str();
- }
- mapName.translate( start );
- }
- UnicodeString tmp;
- tooltip.format(TheGameText->fetch("TOOLTIP:GameInfoGameName"), room->getGameName().str());
- if (room->getLadderPort() != 0)
- {
- const LadderInfo *linfo = TheLadderList->findLadder(room->getLadderIP(), room->getLadderPort());
- if (linfo)
- {
- tmp.format(TheGameText->fetch("TOOLTIP:GameInfoLadderName"), linfo->name.str());
- tooltip.concat(tmp);
- }
- }
- if (room->getExeCRC() != TheGlobalData->m_exeCRC || room->getIniCRC() != TheGlobalData->m_iniCRC)
- {
- tmp.format(TheGameText->fetch("TOOLTIP:InvalidGameVersion"), mapName.str());
- tooltip.concat(tmp);
- }
- tmp.format(TheGameText->fetch("TOOLTIP:GameInfoMap"), mapName.str());
- tooltip.concat(tmp);
-
- AsciiString aPlayer;
- UnicodeString player;
- Int numPlayers = 0;
- for (Int i=0; igetGameSpySlot(i);
- if (i == 0 && (!slot || !slot->isHuman()))
- {
- DEBUG_CRASH(("About to tooltip a non-hosted game!\n"));
- }
- if (slot && slot->isHuman())
- {
- tmp.format(TheGameText->fetch("TOOLTIP:GameInfoPlayer"), slot->getName().str(), slot->getWins(), slot->getLosses());
- tooltip.concat(tmp);
- ++numPlayers;
- }
- else if (slot && slot->isAI())
- {
- ++numPlayers;
- switch(slot->getState())
- {
- case SLOT_EASY_AI:
- tooltip.concat(L'\n');
- tooltip.concat(TheGameText->fetch("GUI:EasyAI"));
- break;
- case SLOT_MED_AI:
- tooltip.concat(L'\n');
- tooltip.concat(TheGameText->fetch("GUI:MediumAI"));
- break;
- case SLOT_BRUTAL_AI:
- tooltip.concat(L'\n');
- tooltip.concat(TheGameText->fetch("GUI:HardAI"));
- break;
- }
- }
- }
- DEBUG_ASSERTCRASH(numPlayers, ("Tooltipping a 0-player game!\n"));
-
- TheMouse->setCursorTooltip( tooltip, 10, NULL, 2.0f ); // the text and width are the only params used. the others are the default values.
-}
-
-static Bool isSmall = TRUE;
-
-GameWindow *GetGameListBox( void )
-{
- return listboxLobbyGamesLarge;
-}
-
-GameWindow *GetGameInfoListBox( void )
-{
- return NULL;
-}
-
-NameKeyType GetGameListBoxID( void )
-{
- return listboxLobbyGamesLargeID;
-}
-
-NameKeyType GetGameInfoListBoxID( void )
-{
- return NAMEKEY_INVALID;
-}
-
-void GrabWindowInfo( void )
-{
- isSmall = TRUE;
- parentID = NAMEKEY( "WOLCustomLobby.wnd:WOLLobbyMenuParent" );
- parent = TheWindowManager->winGetWindowFromId(NULL, parentID);
-
- pingImages[0] = TheMappedImageCollection->findImageByName("Ping03");
- pingImages[1] = TheMappedImageCollection->findImageByName("Ping02");
- pingImages[2] = TheMappedImageCollection->findImageByName("Ping01");
- DEBUG_ASSERTCRASH(pingImages[0], ("Can't find ping image!"));
- DEBUG_ASSERTCRASH(pingImages[1], ("Can't find ping image!"));
- DEBUG_ASSERTCRASH(pingImages[2], ("Can't find ping image!"));
-
-// parentGameListSmallID = NAMEKEY( "WOLCustomLobby.wnd:ParentGameListSmall" );
-// parentGameListSmall = TheWindowManager->winGetWindowFromId(NULL, parentGameListSmallID);
-
- parentGameListLargeID = NAMEKEY( "WOLCustomLobby.wnd:ParentGameListLarge" );
- parentGameListLarge = TheWindowManager->winGetWindowFromId(NULL, parentGameListLargeID);
-
- listboxLobbyGamesSmallID = NAMEKEY( "WOLCustomLobby.wnd:ListboxGames" );
-// listboxLobbyGamesSmall = TheWindowManager->winGetWindowFromId(NULL, listboxLobbyGamesSmallID);
-// listboxLobbyGamesSmall->winSetTooltipFunc(gameTooltip);
-
- listboxLobbyGamesLargeID = NAMEKEY( "WOLCustomLobby.wnd:ListboxGamesLarge" );
- listboxLobbyGamesLarge = TheWindowManager->winGetWindowFromId(NULL, listboxLobbyGamesLargeID);
- listboxLobbyGamesLarge->winSetTooltipFunc(gameTooltip);
-//
-// listboxLobbyGameInfoID = NAMEKEY( "WOLCustomLobby.wnd:ListboxGameInfo" );
-// listboxLobbyGameInfo = TheWindowManager->winGetWindowFromId(NULL, listboxLobbyGameInfoID);
-
- buttonSortAlphaID = NAMEKEY("WOLCustomLobby.wnd:ButtonSortAlpha");
- buttonSortPingID = NAMEKEY("WOLCustomLobby.wnd:ButtonSortPing");
- buttonSortBuddiesID = NAMEKEY("WOLCustomLobby.wnd:ButtonSortBuddies");
- windowSortAlphaID = NAMEKEY("WOLCustomLobby.wnd:WindowSortAlpha");
- windowSortPingID = NAMEKEY("WOLCustomLobby.wnd:WindowSortPing");
- windowSortBuddiesID = NAMEKEY("WOLCustomLobby.wnd:WindowSortBuddies");
-
- buttonSortAlpha = TheWindowManager->winGetWindowFromId(parent, buttonSortAlphaID);
- buttonSortPing = TheWindowManager->winGetWindowFromId(parent, buttonSortPingID);
- buttonSortBuddies = TheWindowManager->winGetWindowFromId(parent, buttonSortBuddiesID);
- windowSortAlpha = TheWindowManager->winGetWindowFromId(parent, windowSortAlphaID);
- windowSortPing = TheWindowManager->winGetWindowFromId(parent, windowSortPingID);
- windowSortBuddies = TheWindowManager->winGetWindowFromId(parent, windowSortBuddiesID);
-
- showSortIcons();
-}
-
-void ReleaseWindowInfo( void )
-{
- isSmall = TRUE;
- parent = NULL;
-// parentGameListSmall = NULL;
- parentGameListLarge = NULL;
-// listboxLobbyGamesSmall = NULL;
- listboxLobbyGamesLarge = NULL;
-// listboxLobbyGameInfo = NULL;
-
- buttonSortAlpha = NULL;
- buttonSortPing = NULL;
- buttonSortBuddies = NULL;
- windowSortAlpha = NULL;
- windowSortPing = NULL;
- windowSortBuddies = NULL;
-}
-
-typedef std::set BuddyGameSet;
-static BuddyGameSet *theBuddyGames = NULL;
-static void populateBuddyGames(void)
-{
- BuddyInfoMap *m = TheGameSpyInfo->getBuddyMap();
- theBuddyGames = NEW BuddyGameSet;
- if (!m)
- {
- return;
- }
- for (BuddyInfoMap::const_iterator bit = m->begin(); bit != m->end(); ++bit)
- {
- BuddyInfo info = bit->second;
- if (info.m_status == GP_STAGING)
- {
- StagingRoomMap *srm = TheGameSpyInfo->getStagingRoomList();
- for (StagingRoomMap::iterator srmIt = srm->begin(); srmIt != srm->end(); ++srmIt)
- {
- GameSpyStagingRoom *game = srmIt->second;
- game->cleanUpSlotPointers();
- const GameSpyGameSlot *slot = game->getGameSpySlot(0);
- if (slot && slot->getName() == info.m_locationString)
- {
- theBuddyGames->insert(game);
- break;
- }
- }
- }
- }
-}
-
-static void clearBuddyGames(void)
-{
- if (theBuddyGames)
- delete theBuddyGames;
- theBuddyGames = NULL;
-}
-
-struct GameSortStruct
-{
- bool operator()(GameSpyStagingRoom *g1, GameSpyStagingRoom *g2)
- {
- // sort CRC mismatches to the bottom
- Bool g1Good = (g1->getExeCRC() != TheGlobalData->m_exeCRC || g1->getIniCRC() != TheGlobalData->m_iniCRC);
- Bool g2Good = (g1->getExeCRC() != TheGlobalData->m_exeCRC || g1->getIniCRC() != TheGlobalData->m_iniCRC);
- if ( g1Good ^ g2Good )
- {
- return g1Good;
- }
-
- // sort games with private ladders to the bottom
- Bool g1UnknownLadder = (g1->getLadderPort() && TheLadderList->findLadder(g1->getLadderIP(), g1->getLadderPort()) == NULL);
- Bool g2UnknownLadder = (g2->getLadderPort() && TheLadderList->findLadder(g2->getLadderIP(), g2->getLadderPort()) == NULL);
- if ( g1UnknownLadder ^ g2UnknownLadder )
- {
- return g2UnknownLadder;
- }
-
- // sort full games to the bottom
- Bool g1Full = (g1->getNumNonObserverPlayers() == g1->getMaxPlayers() || g1->getNumPlayers() == MAX_SLOTS);
- Bool g2Full = (g2->getNumNonObserverPlayers() == g2->getMaxPlayers() || g2->getNumPlayers() == MAX_SLOTS);
- if ( g1Full ^ g2Full )
- {
- return g2Full;
- }
-
- if (sortBuddies)
- {
- Bool g1HasBuddies = (theBuddyGames->find(g1) != theBuddyGames->end());
- Bool g2HasBuddies = (theBuddyGames->find(g2) != theBuddyGames->end());
- if ( g1HasBuddies ^ g2HasBuddies )
- {
- return g1HasBuddies;
- }
- }
-
- switch(theGameSortType)
- {
- case GAMESORT_ALPHA_ASCENDING:
- return wcsicmp(g1->getGameName().str(), g2->getGameName().str()) < 0;
- break;
- case GAMESORT_ALPHA_DESCENDING:
- return wcsicmp(g1->getGameName().str(),g2->getGameName().str()) > 0;
- break;
- case GAMESORT_PING_ASCENDING:
- return g1->getPingAsInt() < g2->getPingAsInt();
- break;
- case GAMESORT_PING_DESCENDING:
- return g1->getPingAsInt() > g2->getPingAsInt();
- break;
- }
- return false;
- }
-};
-
-static Int insertGame( GameWindow *win, GameSpyStagingRoom *game, Bool showMap )
-{
- game->cleanUpSlotPointers();
- Color gameColor = GameSpyColor[GSCOLOR_GAME];
- if (game->getNumNonObserverPlayers() == game->getMaxPlayers() || game->getNumPlayers() == MAX_SLOTS)
- {
- gameColor = GameSpyColor[GSCOLOR_GAME_FULL];
- }
- if (game->getExeCRC() != TheGlobalData->m_exeCRC || game->getIniCRC() != TheGlobalData->m_iniCRC)
- {
- gameColor = GameSpyColor[GSCOLOR_GAME_CRCMISMATCH];
- }
- UnicodeString gameName = game->getGameName();
-
- if(TheGameSpyInfo->getDisallowAsianText())
- {
- const WideChar *buff = gameName.str();
- Int length = gameName.getLength();
- for(Int i = 0; i < length; ++i)
- {
- if(buff[i] >= 256)
- return -1;
- }
- }
- else if(TheGameSpyInfo->getDisallowNonAsianText())
- {
- const WideChar *buff = gameName.str();
- Int length = gameName.getLength();
- Bool hasUnicode = FALSE;
- for(Int i = 0; i < length; ++i)
- {
- if(buff[i] >= 256)
- {
- hasUnicode = TRUE;
- break;
- }
- }
- if(!hasUnicode)
- return -1;
- }
-
-
-
- Int index = GadgetListBoxAddEntryText(win, game->getGameName(), gameColor, -1, COLUMN_NAME);
- GadgetListBoxSetItemData(win, (void *)game->getID(), index);
-
- UnicodeString s;
-
- if (showMap)
- {
- UnicodeString mapName;
- const MapMetaData *md = TheMapCache->findMap(game->getMap());
- if (md)
- {
- mapName = md->m_displayName;
- }
- else
- {
- const char *start = game->getMap().reverseFind('\\');
- if (start)
- {
- ++start;
- }
- else
- {
- start = game->getMap().str();
- }
- mapName.translate( start );
- }
- GadgetListBoxAddEntryText(win, mapName, gameColor, index, COLUMN_MAP);
-
- const LadderInfo * li = TheLadderList->findLadder(game->getLadderIP(), game->getLadderPort());
- if (li)
- {
- GadgetListBoxAddEntryText(win, li->name, gameColor, index, COLUMN_LADDER);
- }
- else if (game->getLadderPort())
- {
- GadgetListBoxAddEntryText(win, TheGameText->fetch("GUI:UnknownLadder"), gameColor, index, COLUMN_LADDER);
- }
- else
- {
- GadgetListBoxAddEntryText(win, TheGameText->fetch("GUI:NoLadder"), gameColor, index, COLUMN_LADDER);
- }
- }
- else
- {
- GadgetListBoxAddEntryText(win, UnicodeString(L" "), gameColor, index, COLUMN_MAP);
- GadgetListBoxAddEntryText(win, UnicodeString(L" "), gameColor, index, COLUMN_LADDER);
- }
-
- s.format(L"%d/%d", game->getReportedNumPlayers(), game->getReportedMaxPlayers());
- GadgetListBoxAddEntryText(win, s, gameColor, index, COLUMN_NUMPLAYERS);
-
- if (game->getHasPassword())
- {
- const Image *img = TheMappedImageCollection->findImageByName("Password");
- Int width = 10, height = 10;
- if (img)
- {
- width = img->getImageWidth();
- height = img->getImageHeight();
- }
- GadgetListBoxAddEntryImage(win, img, index, COLUMN_PASSWORD, width, height);
- }
- else
- {
- GadgetListBoxAddEntryText(win, UnicodeString(L" "), gameColor, index, COLUMN_PASSWORD);
- }
-
- if (game->getAllowObservers())
- {
- const Image *img = TheMappedImageCollection->findImageByName("Observer");
- GadgetListBoxAddEntryImage(win, img, index, COLUMN_OBSERVER);
- }
- else
- {
- GadgetListBoxAddEntryText(win, UnicodeString(L" "), gameColor, index, COLUMN_OBSERVER);
- }
-
- s.format(L"%d", game->getPingAsInt());
- GadgetListBoxAddEntryText(win, s, gameColor, index, COLUMN_PING);
- Int ping = game->getPingAsInt();
- Int width = 10, height = 10;
- if (pingImages[0])
- {
- width = pingImages[0]->getImageWidth();
- height = pingImages[0]->getImageHeight();
- }
- // CLH picking an arbitrary number for our ping display
- if (ping < TheGameSpyConfig->getPingCutoffGood())
- {
- GadgetListBoxAddEntryImage(win, pingImages[0], index, COLUMN_PING, width, height);
- }
- else if (ping < TheGameSpyConfig->getPingCutoffBad())
- {
- GadgetListBoxAddEntryImage(win, pingImages[1], index, COLUMN_PING, width, height);
- }
- else
- {
- GadgetListBoxAddEntryImage(win, pingImages[2], index, COLUMN_PING, width, height);
- }
-
- return index;
-}
-
-void RefreshGameListBox( GameWindow *win, Bool showMap )
-{
- if (!win)
- return;
-
- // save off selection
- Int selectedIndex = -1;
- Int indexToSelect = -1;
- Int selectedID = 0;
- GadgetListBoxGetSelected(win, &selectedIndex);
- if (selectedIndex != -1 )
- {
- selectedID = (Int)GadgetListBoxGetItemData(win, selectedIndex);
- }
- int prevPos = GadgetListBoxGetTopVisibleEntry( win );
-
- // empty listbox
- GadgetListBoxReset(win);
-
- // sort our games
- typedef std::multiset SortedGameList;
- SortedGameList sgl;
- StagingRoomMap *srm = TheGameSpyInfo->getStagingRoomList();
- populateBuddyGames();
- for (StagingRoomMap::iterator srmIt = srm->begin(); srmIt != srm->end(); ++srmIt)
- {
- sgl.insert(srmIt->second);
- }
-
- // populate listbox
- for (SortedGameList::iterator sglIt = sgl.begin(); sglIt != sgl.end(); ++sglIt)
- {
- GameSpyStagingRoom *game = *sglIt;
- if (game)
- {
- Int index = insertGame(win, game, showMap);
- if (game->getID() == selectedID)
- {
- indexToSelect = index;
- }
- }
- }
-
- clearBuddyGames();
-
- // restore selection
- GadgetListBoxSetSelected(win, indexToSelect); // even for -1, so we can disable the 'Join Game' button
-// if(prevPos > 10)
- GadgetListBoxSetTopVisibleEntry( win, prevPos );//+ 1
-
- if (indexToSelect < 0 && selectedID)
- {
- TheWindowManager->winSetLoneWindow(NULL);
- }
-}
-
-void RefreshGameInfoListBox( GameWindow *mainWin, GameWindow *win )
-{
-// if (!mainWin || !win)
-// return;
-//
-// GadgetListBoxReset(win);
-//
-// Int selected = -1;
-// GadgetListBoxGetSelected(mainWin, &selected);
-// if (selected < 0)
-// {
-// return;
-// }
-//
-// Int selectedID = (Int)GadgetListBoxGetItemData(mainWin, selected);
-// if (selectedID < 0)
-// {
-// return;
-// }
-//
-// StagingRoomMap *srm = TheGameSpyInfo->getStagingRoomList();
-// StagingRoomMap::iterator srmIt = srm->find(selectedID);
-// if (srmIt != srm->end())
-// {
-// GameSpyStagingRoom *theRoom = srmIt->second;
-// theRoom->cleanUpSlotPointers();
-//
-// // game name
-//// GadgetListBoxAddEntryText(listboxLobbyGameInfo, theRoom->getGameName(), GameSpyColor[GSCOLOR_DEFAULT], -1);
-//
-// const LadderInfo * li = TheLadderList->findLadder(theRoom->getLadderIP(), theRoom->getLadderPort());
-// if (li)
-// {
-// UnicodeString tmp;
-// tmp.format(TheGameText->fetch("TOOLTIP:LadderName"), li->name.str());
-// GadgetListBoxAddEntryText(listboxLobbyGameInfo, tmp, GameSpyColor[GSCOLOR_DEFAULT], -1);
-// }
-// else if (theRoom->getLadderPort())
-// {
-// GadgetListBoxAddEntryText(listboxLobbyGameInfo, TheGameText->fetch("TOOLTIP:UnknownLadder"), GameSpyColor[GSCOLOR_DEFAULT], -1);
-// }
-// else
-// {
-// GadgetListBoxAddEntryText(listboxLobbyGameInfo, TheGameText->fetch("TOOLTIP:NoLadder"), GameSpyColor[GSCOLOR_DEFAULT], -1);
-// }
-//
-// if (theRoom->getExeCRC() != TheGlobalData->m_exeCRC || theRoom->getIniCRC() != TheGlobalData->m_iniCRC)
-// {
-// GadgetListBoxAddEntryText(listboxLobbyGameInfo, TheGameText->fetch("TOOLTIP:InvalidGameVersionSingleLine"), GameSpyColor[GSCOLOR_DEFAULT], -1);
-// }
-//
-// // map name
-// UnicodeString mapName;
-// const MapMetaData *md = TheMapCache->findMap(theRoom->getMap());
-// if (md)
-// {
-// mapName = md->m_displayName;
-// }
-// else
-// {
-// const char *start = theRoom->getMap().reverseFind('\\');
-// if (start)
-// {
-// ++start;
-// }
-// else
-// {
-// start = theRoom->getMap().str();
-// }
-// mapName.translate( start );
-// }
-//
-// GadgetListBoxAddEntryText(listboxLobbyGameInfo, mapName, GameSpyColor[GSCOLOR_DEFAULT], -1);
-//
-// // player list (rank, win/loss, side)
-// for (Int i=0; igetGameSpySlot(i);
-// if (slot && slot->isHuman())
-// {
-// UnicodeString theName, theRating, thePlayerTemplate;
-// Int colorIdx = slot->getColor();
-// theName = slot->getName();
-// theRating.format(L" (%d-%d)", slot->getWins(), slot->getLosses());
-// const PlayerTemplate * pt = ThePlayerTemplateStore->getNthPlayerTemplate(slot->getPlayerTemplate());
-// if (pt)
-// {
-// thePlayerTemplate = pt->getDisplayName();
-// }
-// else
-// {
-// thePlayerTemplate = TheGameText->fetch("GUI:Random");
-// }
-//
-// UnicodeString theText;
-// theText.format(L"%ls - %ls - %ls", theName.str(), thePlayerTemplate.str(), theRating.str());
-//
-// Int theColor = GameSpyColor[GSCOLOR_DEFAULT];
-// const MultiplayerColorDefinition *mcd = TheMultiplayerSettings->getColor(colorIdx);
-// if (mcd)
-// {
-// theColor = mcd->getColor();
-// }
-//
-// GadgetListBoxAddEntryText(listboxLobbyGameInfo, theText, theColor, -1);
-// }
-// }
-// }
-
-}
-
-void RefreshGameListBoxes( void )
-{
- GameWindow *main = GetGameListBox();
- GameWindow *info = GetGameInfoListBox();
-
- RefreshGameListBox( main, (info == NULL) );
-
- if (info)
- {
- RefreshGameInfoListBox( main, info );
- }
-}
-
-void ToggleGameListType( void )
-{
- isSmall = !isSmall;
- if(isSmall)
- {
- parentGameListLarge->winHide(TRUE);
-// parentGameListSmall->winHide(FALSE);
- }
- else
- {
- parentGameListLarge->winHide(FALSE);
-// parentGameListSmall->winHide(TRUE);
- }
-
- RefreshGameListBoxes();
-}
-
diff --git a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/MainMenuUtils.cpp b/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/MainMenuUtils.cpp
deleted file mode 100644
index 27dc0d0a2b8..00000000000
--- a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/MainMenuUtils.cpp
+++ /dev/null
@@ -1,895 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////////////
-// FILE: MainMenuUtils.cpp
-// Author: Matthew D. Campbell, Sept 2002
-// Description: GameSpy version check, patch download, etc utils
-///////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include
-
-//#include "Common/Registry.h"
-#include "Common/UserPreferences.h"
-#include "Common/Version.h"
-#include "GameClient/GameText.h"
-#include "GameClient/MessageBox.h"
-#include "GameClient/Shell.h"
-#include "GameLogic/ScriptEngine.h"
-
-#include "GameClient/ShellHooks.h"
-
-#include "GameSpy/ghttp/ghttp.h"
-
-#include "GameNetwork/DownloadManager.h"
-#include "GameNetwork/GameSpy/BuddyThread.h"
-#include "GameNetwork/GameSpy/MainMenuUtils.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpy/PeerThread.h"
-
-#include "WWDownload/Registry.h"
-#include "WWDownload/URLBuilder.h"
-
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-static Bool checkingForPatchBeforeGameSpy = FALSE;
-static Int checksLeftBeforeOnline = 0;
-static Int timeThroughOnline = 0; // used to avoid having old callbacks cause problems
-static Bool mustDownloadPatch = FALSE;
-static Bool cantConnectBeforeOnline = FALSE;
-static std::list queuedDownloads;
-
-static char *MOTDBuffer = NULL;
-static char *configBuffer = NULL;
-GameWindow *onlineCancelWindow = NULL;
-
-static Bool s_asyncDNSThreadDone = TRUE;
-static Bool s_asyncDNSThreadSucceeded = FALSE;
-static Bool s_asyncDNSLookupInProgress = FALSE;
-static HANDLE s_asyncDNSThreadHandle = NULL;
-enum {
- LOOKUP_INPROGRESS,
- LOOKUP_FAILED,
- LOOKUP_SUCCEEDED,
-};
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-static void startOnline( void );
-static void reallyStartPatchCheck( void );
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-// someone has hit a button allowing downloads to start
-void StartDownloadingPatches( void )
-{
- if (queuedDownloads.empty())
- {
- HandleCanceledDownload();
- return;
- }
-
- WindowLayout *layout;
- layout = TheWindowManager->winCreateLayout( AsciiString( "Menus/DownloadMenu.wnd" ) );
- layout->runInit();
- layout->hide( FALSE );
- layout->bringForward();
- HandleCanceledDownload(FALSE);
- DEBUG_ASSERTCRASH(TheDownloadManager, ("No download manager!"));
- if (TheDownloadManager)
- {
- std::list::iterator it = queuedDownloads.begin();
- while (it != queuedDownloads.end())
- {
- QueuedDownload q = *it;
- TheDownloadManager->queueFileForDownload(q.server, q.userName, q.password,
- q.file, q.localFile, q.regKey, q.tryResume);
- queuedDownloads.pop_front();
- it = queuedDownloads.begin();
- }
- TheDownloadManager->downloadNextQueuedFile();
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-// user agrees to patch before going online
-static void patchBeforeOnlineCallback( void )
-{
- StartDownloadingPatches();
-}
-
-// user doesn't want to patch before going online
-static void noPatchBeforeOnlineCallback( void )
-{
- queuedDownloads.clear();
- if (mustDownloadPatch || cantConnectBeforeOnline)
- {
- // go back to normal
- HandleCanceledDownload();
- }
- else
- {
- // clear out unneeded downloads and go on
- startOnline();
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-static Bool hasWriteAccess()
-{
- const char* filename = "PatchAccessTest.txt";
-
- remove(filename);
-
- int handle = _open( filename, _O_CREAT | _O_RDWR, _S_IREAD | _S_IWRITE);
- if (handle == -1)
- {
- return false;
- }
-
- _close(handle);
- remove(filename);
-
- unsigned int val;
- if (!GetUnsignedIntFromRegistry("", "Version", val))
- {
- return false;
- }
-
- if (!SetUnsignedIntInRegistry("", "Version", val))
- {
- return false;
- }
-
- return true;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-static void startOnline( void )
-{
- checkingForPatchBeforeGameSpy = FALSE;
-
- DEBUG_ASSERTCRASH(checksLeftBeforeOnline==0, ("starting online with pending callbacks"));
- if (onlineCancelWindow)
- {
- TheWindowManager->winDestroy(onlineCancelWindow);
- onlineCancelWindow = NULL;
- }
-
- if (cantConnectBeforeOnline)
- {
- MessageBoxOk(TheGameText->fetch("GUI:CannotConnectToServservTitle"),
- TheGameText->fetch("GUI:CannotConnectToServserv"),
- noPatchBeforeOnlineCallback);
- return;
- }
- if (queuedDownloads.size())
- {
- if (!hasWriteAccess())
- {
- MessageBoxOk(TheGameText->fetch("GUI:Error"),
- TheGameText->fetch("GUI:MustHaveAdminRights"),
- noPatchBeforeOnlineCallback);
- }
- else if (mustDownloadPatch)
- {
- MessageBoxOkCancel(TheGameText->fetch("GUI:PatchAvailable"),
- TheGameText->fetch("GUI:MustPatchForOnline"),
- patchBeforeOnlineCallback, noPatchBeforeOnlineCallback);
- }
- else
- {
- MessageBoxYesNo(TheGameText->fetch("GUI:PatchAvailable"),
- TheGameText->fetch("GUI:CanPatchForOnline"),
- patchBeforeOnlineCallback, noPatchBeforeOnlineCallback);
- }
- return;
- }
-
- TheScriptEngine->signalUIInteract(TheShellHookNames[SHELL_SCRIPT_HOOK_MAIN_MENU_ONLINE_SELECTED]);
-
- DEBUG_ASSERTCRASH( !TheGameSpyBuddyMessageQueue, ("TheGameSpyBuddyMessageQueue exists!") );
- DEBUG_ASSERTCRASH( !TheGameSpyPeerMessageQueue, ("TheGameSpyPeerMessageQueue exists!") );
- DEBUG_ASSERTCRASH( !TheGameSpyInfo, ("TheGameSpyInfo exists!") );
- SetUpGameSpy(MOTDBuffer, configBuffer);
- if (MOTDBuffer)
- {
- delete[] MOTDBuffer;
- MOTDBuffer = NULL;
- }
- if (configBuffer)
- {
- delete[] configBuffer;
- configBuffer = NULL;
- }
-
-#ifdef ALLOW_NON_PROFILED_LOGIN
- UserPreferences pref;
- pref.load("GameSpyLogin.ini");
- UserPreferences::const_iterator it = pref.find("useProfiles");
- if (it != pref.end() && it->second.compareNoCase("yes") == 0)
-#endif ALLOW_NON_PROFILED_LOGIN
- TheShell->push( AsciiString("Menus/GameSpyLoginProfile.wnd") );
-#ifdef ALLOW_NON_PROFILED_LOGIN
- else
- TheShell->push( AsciiString("Menus/GameSpyLoginQuick.wnd") );
-#endif ALLOW_NON_PROFILED_LOGIN
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-static void queuePatch(Bool mandatory, AsciiString downloadURL)
-{
- QueuedDownload q;
- Bool success = TRUE;
-
- AsciiString connectionType;
- success &= downloadURL.nextToken(&connectionType, ":");
-
- AsciiString server;
- success &= downloadURL.nextToken(&server, ":/");
-
- AsciiString user;
- success &= downloadURL.nextToken(&user, ":@");
-
- AsciiString pass;
- success &= downloadURL.nextToken(&pass, "@/");
-
- AsciiString filePath;
- success &= downloadURL.nextToken(&filePath, "");
-
- if (!success && user.isNotEmpty())
- {
- // no user/pass combo - move the file into it's proper place
- filePath = user;
- user = ""; // LFeenanEA - Credentials removed as per Security requirements
- pass = "";
- success = TRUE;
- }
-
- AsciiString fileStr = filePath;
- const char *s = filePath.reverseFind('/');
- if (s)
- fileStr = s+1;
- AsciiString fileName = "patches\\";
- fileName.concat(fileStr);
-
- DEBUG_LOG(("download URL split: %d [%s] [%s] [%s] [%s] [%s] [%s]\n",
- success, connectionType.str(), server.str(), user.str(), pass.str(),
- filePath.str(), fileName.str()));
-
- if (!success)
- return;
-
- q.file = filePath;
- q.localFile = fileName;
- q.password = pass;
- q.regKey = "";
- q.server = server;
- q.tryResume = TRUE;
- q.userName = user;
-
- std::list::iterator it = queuedDownloads.begin();
- while (it != queuedDownloads.end())
- {
- if (it->localFile == q.localFile)
- return; // don't add it if it exists already (because we can check multiple times)
- ++it;
- }
-
- queuedDownloads.push_back(q);
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-static GHTTPBool motdCallback( GHTTPRequest request, GHTTPResult result,
- char * buffer, GHTTPByteCount bufferLen, void * param )
-{
- Int run = (Int)param;
- if (run != timeThroughOnline)
- {
- DEBUG_CRASH(("Old callback being called!"));
- return GHTTPTrue;
- }
-
- if (MOTDBuffer)
- {
- delete[] MOTDBuffer;
- MOTDBuffer = NULL;
- }
-
- MOTDBuffer = NEW char[bufferLen];
- memcpy(MOTDBuffer, buffer, bufferLen);
- MOTDBuffer[bufferLen-1] = 0;
-
- --checksLeftBeforeOnline;
- DEBUG_ASSERTCRASH(checksLeftBeforeOnline>=0, ("Too many callbacks"));
- if (onlineCancelWindow && !checksLeftBeforeOnline)
- {
- TheWindowManager->winDestroy(onlineCancelWindow);
- onlineCancelWindow = NULL;
- }
-
- DEBUG_LOG(("------- Got MOTD before going online -------\n"));
- DEBUG_LOG(("%s\n", (MOTDBuffer)?MOTDBuffer:""));
- DEBUG_LOG(("--------------------------------------------\n"));
-
- if (!checksLeftBeforeOnline)
- startOnline();
-
- return GHTTPTrue;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-static GHTTPBool configCallback( GHTTPRequest request, GHTTPResult result,
- char * buffer, GHTTPByteCount bufferLen, void * param )
-{
- Int run = (Int)param;
- if (run != timeThroughOnline)
- {
- DEBUG_CRASH(("Old callback being called!"));
- return GHTTPTrue;
- }
-
- if (configBuffer)
- {
- delete[] configBuffer;
- configBuffer = NULL;
- }
-
- if (result != GHTTPSuccess || bufferLen < 100)
- {
- if (!checkingForPatchBeforeGameSpy)
- return GHTTPTrue;
- --checksLeftBeforeOnline;
- if (onlineCancelWindow && !checksLeftBeforeOnline)
- {
- TheWindowManager->winDestroy(onlineCancelWindow);
- onlineCancelWindow = NULL;
- }
- cantConnectBeforeOnline = TRUE;
- if (!checksLeftBeforeOnline)
- {
- startOnline();
- }
- return GHTTPTrue;
- }
-
- configBuffer = NEW char[bufferLen];
- memcpy(configBuffer, buffer, bufferLen);
- configBuffer[bufferLen-1] = 0;
-
- AsciiString fname;
- fname.format("%sGeneralsOnline\\Config.txt", TheGlobalData->getPath_UserData().str());
- FILE *fp = fopen(fname.str(), "wb");
- if (fp)
- {
- fwrite(configBuffer, bufferLen, 1, fp);
- fclose(fp);
- }
-
- --checksLeftBeforeOnline;
- DEBUG_ASSERTCRASH(checksLeftBeforeOnline>=0, ("Too many callbacks"));
- if (onlineCancelWindow && !checksLeftBeforeOnline)
- {
- TheWindowManager->winDestroy(onlineCancelWindow);
- onlineCancelWindow = NULL;
- }
-
- DEBUG_LOG(("Got Config before going online\n"));
-
- if (!checksLeftBeforeOnline)
- startOnline();
-
- return GHTTPTrue;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-static GHTTPBool configHeadCallback( GHTTPRequest request, GHTTPResult result,
- char * buffer, GHTTPByteCount bufferLen, void * param )
-{
- Int run = (Int)param;
- if (run != timeThroughOnline)
- {
- DEBUG_CRASH(("Old callback being called!"));
- return GHTTPTrue;
- }
-
- DEBUG_LOG(("HTTP head resp: res=%d, len=%d, buf=[%s]\n", result, bufferLen, buffer));
-
- if (result == GHTTPSuccess)
- {
- DEBUG_LOG(("Headers are [%s]\n", ghttpGetHeaders( request )));
-
- AsciiString headers(ghttpGetHeaders( request ));
- AsciiString line;
- while (headers.nextToken(&line, "\n\r"))
- {
- AsciiString key, val;
- line.nextToken(&key, ": ");
- line.nextToken(&val, ": \r\n");
-
- if (key.compare("Content-Length") == 0 && val.isNotEmpty())
- {
- Int serverLen = atoi(val.str());
- Int fileLen = 0;
- AsciiString fname;
- fname.format("%sGeneralsOnline\\Config.txt", TheGlobalData->getPath_UserData().str());
- FILE *fp = fopen(fname.str(), "rb");
- if (fp)
- {
- fseek(fp, 0, SEEK_END);
- fileLen = ftell(fp);
- fclose(fp);
- }
-
- if (serverLen == fileLen)
- {
- // we don't need to download the MOTD again
- --checksLeftBeforeOnline;
- DEBUG_ASSERTCRASH(checksLeftBeforeOnline>=0, ("Too many callbacks"));
- if (onlineCancelWindow && !checksLeftBeforeOnline)
- {
- TheWindowManager->winDestroy(onlineCancelWindow);
- onlineCancelWindow = NULL;
- }
-
- if (configBuffer)
- {
- delete[] configBuffer;
- configBuffer = NULL;
- }
-
- AsciiString fname;
- fname.format("%sGeneralsOnline\\Config.txt", TheGlobalData->getPath_UserData().str());
- FILE *fp = fopen(fname.str(), "rb");
- if (fp)
- {
- configBuffer = NEW char[fileLen];
- fread(configBuffer, fileLen, 1, fp);
- configBuffer[fileLen-1] = 0;
- fclose(fp);
-
- DEBUG_LOG(("Got Config before going online\n"));
-
- if (!checksLeftBeforeOnline)
- startOnline();
-
- return GHTTPTrue;
- }
- }
- }
- }
- }
-
- // we need to download the MOTD again
- std::string gameURL, mapURL;
- std::string configURL, motdURL;
- FormatURLFromRegistry(gameURL, mapURL, configURL, motdURL);
- ghttpGet( configURL.c_str(), GHTTPFalse, configCallback, param );
-
- return GHTTPTrue;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-static GHTTPBool gamePatchCheckCallback( GHTTPRequest request, GHTTPResult result, char * buffer, GHTTPByteCount bufferLen, void * param )
-{
- Int run = (Int)param;
- if (run != timeThroughOnline)
- {
- DEBUG_CRASH(("Old callback being called!"));
- return GHTTPTrue;
- }
-
- --checksLeftBeforeOnline;
- DEBUG_ASSERTCRASH(checksLeftBeforeOnline>=0, ("Too many callbacks"));
-
- DEBUG_LOG(("Result=%d, buffer=[%s], len=%d\n", result, buffer, bufferLen));
- if (result != GHTTPSuccess)
- {
- if (!checkingForPatchBeforeGameSpy)
- return GHTTPTrue;
- cantConnectBeforeOnline = TRUE;
- if (!checksLeftBeforeOnline)
- {
- startOnline();
- }
- return GHTTPTrue;
- }
-
- AsciiString message = buffer;
- AsciiString line;
- while (message.nextToken(&line, "\r\n"))
- {
- AsciiString type, req, url;
- Bool ok = TRUE;
- ok &= line.nextToken(&type, " ");
- ok &= line.nextToken(&req, " ");
- ok &= line.nextToken(&url, " ");
- if (ok && type == "patch")
- {
- DEBUG_LOG(("Saw a patch: %d/[%s]\n", atoi(req.str()), url.str()));
- queuePatch( atoi(req.str()), url );
- if (atoi(req.str()))
- {
- mustDownloadPatch = TRUE;
- }
- }
- else if (ok && type == "server")
- {
- }
- }
-
- if (!checksLeftBeforeOnline)
- {
- startOnline();
- }
-
- return GHTTPTrue;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-void CancelPatchCheckCallbackAndReopenDropdown( void )
-{
- HandleCanceledDownload();
- CancelPatchCheckCallback();
-}
-
-void CancelPatchCheckCallback( void )
-{
- s_asyncDNSLookupInProgress = FALSE;
- HandleCanceledDownload(FALSE); // don't dropdown
- checkingForPatchBeforeGameSpy = FALSE;
- checksLeftBeforeOnline = 0;
- if (onlineCancelWindow)
- {
- TheWindowManager->winDestroy(onlineCancelWindow);
- onlineCancelWindow = NULL;
- }
- queuedDownloads.clear();
- if (MOTDBuffer)
- {
- delete[] MOTDBuffer;
- MOTDBuffer = NULL;
- }
- if (configBuffer)
- {
- delete[] configBuffer;
- configBuffer = NULL;
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-static GHTTPBool overallStatsCallback( GHTTPRequest request, GHTTPResult result, char * buffer, GHTTPByteCount bufferLen, void * param )
-{
- DEBUG_LOG(("overallStatsCallback() - Result=%d, len=%d\n", result, bufferLen));
- if (result != GHTTPSuccess)
- {
- return GHTTPTrue;
- }
-
- OverallStats USA, China, GLA;
- AsciiString message = buffer;
-
- Int state = STATS_MAX; // STATS_MAX == none
- AsciiString line;
- OverallStats *stats = NULL;
- while (message.nextToken(&line, "\n"))
- {
- line.trim();
- line.toLower();
- if (strstr(line.str(), "today"))
- {
- state = STATS_TODAY;
- }
- else if (strstr(line.str(), "yesterday"))
- {
- state = STATS_YESTERDAY;
- }
- else if (strstr(line.str(), "all time"))
- {
- state = STATS_ALLTIME;
- }
- else if (strstr(line.str(), "last week"))
- {
- state = STATS_LASTWEEK;
- }
- else if (state != STATS_MAX && strstr(line.str(), "usa"))
- {
- stats = &USA;
- }
- else if (state != STATS_MAX && strstr(line.str(), "china"))
- {
- stats = &China;
- }
- else if (state != STATS_MAX && strstr(line.str(), "gla"))
- {
- stats = &GLA;
- }
-
- if (stats)
- {
- AsciiString totalLine, winsLine, lossesLine;
- message.nextToken(&totalLine, "\n");
- message.nextToken(&winsLine, "\n");
- message.nextToken(&lossesLine, "\n");
- while (totalLine.isNotEmpty() && !isdigit(totalLine.getCharAt(0)))
- {
- totalLine = totalLine.str()+1;
- }
- while (winsLine.isNotEmpty() && !isdigit(winsLine.getCharAt(0)))
- {
- winsLine = winsLine.str()+1;
- }
- while (lossesLine.isNotEmpty() && !isdigit(lossesLine.getCharAt(0)))
- {
- lossesLine = lossesLine.str()+1;
- }
- if (totalLine.isNotEmpty() && winsLine.isNotEmpty() && lossesLine.isNotEmpty())
- {
- stats->wins[state] = atoi(winsLine.str());
- stats->losses[state] = atoi(lossesLine.str());
- }
-
- stats = NULL;
- }
- }
-
- HandleOverallStats(USA, China, GLA);
-
- return GHTTPTrue;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-static GHTTPBool numPlayersOnlineCallback( GHTTPRequest request, GHTTPResult result, char * buffer, GHTTPByteCount bufferLen, void * param )
-{
- DEBUG_LOG(("numPlayersOnlineCallback() - Result=%d, buffer=[%s], len=%d\n", result, buffer, bufferLen));
- if (result != GHTTPSuccess)
- {
- return GHTTPTrue;
- }
-
- AsciiString message = buffer;
- message.trim();
- const char *s = message.reverseFind('\\');
- if (!s)
- {
- return GHTTPTrue;
- }
-
- if (*s == '\\')
- ++s;
-
- DEBUG_LOG(("Message was '%s', trimmed to '%s'=%d\n", buffer, s, atoi(s)));
- HandleNumPlayersOnline(atoi(s));
-
- return GHTTPTrue;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-void CheckOverallStats( void )
-{
- ghttpGet("http://gamestats.gamespy.com/ccgenerals/display.html",
- GHTTPFalse, overallStatsCallback, NULL);
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-void CheckNumPlayersOnline( void )
-{
- ghttpGet("http://launch.gamespyarcade.com/software/launch/arcadecount2.dll?svcname=ccgenerals",
- GHTTPFalse, numPlayersOnlineCallback, NULL);
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-DWORD WINAPI asyncGethostbynameThreadFunc( void * szName )
-{
- HOSTENT *he = gethostbyname( (const char *)szName );
-
- if (he)
- {
- s_asyncDNSThreadSucceeded = TRUE;
- }
- else
- {
- s_asyncDNSThreadSucceeded = FALSE;
- }
-
- s_asyncDNSThreadDone = TRUE;
- return 0;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-int asyncGethostbyname(char * szName)
-{
- static int stat = 0;
- static unsigned long threadid;
-
- if( stat == 0 )
- {
- /* Kick off gethostname thread */
- s_asyncDNSThreadDone = FALSE;
- s_asyncDNSThreadHandle = CreateThread( NULL, 0, asyncGethostbynameThreadFunc, szName, 0, &threadid );
-
- if( s_asyncDNSThreadHandle == NULL )
- {
- return( LOOKUP_FAILED );
- }
- stat = 1;
- }
- if( stat == 1 )
- {
- if( s_asyncDNSThreadDone )
- {
- /* Thread finished */
- stat = 0;
- s_asyncDNSLookupInProgress = FALSE;
- s_asyncDNSThreadHandle = NULL;
- return( (s_asyncDNSThreadSucceeded)?LOOKUP_SUCCEEDED:LOOKUP_FAILED );
- }
- }
-
- return( LOOKUP_INPROGRESS );
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-// GameSpy's HTTP SDK has had at least 1 crash bug, so we're going to just bail and
-// never try again if they crash us. We won't be able to get back online again (we'll
-// time out) but at least we'll live.
-static Bool isHttpOk = TRUE;
-
-void HTTPThinkWrapper( void )
-{
- if (s_asyncDNSLookupInProgress)
- {
- Int ret = asyncGethostbyname("servserv.generals.ea.com");
- switch(ret)
- {
- case LOOKUP_FAILED:
- cantConnectBeforeOnline = TRUE;
- startOnline();
- break;
- case LOOKUP_SUCCEEDED:
- reallyStartPatchCheck();
- break;
- }
- }
-
- if (isHttpOk)
- {
- try
- {
- ghttpThink();
- }
- catch (...)
- {
- isHttpOk = FALSE; // we can't abort the login, since we might be done with the
- // required checks and are fetching extras. If it is a required
- // check, we'll time out normally.
- }
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-void StopAsyncDNSCheck( void )
-{
- if (s_asyncDNSThreadHandle)
- {
-#ifdef DEBUG_CRASHING
- Int res =
-#endif
- TerminateThread(s_asyncDNSThreadHandle,0);
- DEBUG_ASSERTCRASH(res, ("Could not terminate the Async DNS Lookup thread!")); // Thread still not killed!
- }
- s_asyncDNSThreadHandle = NULL;
- s_asyncDNSLookupInProgress = FALSE;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-void StartPatchCheck( void )
-{
- checkingForPatchBeforeGameSpy = TRUE;
- cantConnectBeforeOnline = FALSE;
- timeThroughOnline++;
- checksLeftBeforeOnline = 0;
-
- onlineCancelWindow = MessageBoxCancel(TheGameText->fetch("GUI:CheckingForPatches"),
- TheGameText->fetch("GUI:CheckingForPatches"), CancelPatchCheckCallbackAndReopenDropdown);
-
- s_asyncDNSLookupInProgress = TRUE;
- Int ret = asyncGethostbyname("servserv.generals.ea.com");
- switch(ret)
- {
- case LOOKUP_FAILED:
- cantConnectBeforeOnline = TRUE;
- startOnline();
- break;
- case LOOKUP_SUCCEEDED:
- reallyStartPatchCheck();
- break;
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
-
-static void reallyStartPatchCheck( void )
-{
- checksLeftBeforeOnline = 4;
-
- std::string gameURL, mapURL;
- std::string configURL, motdURL;
-
- FormatURLFromRegistry(gameURL, mapURL, configURL, motdURL);
-
- std::string proxy;
- if (GetStringFromRegistry("", "Proxy", proxy))
- {
- if (!proxy.empty())
- {
- ghttpSetProxy(proxy.c_str());
- }
- }
-
- // check for a patch first
- DEBUG_LOG(("Game patch check: [%s]\n", gameURL.c_str()));
- DEBUG_LOG(("Map patch check: [%s]\n", mapURL.c_str()));
- DEBUG_LOG(("Config: [%s]\n", configURL.c_str()));
- DEBUG_LOG(("MOTD: [%s]\n", motdURL.c_str()));
- ghttpGet(gameURL.c_str(), GHTTPFalse, gamePatchCheckCallback, (void *)timeThroughOnline);
- ghttpGet(mapURL.c_str(), GHTTPFalse, gamePatchCheckCallback, (void *)timeThroughOnline);
- ghttpHead(configURL.c_str(), GHTTPFalse, configHeadCallback, (void *)timeThroughOnline);
- ghttpGet(motdURL.c_str(), GHTTPFalse, motdCallback, (void *)timeThroughOnline);
-
- // check total game stats
- CheckOverallStats();
-
- // check the users online
- CheckNumPlayersOnline();
-}
-
-///////////////////////////////////////////////////////////////////////////////////////
diff --git a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/PeerDefs.cpp b/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/PeerDefs.cpp
deleted file mode 100644
index 9f930de2908..00000000000
--- a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/PeerDefs.cpp
+++ /dev/null
@@ -1,938 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-// FILE: PeerDefs.cpp //////////////////////////////////////////////////////
-// Generals GameSpy Peer (chat) definitions
-// Author: Matthew D. Campbell, June 2002
-
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-#include
-
-#include "Common/GameState.h"
-#include "Common/RandomValue.h"
-#include "Common/IgnorePreferences.h"
-#include "Common/CustomMatchPreferences.h"
-#include "Common/GameSpyMiscPreferences.h"
-#include "Common/Recorder.h"
-#include "Common/Player.h"
-#include "Common/PlayerList.h"
-#include "Common/PlayerTemplate.h"
-#include "GameClient/MapUtil.h"
-#include "GameClient/ShellHooks.h"
-#include "GameClient/GameText.h"
-#include "GameNetwork/GameSpy/LadderDefs.h"
-#include "GameNetwork/GameSpy/PeerDefsImplementation.h"
-#include "GameNetwork/GameSpy/BuddyThread.h"
-#include "GameNetwork/GameSpy/PeerThread.h"
-#include "GameNetwork/GameSpy/PingThread.h"
-#include "GameNetwork/GameSpy/PersistentStorageThread.h"
-#include "GameNetwork/GameSpy/GSConfig.h"
-#include "GameNetwork/GameSpyOverlay.h"
-#include "GameNetwork/RankPointValue.h"
-#include "GameLogic/GameLogic.h"
-
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-
-GameSpyInfoInterface *TheGameSpyInfo = NULL;
-GameSpyStagingRoom *TheGameSpyGame = NULL;
-void deleteNotificationBox( void );
-
-bool AsciiComparator::operator()(AsciiString s1, AsciiString s2) const
-{
- return stricmp(s1.str(), s2.str()) < 0;
-}
-
-GameSpyInfo::GameSpyInfo()
-{
- reset();
- TheGameSpyGame = &m_localStagingRoom;
- m_isDisconAfterGameStart = FALSE;
-}
-
-GameSpyInfo::~GameSpyInfo()
-{
- TheGameSpyGame = NULL;
- reset();
-}
-
-void GameSpyInfo::reset( void )
-{
- m_sawFullGameList = FALSE;
- m_isDisconAfterGameStart = FALSE;
- m_currentGroupRoomID = 0;
- clearGroupRoomList();
- clearStagingRoomList();
- m_localStagingRoomID = 0;
- m_buddyRequestMap.clear();
- m_buddyMap.clear();
- m_buddyMessages.clear();
- m_joinedStagingRoom = 0;
- m_isHosting = false;
- m_localStagingRoomID = 0;
- m_localStagingRoom.reset();
- m_gotGroupRoomList = false;
- m_localName = "";
- m_localProfileID = 0;
- m_maxMessagesPerUpdate = 100;
-
- // Added By Sadullah Nader
- // Initialization missing and needed
- m_disallowAsainText = FALSE;
- m_disallowNonAsianText = FALSE;
- m_disconReason = 0;
- m_localBaseName.clear();
- m_localEmail.clear();
- m_localPasswd.clear();
- m_pingString.clear();
- m_rawConfig.clear();
- m_rawMotd.clear();
- //
-
- m_internalIP = m_externalIP = 0;
-
- m_savedIgnoreMap.clear();
- m_preorderPlayers.clear();
-
- m_cachedLocalPlayerStats.reset();
-
- m_additionalDisconnects = -1;
-}
-
-Bool GameSpyInfo::didPlayerPreorder( Int profileID ) const
-{
- std::set::const_iterator it = m_preorderPlayers.find(profileID);
- return (it != m_preorderPlayers.end());
-}
-
-void GameSpyInfo::markPlayerAsPreorder( Int profileID )
-{
- m_preorderPlayers.insert(profileID);
-}
-
-void GameSpyInfo::setLocalIPs(UnsignedInt internalIP, UnsignedInt externalIP)
-{
- m_internalIP = internalIP;
- m_externalIP = externalIP;
-}
-
-void GameSpyInfo::readAdditionalDisconnects( void )
-{
- m_additionalDisconnects = GetAdditionalDisconnectsFromUserFile(m_localProfileID);
- DEBUG_LOG(("GameSpyInfo::readAdditionalDisconnects() found %d disconnects.\n", m_additionalDisconnects));
-}
-
-Int GameSpyInfo::getAdditionalDisconnects( void )
-{
- DEBUG_LOG(("GameSpyInfo::getAdditionalDisconnects() would have returned %d. Returning 0 instead.\n", m_additionalDisconnects));
- return 0;
-}
-
-void GameSpyInfo::clearAdditionalDisconnects( void )
-{
- m_additionalDisconnects = 0;
-}
-
-GameSpyInfoInterface* GameSpyInfoInterface::createNewGameSpyInfoInterface( void )
-{
- return NEW GameSpyInfo;
-}
-
-Bool GameSpyInfo::amIHost( void )
-{
- return m_isHosting;
-}
-
-GameSpyStagingRoom* GameSpyInfo::getCurrentStagingRoom( void )
-{
- if (m_isHosting || m_joinedStagingRoom)
- return &m_localStagingRoom;
-
- StagingRoomMap::iterator it = m_stagingRooms.find(m_joinedStagingRoom);
- if (it != m_stagingRooms.end())
- return it->second;
-
- return NULL;
-}
-
-void GameSpyInfo::setGameOptions( void )
-{
- if (!m_isHosting)
- return;
-
- // set options for game lists, and UTM players in-game
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_SETGAMEOPTIONS;
- req.options = GameInfoToAsciiString(&m_localStagingRoom).str();
-
- Int i;
- AsciiString mapName = TheGameState->realMapPathToPortableMapPath(m_localStagingRoom.getMap());
- AsciiString newMapName;
- for (i=0; ifindMap(mapName);
- //if (!md)
- //return; // there really isn't any need to send info like this...
-
- req.gameOptions.numPlayers = 0;
- req.gameOptions.numObservers = 0;
- Int numOpenSlots = 0;
- AsciiString playerInfo = "";
- for (i=0; igetGameSpySlot(i);
- req.gameOptsPlayerNames[i] = "";
- if (!slot->isOccupied())
- {
- if (slot->isOpen())
- ++numOpenSlots;
- }
- else
- {
- AsciiString playerName;
- if (slot->isHuman())
- {
- playerName.translate(slot->getName());
- req.gameOptsPlayerNames[i] = playerName.str();
- PlayerInfoMap::iterator it = m_playerInfoMap.find(playerName);
- if (it != m_playerInfoMap.end())
- {
- wins = it->second.m_wins;
- losses = it->second.m_losses;
- profileID = it->second.m_profileID;
- }
- req.gameOptions.wins[req.gameOptions.numObservers+req.gameOptions.numPlayers] = wins;
- req.gameOptions.losses[req.gameOptions.numObservers+req.gameOptions.numPlayers] = losses;
- req.gameOptions.profileID[req.gameOptions.numObservers+req.gameOptions.numPlayers] = profileID;
- req.gameOptions.faction[req.gameOptions.numObservers+req.gameOptions.numPlayers] = slot->getPlayerTemplate();
- req.gameOptions.color[req.gameOptions.numObservers+req.gameOptions.numPlayers] = slot->getColor();
- if (slot->getPlayerTemplate() == PLAYERTEMPLATE_OBSERVER)
- {
- ++req.gameOptions.numObservers;
- }
- else
- {
- ++req.gameOptions.numPlayers;
- }
- }
- else if (slot->isAI())
- {
- // add in AI players
- switch (slot->getState())
- {
- case SLOT_EASY_AI:
- playerName = "CE";
- break;
- case SLOT_MED_AI:
- playerName = "CM";
- break;
- case SLOT_BRUTAL_AI:
- playerName = "CH";
- break;
- }
- req.gameOptsPlayerNames[i] = playerName.str(); // name is unused - we go off of the profileID
- req.gameOptions.wins[req.gameOptions.numObservers+req.gameOptions.numPlayers] = 0;
- req.gameOptions.losses[req.gameOptions.numObservers+req.gameOptions.numPlayers] = 0;
- req.gameOptions.profileID[req.gameOptions.numObservers+req.gameOptions.numPlayers] = slot->getState();
- req.gameOptions.faction[req.gameOptions.numObservers+req.gameOptions.numPlayers] = slot->getPlayerTemplate();
- req.gameOptions.color[req.gameOptions.numObservers+req.gameOptions.numPlayers] = slot->getColor();
- ++req.gameOptions.numPlayers;
- }
- }
- }
- req.gameOptions.maxPlayers = numOpenSlots + req.gameOptions.numPlayers + req.gameOptions.numObservers;
- TheGameSpyPeerMessageQueue->addRequest(req);
-
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMROOM;
- req.UTM.isStagingRoom = TRUE;
- req.id = "Pings/";
- AsciiString pings;
- for (i=0; igetGameSpySlot(i);
- if (slot && slot->isHuman())
- {
- pings.concat(slot->getPingString());
- }
- else
- {
- pings.concat("0");
- }
- }
- req.options = pings.str();
- TheGameSpyPeerMessageQueue->addRequest(req);
-}
-
-Bool GameSpyInfo::isBuddy( Int id )
-{
- return m_buddyMap.find(id) != m_buddyMap.end();
-}
-
-void GameSpyInfo::addGroupRoom( GameSpyGroupRoom room )
-{
- if (room.m_groupID == 0)
- {
- m_gotGroupRoomList = TRUE;
-
- GroupRoomMap::iterator iter;
-
- // figure out how many good strings we've got
- std::vector names;
- Int numRooms = 0;
- for (iter = getGroupRoomList()->begin(); iter != getGroupRoomList()->end(); ++iter)
- {
- GameSpyGroupRoom room = iter->second;
- if (room.m_groupID != TheGameSpyConfig->getQMChannel())
- {
- ++numRooms;
-
- AsciiString groupLabel;
- groupLabel.format("GUI:%s", room.m_name.str());
-
- Bool exists = FALSE;
- UnicodeString groupName = TheGameText->fetch(groupLabel, &exists);
- if (exists)
- {
- names.push_back(groupName);
- }
- }
- }
-
- if (!names.empty() && names.size() != numRooms)
- {
- // didn't get all names. fix up
- Int nameIndex = 0;
- Int timesThrough = 1; // start with USA Lobby 1
- for (iter = TheGameSpyInfo->getGroupRoomList()->begin(); iter != TheGameSpyInfo->getGroupRoomList()->end(); ++iter)
- {
- GameSpyGroupRoom room = iter->second;
- if (room.m_groupID != TheGameSpyConfig->getQMChannel())
- {
- room.m_translatedName.format(L"%ls %d", names[nameIndex].str(), timesThrough);
- nameIndex = (nameIndex+1)%names.size();
- m_groupRooms[room.m_groupID] = room;
- if (!nameIndex)
- {
- // we've looped through the name list already. increment the timesThrough counter
- ++timesThrough;
- }
- }
- }
- }
- }
- else
- {
- DEBUG_LOG(("Adding group room %d (%s)\n", room.m_groupID, room.m_name.str()));
- AsciiString groupLabel;
- groupLabel.format("GUI:%s", room.m_name.str());
- room.m_translatedName = TheGameText->fetch(groupLabel);
- m_groupRooms[room.m_groupID] = room;
- if ( !stricmp("quickmatch", room.m_name.str()) )
- {
- DEBUG_LOG(("Group room %d (%s) is the QuickMatch room\n", room.m_groupID, room.m_name.str()));
- TheGameSpyConfig->setQMChannel(room.m_groupID);
- }
- }
-}
-
-void GameSpyInfo::joinGroupRoom( Int groupID )
-{
- if (groupID > 0)
- {
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_JOINGROUPROOM;
- req.groupRoom.id = groupID;
- TheGameSpyPeerMessageQueue->addRequest(req);
- m_playerInfoMap.clear();
- }
-}
-
-void GameSpyInfo::leaveGroupRoom( void )
-{
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_LEAVEGROUPROOM;
- TheGameSpyPeerMessageQueue->addRequest(req);
- setCurrentGroupRoom(0);
- m_playerInfoMap.clear();
-}
-
-void GameSpyInfo::joinBestGroupRoom( void )
-{
- if (m_currentGroupRoomID)
- {
- DEBUG_LOG(("Bailing from GameSpyInfo::joinBestGroupRoom() - we were already in a room\n"));
- m_currentGroupRoomID = 0;
- return;
- }
-
- if (m_groupRooms.size())
- {
- int minID = -1;
- int minPlayers = 1000;
- GroupRoomMap::iterator iter = m_groupRooms.begin();
- while (iter != m_groupRooms.end())
- {
- GameSpyGroupRoom room = iter->second;
- DEBUG_LOG(("Group room %d: %s (%d, %d, %d, %d)\n", room.m_groupID, room.m_name.str(), room.m_numWaiting, room.m_maxWaiting,
- room.m_numGames, room.m_numPlaying));
-
- if (TheGameSpyConfig->getQMChannel() != room.m_groupID && minPlayers > 25 && room.m_numWaiting < minPlayers)
- {
- minID = room.m_groupID;
- minPlayers = room.m_numWaiting;
- }
-
- ++iter;
- }
-
- if (minID > 0)
- {
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_JOINGROUPROOM;
- req.groupRoom.id = minID;
- TheGameSpyPeerMessageQueue->addRequest(req);
- m_playerInfoMap.clear();
- }
- else
- {
- GSMessageBoxOk(TheGameText->fetch("GUI:Error"), TheGameText->fetch("GUI:GSGroupRoomJoinFail"), NULL);
- }
- }
- else
- {
- GSMessageBoxOk(TheGameText->fetch("GUI:Error"), TheGameText->fetch("GUI:GSGroupRoomJoinFail"), NULL);
- }
-}
-
-void GameSpyInfo::updatePlayerInfo( PlayerInfo pi, AsciiString oldNick )
-{
- if (!oldNick.isEmpty())
- playerLeftGroupRoom(oldNick);
-
- m_playerInfoMap[pi.m_name] = pi;
-
- if (pi.m_preorder != 0)
- markPlayerAsPreorder(pi.m_profileID);
-}
-
-void GameSpyInfo::playerLeftGroupRoom( AsciiString nick )
-{
- PlayerInfoMap::iterator it = m_playerInfoMap.find(nick);
- if (it != m_playerInfoMap.end())
- {
- m_playerInfoMap.erase(it);
- }
-}
-
-void GameSpyInfo::clearStagingRoomList( void )
-{
- Int numRoomsRemoved = 0;
- m_sawFullGameList = FALSE;
- m_stagingRoomsDirty = FALSE;
-
- StagingRoomMap::iterator it = m_stagingRooms.begin();
- while (it != m_stagingRooms.end())
- {
- ++numRoomsRemoved;
-
- delete it->second;
- m_stagingRooms.erase(it);
- it = m_stagingRooms.begin();
- }
- if (numRoomsRemoved > 0)
- {
- //m_stagingRoomsDirty = true; // only consider ourselves dirty if we actually removed some games.
- }
-}
-
-void GameSpyInfo::addStagingRoom( GameSpyStagingRoom room )
-{
- removeStagingRoom(room);
- GameSpyStagingRoom *newRoom = NEW GameSpyStagingRoom;
- *newRoom = room;
- newRoom->cleanUpSlotPointers();
- m_stagingRooms[room.getID()] = newRoom;
- m_stagingRoomsDirty = m_sawFullGameList;
-}
-
-void GameSpyInfo::updateStagingRoom( GameSpyStagingRoom room )
-{
- addStagingRoom(room);
-}
-
-void GameSpyInfo::removeStagingRoom( GameSpyStagingRoom room )
-{
- StagingRoomMap::iterator it = m_stagingRooms.find(room.getID());
- if (it != m_stagingRooms.end())
- {
- delete it->second;
- m_stagingRooms.erase(it);
-
- m_stagingRoomsDirty = m_sawFullGameList;
- }
-}
-
-Bool GameSpyInfo::hasStagingRoomListChanged( void )
-{
- Bool val = m_stagingRoomsDirty;
- m_stagingRoomsDirty = false;
- return val;
-}
-
-GameSpyStagingRoom* GameSpyInfo::findStagingRoomByID( Int id )
-{
- StagingRoomMap::iterator it = m_stagingRooms.find(id);
- if (it != m_stagingRooms.end())
- return it->second;
-
- return NULL;
-}
-
-void GameSpyInfo::leaveStagingRoom( void )
-{
- m_localStagingRoomID = 0;
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_LEAVESTAGINGROOM;
- TheGameSpyPeerMessageQueue->addRequest(req);
- m_playerInfoMap.clear();
- m_joinedStagingRoom = FALSE;
- m_isHosting = FALSE;
-}
-
-void GameSpyInfo::markAsStagingRoomHost( void )
-{
- m_localStagingRoomID = 0;
- m_joinedStagingRoom = FALSE; m_isHosting = TRUE;
- m_localStagingRoom.reset();
- m_localStagingRoom.enterGame();
- m_localStagingRoom.setSeed(GetTickCount());
-
- GameSlot newSlot;
- UnicodeString uName;
- uName.translate(m_localName);
- newSlot.setState(SLOT_PLAYER, uName);
-
- m_localStagingRoom.setLocalIP(m_externalIP);
- newSlot.setIP(m_externalIP);
-
- m_localStagingRoom.setSlot(0,newSlot);
- m_localStagingRoom.setLocalName(m_localName);
-
- TheMapCache->updateCache();
- m_localStagingRoom.setMap(getDefaultMap(TRUE));
- m_localStagingRoom.adjustSlotsForMap(); // close slots that the map can't hold. BGC
-}
-
-void GameSpyInfo::markAsStagingRoomJoiner( Int game )
-{
- m_localStagingRoomID = game;
- m_joinedStagingRoom = TRUE; m_isHosting = FALSE;
- m_localStagingRoom.reset();
- m_localStagingRoom.enterGame();
- StagingRoomMap::iterator it = m_stagingRooms.find(game);
- if (it != m_stagingRooms.end())
- {
- GameSpyStagingRoom *info = it->second;
- info->cleanUpSlotPointers();
- AsciiString options = GameInfoToAsciiString(info);
-#ifdef DEBUG_CRASHING
- Bool res =
-#endif
- ParseAsciiStringToGameInfo(&m_localStagingRoom, options);
- DEBUG_ASSERTCRASH(res, ("Could not parse game info \"%s\"", options.str()));
- m_localStagingRoom.setInGame();
- m_localStagingRoom.setLocalName(m_localName);
- m_localStagingRoom.setExeCRC(info->getExeCRC());
- m_localStagingRoom.setIniCRC(info->getIniCRC());
- m_localStagingRoom.setAllowObservers(info->getAllowObservers());
- m_localStagingRoom.setHasPassword(info->getHasPassword());
- m_localStagingRoom.setGameName(info->getGameName());
- DEBUG_LOG(("Joining game: host is %ls\n", m_localStagingRoom.getConstSlot(0)->getName().str()));
- }
-}
-
-void GameSpyInfo::setMOTD( const AsciiString& motd )
-{
- m_rawMotd = motd;
-}
-
-const AsciiString& GameSpyInfo::getMOTD( void )
-{
- return m_rawMotd;
-}
-
-void GameSpyInfo::setConfig( const AsciiString& config )
-{
- m_rawConfig = config;
-}
-
-const AsciiString& GameSpyInfo::getConfig( void )
-{
- return m_rawConfig;
-}
-
-// --------------------------------------------------------------
-void SetUpGameSpy( const char *motdBuffer, const char *configBuffer )
-{
- if (!motdBuffer)
- motdBuffer = "";
- if (!configBuffer)
- configBuffer = "";
- TearDownGameSpy();
-
- AsciiString dir = TheGlobalData->getPath_UserData();
- CreateDirectory(dir.str(), NULL);
- dir.format("%sGeneralsOnline", TheGlobalData->getPath_UserData().str());
- CreateDirectory(dir.str(), NULL);
- dir.format("%sGeneralsOnline\\Ladders", TheGlobalData->getPath_UserData().str());
- CreateDirectory(dir.str(), NULL);
-
- TheGameSpyBuddyMessageQueue = GameSpyBuddyMessageQueueInterface::createNewMessageQueue();
- TheGameSpyBuddyMessageQueue->startThread();
-
- TheGameSpyPeerMessageQueue = GameSpyPeerMessageQueueInterface::createNewMessageQueue();
- TheGameSpyPeerMessageQueue->startThread();
-
- TheGameSpyPSMessageQueue = GameSpyPSMessageQueueInterface::createNewMessageQueue();
- TheGameSpyPSMessageQueue->startThread();
-
- /*
- TheGameSpyGame = NEW GameSpyStagingRoom;
- */
-
- TheGameSpyInfo = GameSpyInfoInterface::createNewGameSpyInfoInterface();
- TheGameSpyInfo->setMOTD(motdBuffer);
- TheGameSpyInfo->setConfig(configBuffer);
-
- CustomMatchPreferences pref;
- TheGameSpyInfo->setDisallowAsianText(pref.getDisallowAsianText());
- TheGameSpyInfo->setDisallowNonAsianText( pref.getDisallowNonAsianText());
-
-
- TheGameSpyConfig = GameSpyConfigInterface::create(configBuffer);
-
- TheLadderList = NEW LadderList;
-
- ThePinger = PingerInterface::createNewPingerInterface();
- ThePinger->startThreads();
-
- TheRankPointValues = NEW RankPoints;
-}
-
-void TearDownGameSpy( void )
-{
- // save off cached stats
- if (TheGameSpyInfo && TheGameSpyInfo->getLocalProfileID())
- {
-// /* This was done on the score screen, so there is no need to do it now.
-// *
- PSPlayerStats localPSStats = TheGameSpyPSMessageQueue->findPlayerStatsByID(TheGameSpyInfo->getLocalProfileID());
- if (localPSStats.id != 0)
- {
- GameSpyMiscPreferences mPref;
- mPref.setCachedStats(GameSpyPSMessageQueueInterface::formatPlayerKVPairs(localPSStats).c_str());
- mPref.write();
- }
-// */
- }
-
- // End our threads before we kill off the singletons they reference. No crashy-crash for you!
- if (TheGameSpyPSMessageQueue)
- TheGameSpyPSMessageQueue->endThread();
- if (TheGameSpyBuddyMessageQueue)
- TheGameSpyBuddyMessageQueue->endThread();
- if (TheGameSpyPeerMessageQueue)
- TheGameSpyPeerMessageQueue->endThread();
- if (ThePinger)
- ThePinger->endThreads();
-
- if(TheRankPointValues)
- {
- delete TheRankPointValues;
- TheRankPointValues = NULL;
- }
- if (TheGameSpyPSMessageQueue)
- {
- delete TheGameSpyPSMessageQueue;
- TheGameSpyPSMessageQueue = NULL;
- }
-
- if (TheGameSpyBuddyMessageQueue)
- {
- delete TheGameSpyBuddyMessageQueue;
- TheGameSpyBuddyMessageQueue = NULL;
- }
-
- if (TheGameSpyPeerMessageQueue)
- {
- delete TheGameSpyPeerMessageQueue;
- TheGameSpyPeerMessageQueue = NULL;
- }
-
- if (TheGameSpyInfo)
- {
- if (TheGameSpyInfo->getInternalIP())
- {
- // we've logged in before. mark us as logging out.
- SignalUIInteraction(SHELL_SCRIPT_HOOK_GENERALS_ONLINE_LOGOUT);
- }
- delete TheGameSpyInfo;
- TheGameSpyInfo = NULL;
- }
-
- if (ThePinger)
- {
- delete ThePinger;
- ThePinger = NULL;
- }
-
- if (TheLadderList)
- {
- delete TheLadderList;
- TheLadderList = NULL;
- }
-
- if (TheGameSpyConfig)
- {
- delete TheGameSpyConfig;
- TheGameSpyConfig = NULL;
- }
-
- // make sure the notification box doesn't exist
- deleteNotificationBox();
-}
-
-
-void GameSpyInfo::addToIgnoreList( AsciiString nick )
-{
- m_ignoreList.insert(nick);
-}
-
-void GameSpyInfo::removeFromIgnoreList( AsciiString nick )
-{
- m_ignoreList.erase(nick);
-}
-
-Bool GameSpyInfo::isIgnored( AsciiString nick )
-{
- return m_ignoreList.find(nick) != m_ignoreList.end();
-}
-
-IgnoreList GameSpyInfo::returnIgnoreList( void )
-{
- return m_ignoreList;
-}
-
-void GameSpyInfo::addToSavedIgnoreList( Int profileID, AsciiString nick)
-{
- m_savedIgnoreMap[profileID] = nick;
- IgnorePreferences pref;
- pref.setIgnore(nick, profileID, true);
- pref.write();
-}
-
-void GameSpyInfo::removeFromSavedIgnoreList( Int profileID )
-{
- m_savedIgnoreMap.erase(profileID);
- IgnorePreferences pref;
- pref.setIgnore(AsciiString::TheEmptyString, profileID, false);
- pref.write();
-}
-
-Bool GameSpyInfo::isSavedIgnored( Int profileID )
-{
- return m_savedIgnoreMap.find(profileID) != m_savedIgnoreMap.end();
-}
-
-SavedIgnoreMap GameSpyInfo::returnSavedIgnoreList( void )
-{
- return m_savedIgnoreMap;
-}
-
-static Int grabHexInt(const char *s)
-{
- char tmp[5] = "0xff";
- tmp[2] = s[0];
- tmp[3] = s[1];
- Int b = strtol(tmp, NULL, 16);
- return b;
-}
-
-Int GameSpyInfo::getPingValue( const AsciiString& otherPing )
-{
- if (m_pingString.getLength() != otherPing.getLength())
- {
- return TheGameSpyConfig->getPingTimeoutInMs();
- }
-
- if (m_pingString.getLength() % 2 != 0)
- {
- return TheGameSpyConfig->getPingTimeoutInMs();
- }
-
- Int best = 255+255;
- const char *myStr = m_pingString.str();
- const char *otherStr = otherPing.str();
-
- while (*myStr)
- {
- Int myVal = grabHexInt(myStr);
- Int otherVal = grabHexInt(otherStr);
- Int val = myVal + otherVal;
- best = (val < best) ? val : best;
- myStr += 2;
- otherStr += 2;
- }
-
- return best * TheGameSpyConfig->getPingTimeoutInMs() / (255+255);
-}
-
-Bool PlayerInfo::isIgnored( void )
-{
- return (m_profileID)?TheGameSpyInfo->isSavedIgnored(m_profileID):TheGameSpyInfo->isIgnored(m_name);
-}
-
-void GameSpyInfo::loadSavedIgnoreList( void )
-{
- m_savedIgnoreMap.clear();
- IgnorePreferences prefs;
- m_savedIgnoreMap = prefs.getIgnores();
-}
-
-void GameSpyInfo::setDisallowAsianText( Bool val )
-{
- m_disallowAsainText = val;
-}
-
-void GameSpyInfo::setDisallowNonAsianText( Bool val )
-{
- m_disallowNonAsianText = val;
-}
-
-Bool GameSpyInfo::getDisallowAsianText( void )
-{
- return m_disallowAsainText;
-}
-Bool GameSpyInfo::getDisallowNonAsianText(void )
-{
- return m_disallowNonAsianText;
-}
-
-void GameSpyInfo::setMaxMessagesPerUpdate( Int num )
-{
- m_maxMessagesPerUpdate = num;
-}
-
-Int GameSpyInfo::getMaxMessagesPerUpdate( void )
-{
- return m_maxMessagesPerUpdate;
-}
-
-/**This function is used to force an update of player's gamespy stats with an additional
-disconnection. This is used upon starting a new game so that if user disconnects prior
-to finishing game, the disconnection stays on the server. If he completes the game, we
-remove this extra disconnection inside of populatePlayerInfo() on the ScoreScreen. This
-seems like the only secure way to handle this issue since users can abort the process
-before we can detect/log disconnections.*/
-void GameSpyInfo::updateAdditionalGameSpyDisconnections(Int count)
-{
- if (TheRecorder->isMultiplayer() && TheGameLogic->isInInternetGame())
- {
- Int localID = TheGameSpyInfo->getLocalProfileID();
- PSPlayerStats stats = TheGameSpyPSMessageQueue->findPlayerStatsByID(localID);
-
- Player *player=ThePlayerList->getLocalPlayer();
-
- Int ptIdx;
- const PlayerTemplate *myTemplate = player->getPlayerTemplate();
- DEBUG_LOG(("myTemplate = %X(%s)\n", myTemplate, myTemplate->getName().str()));
- for (ptIdx = 0; ptIdx < ThePlayerTemplateStore->getPlayerTemplateCount(); ++ptIdx)
- {
- const PlayerTemplate *nthTemplate = ThePlayerTemplateStore->getNthPlayerTemplate(ptIdx);
- DEBUG_LOG(("nthTemplate = %X(%s)\n", nthTemplate, nthTemplate->getName().str()));
- if (nthTemplate == myTemplate)
- {
- break;
- }
- }
-
- Bool anyAI = FALSE;
- for (Int i=0; igetConstSlot(i);
-
- if (slot->isAI())
- {
- anyAI = TRUE;
- }
- }
-
- //Check for cases where we're not tracking stats.
- if (anyAI || stats.id == 0 || myTemplate->isObserver() || player->getPlayerType() != PLAYER_HUMAN || player->isPlayerObserver())
- return;
-
- Int disCons=stats.discons[ptIdx];
- disCons += count;
- if (disCons < 0)
- { DEBUG_LOG(("updateAdditionalGameSpyDisconnections() - disconnection count below zero\n"));
- return; //something is wrong here
- }
- stats.discons[ptIdx] = disCons; //add an additional disconnection to their stats.
-
- //Add an additional disconnection to player stats.
- PSRequest req;
-
- req.requestType = PSRequest::PSREQUEST_UPDATEPLAYERSTATS;
- req.email = TheGameSpyInfo->getLocalEmail().str();
- req.nick = TheGameSpyInfo->getLocalBaseName().str();
- req.password = TheGameSpyInfo->getLocalPassword().str();
- req.player = stats;
- req.addDesync = FALSE;
- req.addDiscon = FALSE;
- req.lastHouse = ptIdx;
-
- TheGameSpyPSMessageQueue->addRequest(req);
- TheGameSpyPSMessageQueue->trackPlayerStats(stats);
-
- // force an update of our shtuff
- PSResponse newResp;
- newResp.responseType = PSResponse::PSRESPONSE_PLAYERSTATS;
- newResp.player = stats;
- TheGameSpyPSMessageQueue->addResponse(newResp);
-
- // cache our stuff for easy reading next time
- GameSpyMiscPreferences mPref;
- mPref.setCachedStats(GameSpyPSMessageQueueInterface::formatPlayerKVPairs(stats).c_str());
- mPref.write();
- }
-}
diff --git a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/StagingRoomGameInfo.cpp b/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/StagingRoomGameInfo.cpp
deleted file mode 100644
index 19452faae11..00000000000
--- a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/StagingRoomGameInfo.cpp
+++ /dev/null
@@ -1,896 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: StagingRoomGameInfo.cpp //////////////////////////////////////////////////////
-// Generals GameSpy GameInfo-related code
-// Author: Matthew D. Campbell, July 2002
-
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/GameState.h"
-#include "Common/Player.h"
-#include "Common/PlayerList.h"
-#include "Common/PlayerTemplate.h"
-#include "Common/RandomValue.h"
-#include "Common/ScoreKeeper.h"
-#include "GameClient/GameText.h"
-#include "GameClient/MapUtil.h"
-#include "GameClient/Shell.h"
-#include "GameLogic/GameLogic.h"
-#include "GameLogic/VictoryConditions.h"
-#include "GameNetwork/FileTransfer.h"
-#include "GameNetwork/GameSpy/BuddyThread.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpy/PersistentStorageThread.h"
-#include "GameNetwork/GameSpy/ThreadUtils.h"
-#include "GameNetwork/GameSpyOverlay.h"
-#include "GameNetwork/NAT.h"
-#include "GameNetwork/NetworkInterface.h"
-
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-
-// GameSpyGameSlot -------------------------------------------
-
-GameSpyGameSlot::GameSpyGameSlot()
-{
- GameSlot();
- m_gameSpyLogin.clear();
- m_gameSpyLocale.clear();
- m_profileID = 0;
- m_wins = 0;
- m_losses = 0;
- m_rankPoints = 0;
- m_favoriteSide = 0;
- m_pingInt = 0;
- // Added By Sadullah Nader
- // Initializations missing and needed
- m_profileID = 0;
- m_pingStr.clear();
-}
-
-// Helper Functions ----------------------------------------
-/*
-** Function definitions for the MIB-II entry points.
-*/
-
-BOOL (__stdcall *SnmpExtensionInitPtr)(IN DWORD dwUpTimeReference, OUT HANDLE *phSubagentTrapEvent, OUT AsnObjectIdentifier *pFirstSupportedRegion);
-BOOL (__stdcall *SnmpExtensionQueryPtr)(IN BYTE bPduType, IN OUT RFC1157VarBindList *pVarBindList, OUT AsnInteger32 *pErrorStatus, OUT AsnInteger32 *pErrorIndex);
-LPVOID (__stdcall *SnmpUtilMemAllocPtr)(IN DWORD bytes);
-VOID (__stdcall *SnmpUtilMemFreePtr)(IN LPVOID pMem);
-
-typedef struct tConnInfoStruct {
- unsigned int State;
- unsigned long LocalIP;
- unsigned short LocalPort;
- unsigned long RemoteIP;
- unsigned short RemotePort;
-} ConnInfoStruct;
-
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
-#endif
-
-/***********************************************************************************************
- * Get_Local_Chat_Connection_Address -- Which address are we using to talk to the chat server? *
- * *
- * *
- * *
- * INPUT: Ptr to address to return local address * *
- * *
- * OUTPUT: True if success *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 10/27/00 3:24PM ST : Created *
- *=============================================================================================*/
-Bool GetLocalChatConnectionAddress(AsciiString serverName, UnsignedShort serverPort, UnsignedInt& localIP)
-{
- //return false;
- /*
- ** Local defines.
- */
- enum {
- CLOSED = 1,
- LISTENING,
- SYN_SENT,
- SEN_RECEIVED,
- ESTABLISHED,
- FIN_WAIT,
- FIN_WAIT2,
- CLOSE_WAIT,
- LAST_ACK,
- CLOSING,
- TIME_WAIT,
- DELETE_TCB
- };
-
- enum {
- tcpConnState = 1,
- tcpConnLocalAddress,
- tcpConnLocalPort,
- tcpConnRemAddress,
- tcpConnRemPort
- };
-
-
- /*
- ** Locals.
- */
- unsigned char serverAddress[4];
- unsigned char remoteAddress[4];
- HANDLE trap_handle;
- AsnObjectIdentifier first_supported_region;
- std::vector connectionVector;
- int last_field;
- int index;
- AsnInteger error_status;
- AsnInteger error_index;
- int conn_entry_type_index;
- int conn_entry_type;
- Bool found;
-
- /*
- ** Statics.
- */
- static char _conn_state[][32] = {
- "?",
- "CLOSED",
- "LISTENING",
- "SYN_SENT",
- "SEN_RECEIVED",
- "ESTABLISHED",
- "FIN_WAIT",
- "FIN_WAIT2",
- "CLOSE_WAIT",
- "LAST_ACK",
- "CLOSING",
- "TIME_WAIT",
- "DELETE_TCB"
- };
-
- DEBUG_LOG(("Finding local address used to talk to the chat server\n"));
- DEBUG_LOG(("Current chat server name is %s\n", serverName.str()));
- DEBUG_LOG(("Chat server port is %d\n", serverPort));
-
- /*
- ** Get the address of the chat server.
- */
- DEBUG_LOG( ("About to call gethostbyname\n"));
- struct hostent *host_info = gethostbyname(serverName.str());
-
- if (!host_info) {
- DEBUG_LOG( ("gethostbyname failed! Error code %d\n", WSAGetLastError()));
- return(false);
- }
-
- memcpy(serverAddress, &host_info->h_addr_list[0][0], 4);
- unsigned long temp = *((unsigned long*)(&serverAddress[0]));
- temp = ntohl(temp);
- *((unsigned long*)(&serverAddress[0])) = temp;
-
- DEBUG_LOG(("Host address is %d.%d.%d.%d\n", serverAddress[3], serverAddress[2], serverAddress[1], serverAddress[0]));
-
- /*
- ** Load the MIB-II SNMP DLL.
- */
- DEBUG_LOG(("About to load INETMIB1.DLL\n"));
-
- HINSTANCE mib_ii_dll = LoadLibrary("inetmib1.dll");
- if (mib_ii_dll == NULL) {
- DEBUG_LOG(("Failed to load INETMIB1.DLL\n"));
- return(false);
- }
-
- DEBUG_LOG(("About to load SNMPAPI.DLL\n"));
-
- HINSTANCE snmpapi_dll = LoadLibrary("snmpapi.dll");
- if (snmpapi_dll == NULL) {
- DEBUG_LOG(("Failed to load SNMPAPI.DLL\n"));
- FreeLibrary(mib_ii_dll);
- return(false);
- }
-
- /*
- ** Get the function pointers into the .dll
- */
- SnmpExtensionInitPtr = (int (__stdcall *)(unsigned long,void ** ,AsnObjectIdentifier *)) GetProcAddress(mib_ii_dll, "SnmpExtensionInit");
- SnmpExtensionQueryPtr = (int (__stdcall *)(unsigned char,SnmpVarBindList *,long *,long *)) GetProcAddress(mib_ii_dll, "SnmpExtensionQuery");
- SnmpUtilMemAllocPtr = (void *(__stdcall *)(unsigned long)) GetProcAddress(snmpapi_dll, "SnmpUtilMemAlloc");
- SnmpUtilMemFreePtr = (void (__stdcall *)(void *)) GetProcAddress(snmpapi_dll, "SnmpUtilMemFree");
- if (SnmpExtensionInitPtr == NULL || SnmpExtensionQueryPtr == NULL || SnmpUtilMemAllocPtr == NULL || SnmpUtilMemFreePtr == NULL) {
- DEBUG_LOG(("Failed to get proc addresses for linked functions\n"));
- FreeLibrary(snmpapi_dll);
- FreeLibrary(mib_ii_dll);
- return(false);
- }
-
-
- RFC1157VarBindList *bind_list_ptr = (RFC1157VarBindList *) SnmpUtilMemAllocPtr(sizeof(RFC1157VarBindList));
- RFC1157VarBind *bind_ptr = (RFC1157VarBind *) SnmpUtilMemAllocPtr(sizeof(RFC1157VarBind));
-
- /*
- ** OK, here we go. Try to initialise the .dll
- */
- DEBUG_LOG(("About to init INETMIB1.DLL\n"));
- int ok = SnmpExtensionInitPtr(GetCurrentTime(), &trap_handle, &first_supported_region);
-
- if (!ok) {
- /*
- ** Aw crap.
- */
- DEBUG_LOG(("Failed to init the .dll\n"));
- SnmpUtilMemFreePtr(bind_list_ptr);
- SnmpUtilMemFreePtr(bind_ptr);
- FreeLibrary(snmpapi_dll);
- FreeLibrary(mib_ii_dll);
- return(false);
- }
-
- /*
- ** Name of mib_ii object we want to query. See RFC 1213.
- **
- ** iso.org.dod.internet.mgmt.mib-2.tcp.tcpConnTable.TcpConnEntry.tcpConnState
- ** 1 3 6 1 2 1 6 13 1 1
- */
- unsigned int mib_ii_name[] = {1,3,6,1,2,1,6,13,1,1};
- unsigned int *mib_ii_name_ptr = (unsigned int *) SnmpUtilMemAllocPtr(sizeof(mib_ii_name));
- memcpy(mib_ii_name_ptr, mib_ii_name, sizeof(mib_ii_name));
-
- /*
- ** Get the index of the conn entry data.
- */
- conn_entry_type_index = ARRAY_SIZE(mib_ii_name) - 1;
-
- /*
- ** Set up the bind list.
- */
- bind_ptr->name.idLength = ARRAY_SIZE(mib_ii_name);
- bind_ptr->name.ids = mib_ii_name;
- bind_list_ptr->list = bind_ptr;
- bind_list_ptr->len = 1;
-
-
- /*
- ** We start with the tcpConnLocalAddress field.
- */
- last_field = 1;
-
- /*
- ** First connection.
- */
- index = 0;
-
- /*
- ** Suck out that tcp connection info....
- */
- while (true) {
-
- if (!SnmpExtensionQueryPtr(SNMP_PDU_GETNEXT, bind_list_ptr, &error_status, &error_index)) {
- //if (!SnmpExtensionQueryPtr(ASN_RFC1157_GETNEXTREQUEST, bind_list_ptr, &error_status, &error_index)) {
- DEBUG_LOG(("SnmpExtensionQuery returned false\n"));
- SnmpUtilMemFreePtr(bind_list_ptr);
- SnmpUtilMemFreePtr(bind_ptr);
- FreeLibrary(snmpapi_dll);
- FreeLibrary(mib_ii_dll);
- return(false);
- }
-
- /*
- ** If this is something new we aren't looking for then we are done.
- */
- if (bind_ptr->name.idLength < ARRAY_SIZE(mib_ii_name)) {
- break;
- }
-
- /*
- ** Get the type of info we are looking at. See RFC1213.
- **
- ** 1 = tcpConnState
- ** 2 = tcpConnLocalAddress
- ** 3 = tcpConnLocalPort
- ** 4 = tcpConnRemAddress
- ** 5 = tcpConnRemPort
- **
- ** tcpConnState is one of the following...
- **
- ** 1 closed
- ** 2 listen
- ** 3 synSent
- ** 4 synReceived
- ** 5 established
- ** 6 finWait1
- ** 7 finWait2
- ** 8 closeWait
- ** 9 lastAck
- ** 10 closing
- ** 11 timeWait
- ** 12 deleteTCB
- */
- conn_entry_type = bind_ptr->name.ids[conn_entry_type_index];
-
- if (last_field != conn_entry_type) {
- index = 0;
- last_field = conn_entry_type;
- }
-
- switch (conn_entry_type) {
-
- /*
- ** 1. First field in the entry. Need to create a new connection info struct
- ** here to store this connection in.
- */
- case tcpConnState:
- {
- ConnInfoStruct new_conn;
- new_conn.State = bind_ptr->value.asnValue.number;
- connectionVector.push_back(new_conn);
- break;
- }
-
- /*
- ** 2. Local address field.
- */
- case tcpConnLocalAddress:
- DEBUG_ASSERTCRASH(index < connectionVector.size(), ("Bad connection index"));
- connectionVector[index].LocalIP = *((unsigned long*)bind_ptr->value.asnValue.address.stream);
- index++;
- break;
-
- /*
- ** 3. Local port field.
- */
- case tcpConnLocalPort:
- DEBUG_ASSERTCRASH(index < connectionVector.size(), ("Bad connection index"));
- connectionVector[index].LocalPort = bind_ptr->value.asnValue.number;
- //connectionVector[index]->LocalPort = ntohs(connectionVector[index]->LocalPort);
- index++;
- break;
-
- /*
- ** 4. Remote address field.
- */
- case tcpConnRemAddress:
- DEBUG_ASSERTCRASH(index < connectionVector.size(), ("Bad connection index"));
- connectionVector[index].RemoteIP = *((unsigned long*)bind_ptr->value.asnValue.address.stream);
- index++;
- break;
-
- /*
- ** 5. Remote port field.
- */
- case tcpConnRemPort:
- DEBUG_ASSERTCRASH(index < connectionVector.size(), ("Bad connection index"));
- connectionVector[index].RemotePort = bind_ptr->value.asnValue.number;
- //connectionVector[index]->RemotePort = ntohs(connectionVector[index]->RemotePort);
- index++;
- break;
- }
- }
-
- SnmpUtilMemFreePtr(bind_list_ptr);
- SnmpUtilMemFreePtr(bind_ptr);
- SnmpUtilMemFreePtr(mib_ii_name_ptr);
-
- DEBUG_LOG(("Got %d connections in list, parsing...\n", connectionVector.size()));
-
- /*
- ** Right, we got the lot. Lets see if any of them have the same address as the chat
- ** server we think we are talking to.
- */
- found = false;
- for (Int i=0; igetPingValue(pingStr);
-}
-
-// GameSpyStagingRoom ----------------------------------------
-
-GameSpyStagingRoom::GameSpyStagingRoom()
-{
- cleanUpSlotPointers();
-
- setLocalIP(0);
- m_transport = NULL;
-
- m_localName = "localhost";
-
- m_ladderIP.clear();
- m_ladderPort = 0;
-}
-
-void GameSpyStagingRoom::cleanUpSlotPointers( void )
-{
- for (Int i = 0; i< MAX_SLOTS; ++i)
- setSlotPointer(i, &m_GameSpySlot[i]);
-}
-
-GameSpyGameSlot * GameSpyStagingRoom::getGameSpySlot( Int index )
-{
- GameSlot *slot = getSlot(index);
- DEBUG_ASSERTCRASH(slot && (slot == &(m_GameSpySlot[index])), ("Bad game slot pointer\n"));
- return (GameSpyGameSlot *)slot;
-}
-
-void GameSpyStagingRoom::init( void )
-{
- GameInfo::init();
-}
-
-void GameSpyStagingRoom::setPingString( AsciiString pingStr )
-{
- m_pingStr = pingStr;
- m_pingInt = TheGameSpyInfo->getPingValue(pingStr);
-}
-
-Bool GameSpyStagingRoom::amIHost( void ) const
-{
- DEBUG_ASSERTCRASH(m_inGame, ("Looking for game slot while not in game"));
- if (!m_inGame)
- return false;
-
- return getConstSlot(0)->isPlayer(m_localName);
-}
-
-void GameSpyStagingRoom::resetAccepted( void )
-{
- GameInfo::resetAccepted();
-
- if (amIHost())
- {
- /*
- peerStateChanged(TheGameSpyChat->getPeer());
- m_hasBeenQueried = false;
- DEBUG_LOG(("resetAccepted() called peerStateChange()\n"));
- */
- }
-}
-
-Int GameSpyStagingRoom::getLocalSlotNum( void ) const
-{
- DEBUG_ASSERTCRASH(m_inGame, ("Looking for local game slot while not in game"));
- if (!m_inGame)
- return -1;
-
- AsciiString localName = TheGameSpyInfo->getLocalName();
-
- for (Int i=0; iisPlayer(localName))
- return i;
- }
- return -1;
-}
-
-void GameSpyStagingRoom::startGame(Int gameID)
-{
- DEBUG_ASSERTCRASH(m_inGame, ("Starting a game while not in game"));
- DEBUG_LOG(("GameSpyStagingRoom::startGame - game id = %d\n", gameID));
- DEBUG_ASSERTCRASH(m_transport == NULL, ("m_transport is not NULL when it should be"));
- DEBUG_ASSERTCRASH(TheNAT == NULL, ("TheNAT is not NULL when it should be"));
-
- UnsignedInt localIP = TheGameSpyInfo->getInternalIP();
- setLocalIP(localIP);
-
- if (TheNAT != NULL) {
- delete TheNAT;
- TheNAT = NULL;
- }
-
- // fill in GS-specific info
- Int numHumans = 0;
- for (Int i=0; igetLocalProfileID()); // hehe - we know our own. the rest, they'll tell us.
- }
- else
- {
- PlayerInfoMap *pInfoMap = TheGameSpyInfo->getPlayerInfoMap();
- PlayerInfoMap::iterator it = pInfoMap->find(gsName);
- if (it != pInfoMap->end())
- {
- m_GameSpySlot[i].setProfileID(it->second.m_profileID);
- m_GameSpySlot[i].setLocale(it->second.m_locale);
- m_GameSpySlot[i].setSlotRankPoints(it->second.m_rankPoints);
- m_GameSpySlot[i].setFavoriteSide(it->second.m_side);
- }
- else
- {
- DEBUG_CRASH(("No player info for %s", gsName.str()));
- }
- }
- }
- }
-
-//#if defined(_DEBUG) || defined(_INTERNAL)
- if (numHumans < 2)
- {
- launchGame();
- if (TheGameSpyInfo)
- TheGameSpyInfo->leaveStagingRoom();
- }
- else
-//#endif defined(_DEBUG) || defined(_INTERNAL)
- {
- TheNAT = NEW NAT();
- TheNAT->attachSlotList(m_slot, getLocalSlotNum(), m_localIP);
- TheNAT->establishConnectionPaths();
- }
-}
-
-AsciiString GameSpyStagingRoom::generateGameSpyGameResultsPacket( void )
-{
- Int i;
- Int endFrame = TheVictoryConditions->getEndFrame();
- Int localSlotNum = getLocalSlotNum();
- Int winningTeam = -1;
- Int numHumans = 0;
- Int numPlayers = 0;
- Int numAIs = 0;
- Int numTeamsAtGameEnd = 0;
- Int lastTeamAtGameEnd = -1;
- for (i=0; ifindPlayerWithNameKey(NAMEKEY(playerName));
- if (p)
- {
- ++numHumans;
- if (TheVictoryConditions->hasAchievedVictory(p))
- {
- winningTeam = getSlot(i)->getTeamNumber();
- }
-
- // check if he lasted
- GameSlot *slot = getSlot(i);
- if (!slot->disconnected())
- {
- if (slot->getTeamNumber() != lastTeamAtGameEnd || numTeamsAtGameEnd == 0)
- {
- lastTeamAtGameEnd = slot->getTeamNumber();
- ++numTeamsAtGameEnd;
- }
- }
- }
- else
- {
- if (m_GameSpySlot[i].isAI())
- ++numAIs;
- }
- }
- numPlayers = numHumans + numAIs;
-
- AsciiString mapName;
- for (i=0; ifindPlayerWithNameKey(NAMEKEY(playerName));
- if (p)
- {
- GameSpyGameSlot *slot = &(m_GameSpySlot[i]);
- AsciiString playerName = (slot->isHuman())?slot->getLoginName():"AIPlayer";
- Int gsPlayerID = slot->getProfileID();
- Bool disconnected = slot->disconnected();
-
- AsciiString result = "loss", side = "USA";
- if (disconnected)
- result = "discon";
- else if (TheNetwork->sawCRCMismatch())
- result = "desync";
- else if (TheVictoryConditions->hasAchievedVictory(p))
- result = "win";
-
- side = p->getPlayerTemplate()->getSide();
- if (side == "America")
- side = "USA";
-
- AsciiString playerStr;
- playerStr.format("\\player_%d\\%s\\pid_%d\\%d\\team_%d\\%d\\result_%d\\%s\\side_%d\\%s",
- playerID, playerName.str(), playerID, gsPlayerID, playerID, slot->getTeamNumber(),
- playerID, result.str(), playerID, side.str());
- results.concat(playerStr);
-
- ++playerID;
- }
- }
-
- return results;
-}
-
-AsciiString GameSpyStagingRoom::generateLadderGameResultsPacket( void )
-{
- Int i;
- Int endFrame = TheVictoryConditions->getEndFrame();
- Int localSlotNum = getLocalSlotNum();
- Bool sawGameEnd = (endFrame > 0);
- Int winningTeam = -1;
- Int numPlayers = 0;
- Int numTeamsAtGameEnd = 0;
- Int lastTeamAtGameEnd = -1;
- Player* p[MAX_SLOTS];
- for (i=0; ifindPlayerWithNameKey(NAMEKEY(playerName));
- if (p[i])
- {
- ++numPlayers;
- if (TheVictoryConditions->hasAchievedVictory(p[i]))
- {
- winningTeam = getSlot(i)->getTeamNumber();
- }
-
- // check if he lasted
- GameSlot *slot = getSlot(i);
- if (!slot->disconnected())
- {
- if (slot->getTeamNumber() != lastTeamAtGameEnd || numTeamsAtGameEnd == 0)
- {
- lastTeamAtGameEnd = slot->getTeamNumber();
- ++numTeamsAtGameEnd;
- }
- }
- }
- }
-
- AsciiString results;
- results.format("seed=%d,slotNum=%d,sawDesync=%d,sawGameEnd=%d,winningTeam=%d,disconEnd=%d,duration=%d,numPlayers=%d,isQM=%d,map=%s",
- getSeed(), localSlotNum, TheNetwork->sawCRCMismatch(), sawGameEnd, winningTeam, (numTeamsAtGameEnd < 2),
- endFrame, numPlayers, m_isQM, TheGameState->realMapPathToPortableMapPath(getMap()).str());
-
- AsciiString tempStr;
- tempStr.format(",ladderIP=%s,ladderPort=%d", getLadderIP().str(), getLadderPort());
- results.concat(tempStr);
-
- Int playerID = 0;
- for (i=0; igetScoreKeeper();
- AsciiString playerName = slot->getLoginName();
- Int gsPlayerID = slot->getProfileID();
- PSPlayerStats stats = TheGameSpyPSMessageQueue->findPlayerStatsByID(gsPlayerID);
- Int fps = TheNetwork->getAverageFPS();
- Int unitsKilled = keeper->getTotalUnitsDestroyed();
- Int unitsLost = keeper->getTotalUnitsLost();
- Int unitsBuilt = keeper->getTotalUnitsBuilt();
- Int buildingsKilled = keeper->getTotalBuildingsDestroyed();
- Int buildingsLost = keeper->getTotalBuildingsLost();
- Int buildingsBuilt = keeper->getTotalBuildingsBuilt();
- Int earnings = keeper->getTotalMoneyEarned();
- Int techCaptured = keeper->getTotalTechBuildingsCaptured();
- Bool disconnected = slot->disconnected();
-
- AsciiString playerStr;
- playerStr.format(",player%d=%s,playerID%d=%d,locale%d=%d",
- playerID, playerName.str(), playerID, gsPlayerID, playerID, stats.locale);
- results.concat(playerStr);
- playerStr.format(",unitsKilled%d=%d,unitsLost%d=%d,unitsBuilt%d=%d",
- playerID, unitsKilled, playerID, unitsLost, playerID, unitsBuilt);
- results.concat(playerStr);
- playerStr.format(",buildingsKilled%d=%d,buildingsLost%d=%d,buildingsBuilt%d=%d",
- playerID, buildingsKilled, playerID, buildingsLost, playerID, buildingsBuilt);
- results.concat(playerStr);
- playerStr.format(",fps%d=%d,cash%d=%d,capturedTech%d=%d,discon%d=%d,side%d=%s,team%d=%d",
- playerID, fps, playerID, earnings, playerID, techCaptured, playerID, disconnected, playerID, p[i]->getPlayerTemplate()->getSide().str(), playerID, slot->getTeamNumber());
- results.concat(playerStr);
-
- ++playerID;
- }
- }
-
- // Add a trailing size value (so the server can ensure it got the entire packet)
- results.concat(",size=");
- int resultsLen = results.getLength()+10;
- AsciiString tail;
- tail.format("%10.10d", resultsLen);
- results.concat(tail);
-
- return results;
-}
-
-void GameSpyStagingRoom::launchGame( void )
-{
- setGameInProgress(TRUE);
-
- for (Int i=0; iisHuman())
- {
- if (TheGameSpyInfo->didPlayerPreorder(slot->getProfileID()))
- markPlayerAsPreorder(i);
- }
- }
-
- // Set up the game network
- AsciiString user;
- AsciiString userList;
- DEBUG_ASSERTCRASH(TheNetwork == NULL, ("For some reason TheNetwork isn't NULL at the start of this game. Better look into that."));
-
- if (TheNetwork != NULL) {
- delete TheNetwork;
- TheNetwork = NULL;
- }
-
- // Time to initialize TheNetwork for this game.
- TheNetwork = NetworkInterface::createNetwork();
- TheNetwork->init();
-
- TheNetwork->setLocalAddress(getLocalIP(), (TheNAT)?TheNAT->getSlotPort(getLocalSlotNum()):8888);
- if (TheNAT)
- TheNetwork->attachTransport(TheNAT->getTransport());
- else
- TheNetwork->initTransport();
-
- TheNetwork->parseUserList(this);
-
-
- if (TheGameLogic->isInGame()) {
- TheGameLogic->clearGameData();
- }
-
- Bool filesOk = DoAnyMapTransfers(this);
-
- // see if we really have the map. if not, back out.
- TheMapCache->updateCache();
- if (!filesOk || TheMapCache->findMap(getMap()) == NULL)
- {
- DEBUG_LOG(("After transfer, we didn't really have the map. Bailing...\n"));
- if (TheNetwork != NULL) {
- delete TheNetwork;
- TheNetwork = NULL;
- }
- GSMessageBoxOk(TheGameText->fetch("GUI:Error"), TheGameText->fetch("GUI:CouldNotTransferMap"));
-
- void PopBackToLobby( void );
- PopBackToLobby();
- return;
- }
-
-
- // shutdown the top, but do not pop it off the stack
-// TheShell->hideShell();
- // setup the Global Data with the Map and Seed
- TheWritableGlobalData->m_pendingFile = TheGameSpyGame->getMap();
-
- // send a message to the logic for a new game
- GameMessage *msg = TheMessageStream->appendMessage( GameMessage::MSG_NEW_GAME );
- msg->appendIntegerArgument(GAME_INTERNET);
-
- TheWritableGlobalData->m_useFpsLimit = false;
-
- // Set the random seed
- InitGameLogicRandom( getSeed() );
- DEBUG_LOG(("InitGameLogicRandom( %d )\n", getSeed()));
-
- // mark us as "Loading" in the buddy list
- BuddyRequest req;
- req.buddyRequestType = BuddyRequest::BUDDYREQUEST_SETSTATUS;
- req.arg.status.status = GP_PLAYING;
- strcpy(req.arg.status.statusString, "Loading");
- sprintf(req.arg.status.locationString, "%s", WideCharStringToMultiByte(TheGameSpyGame->getGameName().str()).c_str());
- TheGameSpyBuddyMessageQueue->addRequest(req);
-
- if (TheNAT != NULL) {
- delete TheNAT;
- TheNAT = NULL;
- }
-}
-
-void GameSpyStagingRoom::reset(void)
-{
-#ifdef DEBUG_LOGGING
- if (this == TheGameSpyGame)
- {
- WindowLayout *theLayout = TheShell->findScreenByFilename("Menus/GameSpyGameOptionsMenu.wnd");
- if (theLayout)
- {
- DEBUG_LOG(("Resetting TheGameSpyGame on the game options menu!\n"));
- }
- }
-#endif
- GameInfo::reset();
-}
diff --git a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/BuddyThread.cpp b/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/BuddyThread.cpp
deleted file mode 100644
index 410dbeed1db..00000000000
--- a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/BuddyThread.cpp
+++ /dev/null
@@ -1,681 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: BuddyThread.cpp //////////////////////////////////////////////////////
-// GameSpy Presence & Messaging (Buddy) thread
-// This thread communicates with GameSpy's buddy server
-// and talks through a message queue with the rest of
-// the game.
-// Author: Matthew D. Campbell, June 2002
-
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "GameNetwork/GameSpy/BuddyThread.h"
-#include "GameNetwork/GameSpy/PeerThread.h"
-#include "GameNetwork/GameSpy/PersistentStorageThread.h"
-#include "GameNetwork/GameSpy/ThreadUtils.h"
-
-#include "Common/StackDump.h"
-
-#include "mutex.h"
-#include "thread.h"
-
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-
-//-------------------------------------------------------------------------
-
-typedef std::queue RequestQueue;
-typedef std::queue ResponseQueue;
-class BuddyThreadClass;
-
-class GameSpyBuddyMessageQueue : public GameSpyBuddyMessageQueueInterface
-{
-public:
- virtual ~GameSpyBuddyMessageQueue();
- GameSpyBuddyMessageQueue();
- virtual void startThread( void );
- virtual void endThread( void );
- virtual Bool isThreadRunning( void );
- virtual Bool isConnected( void );
- virtual Bool isConnecting( void );
-
- virtual void addRequest( const BuddyRequest& req );
- virtual Bool getRequest( BuddyRequest& req );
-
- virtual void addResponse( const BuddyResponse& resp );
- virtual Bool getResponse( BuddyResponse& resp );
-
- virtual GPProfile getLocalProfileID( void );
-
- BuddyThreadClass* getThread( void );
-
-private:
- MutexClass m_requestMutex;
- MutexClass m_responseMutex;
- RequestQueue m_requests;
- ResponseQueue m_responses;
- BuddyThreadClass *m_thread;
-};
-
-GameSpyBuddyMessageQueueInterface* GameSpyBuddyMessageQueueInterface::createNewMessageQueue( void )
-{
- return NEW GameSpyBuddyMessageQueue;
-}
-
-GameSpyBuddyMessageQueueInterface *TheGameSpyBuddyMessageQueue;
-#define MESSAGE_QUEUE ((GameSpyBuddyMessageQueue *)TheGameSpyBuddyMessageQueue)
-
-//-------------------------------------------------------------------------
-
-class BuddyThreadClass : public ThreadClass
-{
-
-public:
- BuddyThreadClass() : ThreadClass() { m_isNewAccount = m_isdeleting = m_isConnecting = m_isConnected = false; m_profileID = 0; m_lastErrorCode = 0; }
-
- void Thread_Function();
-
- void errorCallback( GPConnection *con, GPErrorArg *arg );
- void messageCallback( GPConnection *con, GPRecvBuddyMessageArg *arg );
- void connectCallback( GPConnection *con, GPConnectResponseArg *arg );
- void requestCallback( GPConnection *con, GPRecvBuddyRequestArg *arg );
- void statusCallback( GPConnection *con, GPRecvBuddyStatusArg *arg );
-
- Bool isConnecting( void ) { return m_isConnecting; }
- Bool isConnected( void ) { return m_isConnected; }
-
- GPProfile getLocalProfileID( void ) { return m_profileID; }
-
-private:
- Bool m_isNewAccount;
- Bool m_isConnecting;
- Bool m_isConnected;
- GPProfile m_profileID;
- Int m_lastErrorCode;
- Bool m_isdeleting;
- std::string m_nick, m_email, m_pass;
-};
-
-static enum CallbackType
-{
- CALLBACK_CONNECT,
- CALLBACK_ERROR,
- CALLBACK_RECVMESSAGE,
- CALLBACK_RECVREQUEST,
- CALLBACK_RECVSTATUS,
- CALLBACK_MAX
-};
-
-void callbackWrapper( GPConnection *con, void *arg, void *param )
-{
- CallbackType info = (CallbackType)(Int)param;
- BuddyThreadClass *thread = MESSAGE_QUEUE->getThread() ? MESSAGE_QUEUE->getThread() : NULL /*(TheGameSpyBuddyMessageQueue)?TheGameSpyBuddyMessageQueue->getThread():NULL*/;
- if (!thread)
- return;
-
- switch (info)
- {
- case CALLBACK_CONNECT:
- thread->connectCallback( con, (GPConnectResponseArg *)arg );
- break;
- case CALLBACK_ERROR:
- thread->errorCallback( con, (GPErrorArg *)arg );
- break;
- case CALLBACK_RECVMESSAGE:
- thread->messageCallback( con, (GPRecvBuddyMessageArg *)arg );
- break;
- case CALLBACK_RECVREQUEST:
- thread->requestCallback( con, (GPRecvBuddyRequestArg *)arg );
- break;
- case CALLBACK_RECVSTATUS:
- thread->statusCallback( con, (GPRecvBuddyStatusArg *)arg );
- break;
- }
-}
-
-//-------------------------------------------------------------------------
-
-GameSpyBuddyMessageQueue::GameSpyBuddyMessageQueue()
-{
- m_thread = NULL;
-}
-
-GameSpyBuddyMessageQueue::~GameSpyBuddyMessageQueue()
-{
- endThread();
-}
-
-void GameSpyBuddyMessageQueue::startThread( void )
-{
- if (!m_thread)
- {
- m_thread = NEW BuddyThreadClass;
- m_thread->Execute();
- }
- else
- {
- if (!m_thread->Is_Running())
- {
- m_thread->Execute();
- }
- }
-}
-
-void GameSpyBuddyMessageQueue::endThread( void )
-{
- if (m_thread)
- delete m_thread;
- m_thread = NULL;
-}
-
-Bool GameSpyBuddyMessageQueue::isThreadRunning( void )
-{
- return (m_thread) ? m_thread->Is_Running() : false;
-}
-
-Bool GameSpyBuddyMessageQueue::isConnected( void )
-{
- return (m_thread) ? m_thread->isConnected() : false;
-}
-
-Bool GameSpyBuddyMessageQueue::isConnecting( void )
-{
- return (m_thread) ? m_thread->isConnecting() : false;
-}
-
-void GameSpyBuddyMessageQueue::addRequest( const BuddyRequest& req )
-{
- MutexClass::LockClass m(m_requestMutex);
- if (m.Failed())
- return;
-
- m_requests.push(req);
-}
-
-Bool GameSpyBuddyMessageQueue::getRequest( BuddyRequest& req )
-{
- MutexClass::LockClass m(m_requestMutex, 0);
- if (m.Failed())
- return false;
-
- if (m_requests.empty())
- return false;
- req = m_requests.front();
- m_requests.pop();
- return true;
-}
-
-void GameSpyBuddyMessageQueue::addResponse( const BuddyResponse& resp )
-{
- MutexClass::LockClass m(m_responseMutex);
- if (m.Failed())
- return;
-
- m_responses.push(resp);
-}
-
-Bool GameSpyBuddyMessageQueue::getResponse( BuddyResponse& resp )
-{
- MutexClass::LockClass m(m_responseMutex, 0);
- if (m.Failed())
- return false;
-
- if (m_responses.empty())
- return false;
- resp = m_responses.front();
- m_responses.pop();
- return true;
-}
-
-BuddyThreadClass* GameSpyBuddyMessageQueue::getThread( void )
-{
- return m_thread;
-}
-
-GPProfile GameSpyBuddyMessageQueue::getLocalProfileID( void )
-{
- return (m_thread) ? m_thread->getLocalProfileID() : 0;
-}
-
-//-------------------------------------------------------------------------
-
-void BuddyThreadClass::Thread_Function()
-{
- try {
- _set_se_translator( DumpExceptionInfo ); // Hook that allows stack trace.
- GPConnection gpCon;
- GPConnection *con = &gpCon;
- gpInitialize( con, 675, 0, GP_PARTNERID_GAMESPY );
- m_isConnected = m_isConnecting = false;
-
- gpSetCallback( con, GP_ERROR, callbackWrapper, (void *)CALLBACK_ERROR );
- gpSetCallback( con, GP_RECV_BUDDY_MESSAGE, callbackWrapper, (void *)CALLBACK_RECVMESSAGE );
- gpSetCallback( con, GP_RECV_BUDDY_REQUEST, callbackWrapper, (void *)CALLBACK_RECVREQUEST );
- gpSetCallback( con, GP_RECV_BUDDY_STATUS, callbackWrapper, (void *)CALLBACK_RECVSTATUS );
-
- GPEnum lastStatus = GP_OFFLINE;
- std::string lastStatusString;
-
- BuddyRequest incomingRequest;
- while ( running )
- {
- // deal with requests
- if (TheGameSpyBuddyMessageQueue->getRequest(incomingRequest))
- {
- switch (incomingRequest.buddyRequestType)
- {
- case BuddyRequest::BUDDYREQUEST_LOGIN:
- m_isConnecting = true;
- m_nick = incomingRequest.arg.login.nick;
- m_email = incomingRequest.arg.login.email;
- m_pass = incomingRequest.arg.login.password;
- m_isConnected = (gpConnect( con, incomingRequest.arg.login.nick, incomingRequest.arg.login.email,
- incomingRequest.arg.login.password, (incomingRequest.arg.login.hasFirewall)?GP_FIREWALL:GP_NO_FIREWALL,
- GP_BLOCKING, callbackWrapper, (void *)CALLBACK_CONNECT ) == GP_NO_ERROR);
- m_isConnecting = false;
- break;
-
- case BuddyRequest::BUDDYREQUEST_RELOGIN:
- m_isConnecting = true;
- m_isConnected = (gpConnect( con, m_nick.c_str(), m_email.c_str(), m_pass.c_str(), GP_FIREWALL,
- GP_BLOCKING, callbackWrapper, (void *)CALLBACK_CONNECT ) == GP_NO_ERROR);
- m_isConnecting = false;
- break;
- case BuddyRequest::BUDDYREQUEST_DELETEACCT:
- m_isdeleting = true;
- // TheSuperHackers @tweak OmniBlade API was updated since Generals released to require a callback. Passing -1 will make our wrapper ignore this.
- gpDeleteProfile( con, callbackWrapper, (void *)(-1) );
- break;
- case BuddyRequest::BUDDYREQUEST_LOGOUT:
- m_isConnecting = m_isConnected = false;
- gpDisconnect( con );
- break;
- case BuddyRequest::BUDDYREQUEST_MESSAGE:
- {
- std::string s = WideCharStringToMultiByte( incomingRequest.arg.message.text );
- DEBUG_LOG(("Sending a buddy message to %d [%s]\n", incomingRequest.arg.message.recipient, s.c_str()));
- gpSendBuddyMessage( con, incomingRequest.arg.message.recipient, s.c_str() );
- }
- break;
- case BuddyRequest::BUDDYREQUEST_LOGINNEW:
- {
- m_isConnecting = true;
- m_nick = incomingRequest.arg.login.nick;
- m_email = incomingRequest.arg.login.email;
- m_pass = incomingRequest.arg.login.password;
- m_isNewAccount = TRUE;
- // TheSuperHackers @tweak OmniBlade API was updated since Generals release to require uniquenick which is the same as nick and cdkey is an empty string here.
- m_isConnected = (gpConnectNewUser( con, incomingRequest.arg.login.nick, incomingRequest.arg.login.nick, incomingRequest.arg.login.email,
- incomingRequest.arg.login.password, "", (incomingRequest.arg.login.hasFirewall)?GP_FIREWALL:GP_NO_FIREWALL,
- GP_BLOCKING, callbackWrapper, (void *)CALLBACK_CONNECT ) == GP_NO_ERROR);
- if (m_isNewAccount) // if we didn't re-login
- {
- gpSetInfoMask( con, GP_MASK_NONE ); // don't share info
- }
- m_isConnecting = false;
- }
- break;
- case BuddyRequest::BUDDYREQUEST_ADDBUDDY:
- {
- std::string s = WideCharStringToMultiByte( incomingRequest.arg.addbuddy.text );
- gpSendBuddyRequest( con, incomingRequest.arg.addbuddy.id, s.c_str() );
- }
- break;
- case BuddyRequest::BUDDYREQUEST_DELBUDDY:
- {
- gpDeleteBuddy( con, incomingRequest.arg.profile.id );
- }
- break;
- case BuddyRequest::BUDDYREQUEST_OKADD:
- {
- gpAuthBuddyRequest( con, incomingRequest.arg.profile.id );
- }
- break;
- case BuddyRequest::BUDDYREQUEST_DENYADD:
- {
- gpDenyBuddyRequest( con, incomingRequest.arg.profile.id );
- }
- case BuddyRequest::BUDDYREQUEST_SETSTATUS:
- {
- //don't blast our 'Loading' status with 'Online'.
- if (lastStatus == GP_PLAYING && lastStatusString == "Loading" && incomingRequest.arg.status.status == GP_ONLINE)
- break;
-
- DEBUG_LOG(("BUDDYREQUEST_SETSTATUS: status is now %d:%s/%s\n",
- incomingRequest.arg.status.status, incomingRequest.arg.status.statusString, incomingRequest.arg.status.locationString));
- gpSetStatus( con, incomingRequest.arg.status.status, incomingRequest.arg.status.statusString,
- incomingRequest.arg.status.locationString );
- lastStatus = incomingRequest.arg.status.status;
- lastStatusString = incomingRequest.arg.status.statusString;
- }
- break;
- }
- }
-
- // update the network
- GPEnum isConnected = GP_CONNECTED;
- GPResult res = GP_NO_ERROR;
- res = gpIsConnected( con, &isConnected );
- if ( isConnected == GP_CONNECTED && res == GP_NO_ERROR )
- gpProcess( con );
-
- // end our timeslice
- Switch_Thread();
- }
-
- gpDestroy( con );
- } catch ( ... ) {
- DEBUG_CRASH(("Exception in buddy thread!"));
- }
-}
-
-void BuddyThreadClass::errorCallback( GPConnection *con, GPErrorArg *arg )
-{
- // log the error
- DEBUG_LOG(("GPErrorCallback\n"));
- m_lastErrorCode = arg->errorCode;
-
- char errorCodeString[256];
- char resultString[256];
-
- #define RESULT(x) case x: strcpy(resultString, #x); break;
- switch(arg->result)
- {
- RESULT(GP_NO_ERROR)
- RESULT(GP_MEMORY_ERROR)
- RESULT(GP_PARAMETER_ERROR)
- RESULT(GP_NETWORK_ERROR)
- RESULT(GP_SERVER_ERROR)
- default:
- strcpy(resultString, "Unknown result!");
- }
- #undef RESULT
-
- #define ERRORCODE(x) case x: strcpy(errorCodeString, #x); break;
- switch(arg->errorCode)
- {
- ERRORCODE(GP_GENERAL)
- ERRORCODE(GP_PARSE)
- ERRORCODE(GP_NOT_LOGGED_IN)
- ERRORCODE(GP_BAD_SESSKEY)
- ERRORCODE(GP_DATABASE)
- ERRORCODE(GP_NETWORK)
- ERRORCODE(GP_FORCED_DISCONNECT)
- ERRORCODE(GP_CONNECTION_CLOSED)
- ERRORCODE(GP_LOGIN)
- ERRORCODE(GP_LOGIN_TIMEOUT)
- ERRORCODE(GP_LOGIN_BAD_NICK)
- ERRORCODE(GP_LOGIN_BAD_EMAIL)
- ERRORCODE(GP_LOGIN_BAD_PASSWORD)
- ERRORCODE(GP_LOGIN_BAD_PROFILE)
- ERRORCODE(GP_LOGIN_PROFILE_DELETED)
- ERRORCODE(GP_LOGIN_CONNECTION_FAILED)
- ERRORCODE(GP_LOGIN_SERVER_AUTH_FAILED)
- ERRORCODE(GP_NEWUSER)
- ERRORCODE(GP_NEWUSER_BAD_NICK)
- ERRORCODE(GP_NEWUSER_BAD_PASSWORD)
- ERRORCODE(GP_UPDATEUI)
- ERRORCODE(GP_UPDATEUI_BAD_EMAIL)
- ERRORCODE(GP_NEWPROFILE)
- ERRORCODE(GP_NEWPROFILE_BAD_NICK)
- ERRORCODE(GP_NEWPROFILE_BAD_OLD_NICK)
- ERRORCODE(GP_UPDATEPRO)
- ERRORCODE(GP_UPDATEPRO_BAD_NICK)
- ERRORCODE(GP_ADDBUDDY)
- ERRORCODE(GP_ADDBUDDY_BAD_FROM)
- ERRORCODE(GP_ADDBUDDY_BAD_NEW)
- ERRORCODE(GP_ADDBUDDY_ALREADY_BUDDY)
- ERRORCODE(GP_AUTHADD)
- ERRORCODE(GP_AUTHADD_BAD_FROM)
- ERRORCODE(GP_AUTHADD_BAD_SIG)
- ERRORCODE(GP_STATUS)
- ERRORCODE(GP_BM)
- ERRORCODE(GP_BM_NOT_BUDDY)
- ERRORCODE(GP_GETPROFILE)
- ERRORCODE(GP_GETPROFILE_BAD_PROFILE)
- ERRORCODE(GP_DELBUDDY)
- ERRORCODE(GP_DELBUDDY_NOT_BUDDY)
- ERRORCODE(GP_DELPROFILE)
- ERRORCODE(GP_DELPROFILE_LAST_PROFILE)
- ERRORCODE(GP_SEARCH)
- ERRORCODE(GP_SEARCH_CONNECTION_FAILED)
- default:
- strcpy(errorCodeString, "Unknown error code!");
- }
- #undef ERRORCODE
-
- if(arg->fatal)
- {
- DEBUG_LOG(( "-----------\n"));
- DEBUG_LOG(( "GP FATAL ERROR\n"));
- DEBUG_LOG(( "-----------\n"));
- }
- else
- {
- DEBUG_LOG(( "-----\n"));
- DEBUG_LOG(( "GP ERROR\n"));
- DEBUG_LOG(( "-----\n"));
- }
- DEBUG_LOG(( "RESULT: %s (%d)\n", resultString, arg->result));
- DEBUG_LOG(( "ERROR CODE: %s (0x%X)\n", errorCodeString, arg->errorCode));
- DEBUG_LOG(( "ERROR STRING: %s\n", arg->errorString));
-
- if (arg->fatal == GP_FATAL)
- {
- BuddyResponse errorResponse;
- errorResponse.buddyResponseType = BuddyResponse::BUDDYRESPONSE_DISCONNECT;
- errorResponse.result = arg->result;
- errorResponse.arg.error.errorCode = arg->errorCode;
- errorResponse.arg.error.fatal = arg->fatal;
- strncpy(errorResponse.arg.error.errorString, arg->errorString, MAX_BUDDY_CHAT_LEN);
- errorResponse.arg.error.errorString[MAX_BUDDY_CHAT_LEN-1] = 0;
- m_isConnecting = m_isConnected = false;
- TheGameSpyBuddyMessageQueue->addResponse( errorResponse );
- if (m_isdeleting)
- {
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_LOGOUT;
- TheGameSpyPeerMessageQueue->addRequest( req );
- m_isdeleting = false;
- }
- }
-}
-
-static void getNickForMessage( GPConnection *con, GPGetInfoResponseArg *arg, void *param )
-{
- BuddyResponse *resp = (BuddyResponse *)param;
- strcpy(resp->arg.message.nick, arg->nick);
-}
-
-void BuddyThreadClass::messageCallback( GPConnection *con, GPRecvBuddyMessageArg *arg )
-{
- BuddyResponse messageResponse;
- messageResponse.buddyResponseType = BuddyResponse::BUDDYRESPONSE_MESSAGE;
- messageResponse.profile = arg->profile;
-
- // get info about the person asking to be our buddy
- gpGetInfo( con, arg->profile, GP_CHECK_CACHE, GP_BLOCKING, (GPCallback)getNickForMessage, &messageResponse);
-
- std::wstring s = MultiByteToWideCharSingleLine( arg->message );
- wcsncpy(messageResponse.arg.message.text, s.c_str(), MAX_BUDDY_CHAT_LEN);
- messageResponse.arg.message.text[MAX_BUDDY_CHAT_LEN-1] = 0;
- messageResponse.arg.message.date = arg->date;
- DEBUG_LOG(("Got a buddy message from %d [%ls]\n", arg->profile, s.c_str()));
- TheGameSpyBuddyMessageQueue->addResponse( messageResponse );
-}
-
-void BuddyThreadClass::connectCallback( GPConnection *con, GPConnectResponseArg *arg )
-{
- BuddyResponse loginResponse;
- if (arg->result == GP_NO_ERROR)
- {
- loginResponse.buddyResponseType = BuddyResponse::BUDDYRESPONSE_LOGIN;
- loginResponse.result = arg->result;
- loginResponse.profile = arg->profile;
- TheGameSpyBuddyMessageQueue->addResponse( loginResponse );
- m_profileID = arg->profile;
-
- if (!TheGameSpyPeerMessageQueue->isConnected() && !TheGameSpyPeerMessageQueue->isConnecting())
- {
- DEBUG_LOG(("Buddy connect: trying chat connect\n"));
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_LOGIN;
- req.nick = m_nick;
- req.password = m_pass;
- req.email = m_email;
- req.login.profileID = arg->profile;
- TheGameSpyPeerMessageQueue->addRequest(req);
- }
- }
- else
- {
- if (!TheGameSpyPeerMessageQueue->isConnected() && !TheGameSpyPeerMessageQueue->isConnecting())
- {
- if (m_lastErrorCode == GP_NEWUSER_BAD_NICK)
- {
- m_isNewAccount = FALSE;
- // they just hit 'create account' instead of 'log in'. Fix them.
- DEBUG_LOG(("User Error: Create Account instead of Login. Fixing them...\n"));
- BuddyRequest req;
- req.buddyRequestType = BuddyRequest::BUDDYREQUEST_LOGIN;
- strcpy(req.arg.login.nick, m_nick.c_str());
- strcpy(req.arg.login.email, m_email.c_str());
- strcpy(req.arg.login.password, m_pass.c_str());
- req.arg.login.hasFirewall = true;
- TheGameSpyBuddyMessageQueue->addRequest( req );
- return;
- }
- DEBUG_LOG(("Buddy connect failed (%d/%d): posting a failed chat connect\n", arg->result, m_lastErrorCode));
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_DISCONNECT;
- resp.discon.reason = DISCONNECT_COULDNOTCONNECT;
- switch (m_lastErrorCode)
- {
- case GP_LOGIN_TIMEOUT:
- resp.discon.reason = DISCONNECT_GP_LOGIN_TIMEOUT;
- break;
- case GP_LOGIN_BAD_NICK:
- resp.discon.reason = DISCONNECT_GP_LOGIN_BAD_NICK;
- break;
- case GP_LOGIN_BAD_EMAIL:
- resp.discon.reason = DISCONNECT_GP_LOGIN_BAD_EMAIL;
- break;
- case GP_LOGIN_BAD_PASSWORD:
- resp.discon.reason = DISCONNECT_GP_LOGIN_BAD_PASSWORD;
- break;
- case GP_LOGIN_BAD_PROFILE:
- resp.discon.reason = DISCONNECT_GP_LOGIN_BAD_PROFILE;
- break;
- case GP_LOGIN_PROFILE_DELETED:
- resp.discon.reason = DISCONNECT_GP_LOGIN_PROFILE_DELETED;
- break;
- case GP_LOGIN_CONNECTION_FAILED:
- resp.discon.reason = DISCONNECT_GP_LOGIN_CONNECTION_FAILED;
- break;
- case GP_LOGIN_SERVER_AUTH_FAILED:
- resp.discon.reason = DISCONNECT_GP_LOGIN_SERVER_AUTH_FAILED;
- break;
- case GP_NEWUSER_BAD_NICK:
- resp.discon.reason = DISCONNECT_GP_NEWUSER_BAD_NICK;
- break;
- case GP_NEWUSER_BAD_PASSWORD:
- resp.discon.reason = DISCONNECT_GP_NEWUSER_BAD_PASSWORD;
- break;
- case GP_NEWPROFILE_BAD_NICK:
- resp.discon.reason = DISCONNECT_GP_NEWPROFILE_BAD_NICK;
- break;
- case GP_NEWPROFILE_BAD_OLD_NICK:
- resp.discon.reason = DISCONNECT_GP_NEWPROFILE_BAD_OLD_NICK;
- break;
- }
- TheGameSpyPeerMessageQueue->addResponse(resp);
- }
- }
-}
-
-// -----------------------
-
-static void getInfoResponseForRequest( GPConnection *con, GPGetInfoResponseArg *arg, void *param )
-{
- BuddyResponse *resp = (BuddyResponse *)param;
- resp->profile = arg->profile;
- strcpy(resp->arg.request.nick, arg->nick);
- strcpy(resp->arg.request.email, arg->email);
- strcpy(resp->arg.request.countrycode, arg->countrycode);
-}
-
-void BuddyThreadClass::requestCallback( GPConnection *con, GPRecvBuddyRequestArg *arg )
-{
- BuddyResponse response;
- response.buddyResponseType = BuddyResponse::BUDDYRESPONSE_REQUEST;
- response.profile = arg->profile;
-
- // get info about the person asking to be our buddy
- gpGetInfo( con, arg->profile, GP_CHECK_CACHE, GP_BLOCKING, (GPCallback)getInfoResponseForRequest, &response);
-
- std::wstring s = MultiByteToWideCharSingleLine( arg->reason );
- wcsncpy(response.arg.request.text, s.c_str(), GP_REASON_LEN);
- response.arg.request.text[GP_REASON_LEN-1] = 0;
-
- TheGameSpyBuddyMessageQueue->addResponse( response );
-}
-
-// -----------------------
-
-static void getInfoResponseForStatus(GPConnection * connection, GPGetInfoResponseArg * arg, void * param)
-{
- BuddyResponse *resp = (BuddyResponse *)param;
- resp->profile = arg->profile;
- strcpy(resp->arg.status.nick, arg->nick);
- strcpy(resp->arg.status.email, arg->email);
- strcpy(resp->arg.status.countrycode, arg->countrycode);
-}
-
-void BuddyThreadClass::statusCallback( GPConnection *con, GPRecvBuddyStatusArg *arg )
-{
- BuddyResponse response;
-
- // get user's name
- response.buddyResponseType = BuddyResponse::BUDDYRESPONSE_STATUS;
- gpGetInfo( con, arg->profile, GP_CHECK_CACHE, GP_BLOCKING, (GPCallback)getInfoResponseForStatus, &response);
-
- // get user's status
- GPBuddyStatus status;
- gpGetBuddyStatus( con, arg->index, &status );
- strcpy(response.arg.status.location, status.locationString);
- strcpy(response.arg.status.statusString, status.statusString);
- response.arg.status.status = status.status;
- DEBUG_LOG(("Got buddy status for %d(%s) - status %d\n", status.profile, response.arg.status.nick, status.status));
-
- // relay to UI
- TheGameSpyBuddyMessageQueue->addResponse( response );
-}
-
-
-//-------------------------------------------------------------------------
-
diff --git a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/GameResultsThread.cpp b/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/GameResultsThread.cpp
deleted file mode 100644
index 5b857727fe9..00000000000
--- a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/GameResultsThread.cpp
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: PingThread.cpp //////////////////////////////////////////////////////
-// Ping thread
-// Author: Matthew D. Campbell, August 2002
-
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include // This one has to be here. Prevents collisions with winsock2.h
-
-#include "GameNetwork/GameSpy/GameResultsThread.h"
-#include "mutex.h"
-#include "thread.h"
-
-#include "Common/StackDump.h"
-#include "Common/SubsystemInterface.h"
-
-//-------------------------------------------------------------------------
-
-static const Int NumWorkerThreads = 1;
-
-typedef std::queue RequestQueue;
-typedef std::queue ResponseQueue;
-class GameResultsThreadClass;
-
-class GameResultsQueue : public GameResultsInterface
-{
-public:
- virtual ~GameResultsQueue();
- GameResultsQueue();
-
- virtual void init() {}
- virtual void reset() {}
- virtual void update() {}
-
- virtual void startThreads( void );
- virtual void endThreads( void );
- virtual Bool areThreadsRunning( void );
-
- virtual void addRequest( const GameResultsRequest& req );
- virtual Bool getRequest( GameResultsRequest& resp );
-
- virtual void addResponse( const GameResultsResponse& resp );
- virtual Bool getResponse( GameResultsResponse& resp );
-
- virtual Bool areGameResultsBeingSent( void );
-
-private:
- MutexClass m_requestMutex;
- MutexClass m_responseMutex;
- RequestQueue m_requests;
- ResponseQueue m_responses;
- Int m_requestCount;
- Int m_responseCount;
-
- GameResultsThreadClass *m_workerThreads[NumWorkerThreads];
-};
-
-GameResultsInterface* GameResultsInterface::createNewGameResultsInterface( void )
-{
- return NEW GameResultsQueue;
-}
-
-GameResultsInterface *TheGameResultsQueue;
-
-//-------------------------------------------------------------------------
-
-class GameResultsThreadClass : public ThreadClass
-{
-
-public:
- GameResultsThreadClass() : ThreadClass() {}
-
- void Thread_Function();
-
-private:
- Int sendGameResults( UnsignedInt IP, UnsignedShort port, const std::string& results );
-};
-
-
-//-------------------------------------------------------------------------
-
-GameResultsQueue::GameResultsQueue() : m_requestCount(0), m_responseCount(0)
-{
- for (Int i=0; iExecute();
- }
-}
-
-void GameResultsQueue::endThreads( void )
-{
- for (Int i=0; iIs_Running())
- return true;
- }
- }
- return false;
-}
-
-void GameResultsQueue::addRequest( const GameResultsRequest& req )
-{
- MutexClass::LockClass m(m_requestMutex);
-
- ++m_requestCount;
- m_requests.push(req);
-}
-
-Bool GameResultsQueue::getRequest( GameResultsRequest& req )
-{
- MutexClass::LockClass m(m_requestMutex, 0);
- if (m.Failed())
- return false;
-
- if (m_requests.empty())
- return false;
- req = m_requests.front();
- m_requests.pop();
- return true;
-}
-
-void GameResultsQueue::addResponse( const GameResultsResponse& resp )
-{
- {
- MutexClass::LockClass m(m_responseMutex);
-
- ++m_responseCount;
- m_responses.push(resp);
- }
-}
-
-Bool GameResultsQueue::getResponse( GameResultsResponse& resp )
-{
- MutexClass::LockClass m(m_responseMutex, 0);
- if (m.Failed())
- return false;
-
- if (m_responses.empty())
- return false;
- resp = m_responses.front();
- m_responses.pop();
- return true;
-}
-
-Bool GameResultsQueue::areGameResultsBeingSent( void )
-{
- MutexClass::LockClass m(m_requestMutex, 0);
- if (m.Failed())
- return true;
-
- return m_requestCount > 0;
-}
-
-
-//-------------------------------------------------------------------------
-// Wrap ladder results in HTTP POST
-static WrapHTTP( const std::string& hostname, std::string& results )
-{
- const char HEADER[] =
- "PUT / HTTP/1.1\r\n"
- "Connection: Close\r\n"
- "Host: %s\r\n"
- "Content-Length: %d\r\n"
- "\r\n";
-
- char szHdr[256] = {0};
- _snprintf( szHdr, 255, HEADER, hostname.c_str(), results.length() );
- results = szHdr + results;
-} //WrapHTTP
-
-
-//-------------------------------------------------------------------------
-
-void GameResultsThreadClass::Thread_Function()
-{
- try {
- _set_se_translator( DumpExceptionInfo ); // Hook that allows stack trace.
- GameResultsRequest req;
-
- WSADATA wsaData;
-
- // Fire up winsock (prob already done, but doesn't matter)
- WORD wVersionRequested = MAKEWORD(1, 1);
- WSAStartup( wVersionRequested, &wsaData );
-
- while ( running )
- {
- // deal with requests
- if (TheGameResultsQueue && TheGameResultsQueue->getRequest(req))
- {
- // resolve the hostname
- const char *hostnameBuffer = req.hostname.c_str();
- UnsignedInt IP = 0xFFFFFFFF;
- if (isdigit(hostnameBuffer[0]))
- {
- IP = inet_addr(hostnameBuffer);
- in_addr hostNode;
- hostNode.s_addr = IP;
- DEBUG_LOG(("sending game results to %s - IP = %s\n", hostnameBuffer, inet_ntoa(hostNode) ));
- }
- else
- {
- HOSTENT *hostStruct;
- in_addr *hostNode;
- hostStruct = gethostbyname(hostnameBuffer);
- if (hostStruct == NULL)
- {
- DEBUG_LOG(("sending game results to %s - host lookup failed\n", hostnameBuffer));
-
- // Even though this failed to resolve IP, still need to send a
- // callback.
- IP = 0xFFFFFFFF; // flag for IP resolve failed
- }
- hostNode = (in_addr *) hostStruct->h_addr;
- IP = hostNode->s_addr;
- DEBUG_LOG(("sending game results to %s IP = %s\n", hostnameBuffer, inet_ntoa(*hostNode) ));
- }
-
- int result = sendGameResults( IP, req.port, req.results );
- GameResultsResponse resp;
- resp.hostname = req.hostname;
- resp.port = req.port;
- resp.sentOk = (result == req.results.length());
-
- }
-
- // end our timeslice
- Switch_Thread();
- }
-
- WSACleanup();
- } catch ( ... ) {
- DEBUG_CRASH(("Exception in results thread!"));
- }
-}
-
-//-------------------------------------------------------------------------
-
-#define CASE(x) case (x): return #x;
-
-static const char *getWSAErrorString( Int error )
-{
- switch (error)
- {
- CASE(WSABASEERR)
- CASE(WSAEINTR)
- CASE(WSAEBADF)
- CASE(WSAEACCES)
- CASE(WSAEFAULT)
- CASE(WSAEINVAL)
- CASE(WSAEMFILE)
- CASE(WSAEWOULDBLOCK)
- CASE(WSAEINPROGRESS)
- CASE(WSAEALREADY)
- CASE(WSAENOTSOCK)
- CASE(WSAEDESTADDRREQ)
- CASE(WSAEMSGSIZE)
- CASE(WSAEPROTOTYPE)
- CASE(WSAENOPROTOOPT)
- CASE(WSAEPROTONOSUPPORT)
- CASE(WSAESOCKTNOSUPPORT)
- CASE(WSAEOPNOTSUPP)
- CASE(WSAEPFNOSUPPORT)
- CASE(WSAEAFNOSUPPORT)
- CASE(WSAEADDRINUSE)
- CASE(WSAEADDRNOTAVAIL)
- CASE(WSAENETDOWN)
- CASE(WSAENETUNREACH)
- CASE(WSAENETRESET)
- CASE(WSAECONNABORTED)
- CASE(WSAECONNRESET)
- CASE(WSAENOBUFS)
- CASE(WSAEISCONN)
- CASE(WSAENOTCONN)
- CASE(WSAESHUTDOWN)
- CASE(WSAETOOMANYREFS)
- CASE(WSAETIMEDOUT)
- CASE(WSAECONNREFUSED)
- CASE(WSAELOOP)
- CASE(WSAENAMETOOLONG)
- CASE(WSAEHOSTDOWN)
- CASE(WSAEHOSTUNREACH)
- CASE(WSAENOTEMPTY)
- CASE(WSAEPROCLIM)
- CASE(WSAEUSERS)
- CASE(WSAEDQUOT)
- CASE(WSAESTALE)
- CASE(WSAEREMOTE)
- CASE(WSAEDISCON)
- CASE(WSASYSNOTREADY)
- CASE(WSAVERNOTSUPPORTED)
- CASE(WSANOTINITIALISED)
- CASE(WSAHOST_NOT_FOUND)
- CASE(WSATRY_AGAIN)
- CASE(WSANO_RECOVERY)
- CASE(WSANO_DATA)
- default:
- return "Not a Winsock error";
- }
-}
-
-#undef CASE
-
-//-------------------------------------------------------------------------
-
-Int GameResultsThreadClass::sendGameResults( UnsignedInt IP, UnsignedShort port, const std::string& results )
-{
- int error = 0;
-
- // create the socket
- Int sock = socket( AF_INET, SOCK_STREAM, 0 );
- if (sock < 0)
- {
- DEBUG_LOG(("GameResultsThreadClass::sendGameResults() - socket() returned %d(%s)\n", sock, getWSAErrorString(sock)));
- return sock;
- }
-
- // fill in address info
- struct sockaddr_in sockAddr;
- memset( &sockAddr, 0, sizeof( sockAddr ) );
- sockAddr.sin_family = AF_INET;
- sockAddr.sin_addr.s_addr = IP;
- sockAddr.sin_port = htons(port);
-
- // Start the connection process....
- if( connect( sock, (struct sockaddr *)&sockAddr, sizeof( sockAddr ) ) == -1 )
- {
- error = WSAGetLastError();
- DEBUG_LOG(("GameResultsThreadClass::sendGameResults() - connect() returned %d(%s)\n", error, getWSAErrorString(error)));
- if( ( error == WSAEWOULDBLOCK ) || ( error == WSAEINVAL ) || ( error == WSAEALREADY ) )
- {
- return( -1 );
- }
-
- if( error != WSAEISCONN )
- {
- closesocket( sock );
- return( -1 );
- }
- }
-
- if (send( sock, results.c_str(), results.length(), 0 ) == SOCKET_ERROR)
- {
- error = WSAGetLastError();
- DEBUG_LOG(("GameResultsThreadClass::sendGameResults() - send() returned %d(%s)\n", error, getWSAErrorString(error)));
- closesocket(sock);
- return WSAGetLastError();
- }
-
- closesocket(sock);
-
- return results.length();
-}
-
-
-//-------------------------------------------------------------------------
diff --git a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/PeerThread.cpp b/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/PeerThread.cpp
deleted file mode 100644
index 28e6785d6a8..00000000000
--- a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/PeerThread.cpp
+++ /dev/null
@@ -1,2966 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: PeerThread.cpp //////////////////////////////////////////////////////
-// GameSpy Peer (chat) thread
-// This thread communicates with GameSpy's chat server
-// and talks through a message queue with the rest of
-// the game.
-// Author: Matthew D. Campbell, June 2002
-
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/Registry.h"
-#include "Common/StackDump.h"
-#include "Common/UserPreferences.h"
-#include "Common/Version.h"
-#include "GameNetwork/IPEnumeration.h"
-#include "GameNetwork/GameSpy/BuddyThread.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpy/PeerThread.h"
-#include "GameNetwork/GameSpy/PersistentStorageThread.h"
-#include "GameNetwork/GameSpy/ThreadUtils.h"
-
-#include "strtok_r.h"
-#include "mutex.h"
-#include "thread.h"
-
-#include "Common/MiniLog.h"
-
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-
-// enable this for trying to track down why SBServers are losing their keyvals -MDC 2/20/2003
-#undef SERVER_DEBUGGING
-#ifdef SERVER_DEBUGGING
-void CheckServers(PEER peer);
-#endif // SERVER_DEBUGGING
-
-#ifdef DEBUG_LOGGING
-//#define PING_TEST
-static LogClass s_pingLog("Ping.txt");
-#define PING_LOG(x) s_pingLog.log x
-#else // DEBUG_LOGGING
-#define PING_LOG(x) {}
-#endif // DEBUG_LOGGING
-
-#ifdef DEBUG_LOGGING
-static LogClass s_stateChangedLog("StateChanged.txt");
-
-#define STATECHANGED_LOG(x) s_stateChangedLog.log x
-
-#else // DEBUG_LOGGING
-
-#define STATECHANGED_LOG(x) {}
-
-#endif // DEBUG_LOGGING
-
-// we should always be using broadcast keys from now on. Remove the old code sometime when
-// we're not in a rush, ok?
-// -MDC 2/14/2003
-#define USE_BROADCAST_KEYS
-
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-
-int isThreadHosting = 0;
-static UnsignedInt s_lastStateChangedHeartbeat = 0;
-static Bool s_wantStateChangedHeartbeat = FALSE;
-static UnsignedInt s_heartbeatInterval = 10000;
-
-static SOCKET qr2Sock = INVALID_SOCKET;
-
-enum
-{
- EXECRC_KEY = NUM_RESERVED_KEYS + 1,
- INICRC_KEY,
- PW_KEY,
- OBS_KEY,
- LADIP_KEY,
- LADPORT_KEY,
- PINGSTR_KEY,
- NUMPLAYER_KEY,
- MAXPLAYER_KEY,
- NUMOBS_KEY,
- NAME__KEY,
- FACTION__KEY,
- COLOR__KEY,
- WINS__KEY,
- LOSSES__KEY
-};
-
-#define EXECRC_STR "exeCRC"
-#define INICRC_STR "iniCRC"
-#define PW_STR "pw"
-#define OBS_STR "obs"
-#define LADIP_STR "ladIP"
-#define LADPORT_STR "ladPort"
-#define PINGSTR_STR "pings"
-#define NUMPLAYER_STR "numRealPlayers"
-#define MAXPLAYER_STR "maxRealPlayers"
-#define NUMOBS_STR "numObservers"
-#define NAME__STR "name"
-#define FACTION__STR "faction"
-#define COLOR__STR "color"
-#define WINS__STR "wins"
-#define LOSSES__STR "losses"
-
-//-------------------------------------------------------------------------
-
-typedef std::queue RequestQueue;
-typedef std::queue ResponseQueue;
-class PeerThreadClass;
-
-class GameSpyPeerMessageQueue : public GameSpyPeerMessageQueueInterface
-{
-public:
- virtual ~GameSpyPeerMessageQueue();
- GameSpyPeerMessageQueue();
- virtual void startThread( void );
- virtual void endThread( void );
- virtual Bool isThreadRunning( void );
- virtual Bool isConnected( void );
- virtual Bool isConnecting( void );
-
- virtual void addRequest( const PeerRequest& req );
- virtual Bool getRequest( PeerRequest& req );
-
- virtual void addResponse( const PeerResponse& resp );
- virtual Bool getResponse( PeerResponse& resp );
-
- virtual SerialAuthResult getSerialAuthResult( void ) { return m_serialAuth; }
- void setSerialAuthResult( SerialAuthResult result ) { m_serialAuth = result; }
-
- PeerThreadClass* getThread( void );
-
-private:
- MutexClass m_requestMutex;
- MutexClass m_responseMutex;
- RequestQueue m_requests;
- ResponseQueue m_responses;
- PeerThreadClass *m_thread;
-
- SerialAuthResult m_serialAuth;
-};
-
-GameSpyPeerMessageQueueInterface* GameSpyPeerMessageQueueInterface::createNewMessageQueue( void )
-{
- return NEW GameSpyPeerMessageQueue;
-}
-
-GameSpyPeerMessageQueueInterface *TheGameSpyPeerMessageQueue;
-#define MESSAGE_QUEUE ((GameSpyPeerMessageQueue *)TheGameSpyPeerMessageQueue)
-
-//-------------------------------------------------------------------------
-
-class PeerThreadClass : public ThreadClass
-{
-
-public:
- PeerThreadClass() : ThreadClass()
- {
- //Added By Sadullah Nader
- //Initializations inserted
- m_roomJoined = m_allowObservers = m_hasPassword = FALSE;
- m_exeCRC = m_iniCRC = 0;
- m_gameVersion = 0;
- m_ladderPort = 0;
- m_localRoomID = 0;
- m_maxPlayers = 0;
- m_numObservers = 0;
- m_maxPlayers = 0;
- m_qmGroupRoom = 0;
- m_sawEndOfEnumPlayers = m_sawMatchbot = FALSE;
- m_sawCompleteGameList = FALSE;
- //
- m_isConnecting = m_isConnected = false;
- m_groupRoomID = m_profileID = 0;
- m_nextStagingServer = 1; m_stagingServers.clear();
- m_pingStr = ""; m_mapName = ""; m_ladderIP = ""; m_isHosting = false;
- for (Int i=0; i PlayerStatMap;
- PlayerStatMap m_groupRoomStats;
- PlayerStatMap m_stagingRoomStats;
- std::string packStatKey(const char *nick, const char *key);
-#endif // USE_BROADCAST_KEYS
-
- // game-hosting info for GOA callbacks
- Bool m_isHosting;
- Bool m_hasPassword;
- std::string m_mapName;
- std::string m_playerNames[MAX_SLOTS];
- UnsignedInt m_exeCRC;
- UnsignedInt m_iniCRC;
- UnsignedInt m_gameVersion;
- Bool m_allowObservers;
- std::string m_pingStr;
- std::string m_ladderIP;
- UnsignedShort m_ladderPort;
- Int m_playerWins[MAX_SLOTS];
- Int m_playerLosses[MAX_SLOTS];
- Int m_playerProfileID[MAX_SLOTS];
- Int m_playerColors[MAX_SLOTS];
- Int m_playerFactions[MAX_SLOTS];
- Int m_numPlayers;
- Int m_maxPlayers;
- Int m_numObservers;
-
- Int m_nextStagingServer;
- std::map m_stagingServers;
- std::wstring m_localStagingServerName;
- Int m_localRoomID;
-
- void doQuickMatch( PEER peer );
- QMStatus m_qmStatus;
- PeerRequest m_qmInfo;
- Bool m_roomJoined;
- Int m_qmGroupRoom;
- Bool m_sawEndOfEnumPlayers;
- Bool m_sawMatchbot;
- std::string m_matchbotName;
-};
-
-#ifdef USE_BROADCAST_KEYS
-const char* PeerThreadClass::s_keys[6] = { "b_locale", "b_wins", "b_losses", "b_points", "b_side", "b_pre" };
-char PeerThreadClass::s_valueBuffers[6][20] = { "", "", "", "", "", "" };
-const char* PeerThreadClass::s_values[6] = { s_valueBuffers[0], s_valueBuffers[1], s_valueBuffers[2],
- s_valueBuffers[3], s_valueBuffers[4], s_valueBuffers[5]};
-
-void PeerThreadClass::trackStatsForPlayer(RoomType roomType, const char *nick, const char *key, const char *val)
-{
- switch (roomType)
- {
- case GroupRoom:
- m_groupRoomStats[packStatKey(nick, key)] = atoi(val);
- break;
- case StagingRoom:
- m_stagingRoomStats[packStatKey(nick, key)] = atoi(val);
- break;
- }
-}
-
-std::string PeerThreadClass::packStatKey(const char *nick, const char *key)
-{
- std::string s = nick;
- s.append(key);
- return s;
-}
-
-int PeerThreadClass::lookupStatForPlayer(RoomType roomType, const char *nick, const char *key)
-{
- std::string fullKey = packStatKey(nick, key);
- PlayerStatMap::const_iterator it;
- switch (roomType)
- {
- case GroupRoom:
- it = m_groupRoomStats.find(fullKey);
- if (it != m_groupRoomStats.end())
- return it->second;
- break;
- case StagingRoom:
- it = m_stagingRoomStats.find(fullKey);
- if (it != m_stagingRoomStats.end())
- return it->second;
- break;
- }
- return 0;
-}
-
-void PeerThreadClass::clearPlayerStats(RoomType roomType)
-{
- switch (roomType)
- {
- case GroupRoom:
- m_groupRoomStats.clear();
- break;
- case StagingRoom:
- m_stagingRoomStats.clear();
- break;
- }
-}
-
-void PeerThreadClass::pushStatsToRoom(PEER peer)
-{
- DEBUG_LOG(("PeerThreadClass::pushStatsToRoom(): stats are %s=%s,%s=%s,%s=%s,%s=%s,%s=%s,%s=%s\n",
- s_keys[0], s_values[0],
- s_keys[1], s_values[1],
- s_keys[2], s_values[2],
- s_keys[3], s_values[3],
- s_keys[4], s_values[4],
- s_keys[5], s_values[5]));
- peerSetRoomKeys(peer, GroupRoom, m_loginName.c_str(), 6, s_keys, s_values);
- peerSetRoomKeys(peer, StagingRoom, m_loginName.c_str(), 6, s_keys, s_values);
-}
-
-void getRoomKeysCallback(PEER peer, PEERBool success, RoomType roomType, const char *nick, int num, char **keys, char **values, void *param);
-void PeerThreadClass::getStatsFromRoom(PEER peer, RoomType roomType)
-{
- peerGetRoomKeys(peer, GroupRoom, "*", NumKeys, s_keys, getRoomKeysCallback, this, PEERFalse);
-}
-#endif // USE_BROADCAST_KEYS
-
-Int PeerThreadClass::addServerToMap( SBServer server )
-{
- Int val = m_nextStagingServer++;
- m_stagingServers[val] = server;
- return val;
-}
-
-Int PeerThreadClass::removeServerFromMap( SBServer server )
-{
- for (std::map::iterator it = m_stagingServers.begin(); it != m_stagingServers.end(); ++it)
- {
- if (it->second == server)
- {
- Int val = it->first;
- m_stagingServers.erase(it);
- return val;
- }
- }
-
- return 0;
-}
-
-void PeerThreadClass::clearServers( void )
-{
- m_stagingServers.clear();
-}
-
-SBServer PeerThreadClass::findServerByID( Int id )
-{
- std::map::iterator it = m_stagingServers.find(id);
- if (it != m_stagingServers.end())
- {
- SBServer server = it->second;
- if (server && !server->keyvals)
- {
- DEBUG_CRASH(("Referencing a missing server!"));
- return 0;
- }
- return it->second;
- }
- return 0;
-}
-
-Int PeerThreadClass::findServer( SBServer server )
-{
- char tmp[10] = "";
- const char *newName = SBServerGetStringValue(server, "gamename", tmp);
- UnsignedInt newPrivateIP = SBServerGetPrivateInetAddress(server);
- UnsignedShort newPrivatePort = SBServerGetPrivateQueryPort(server);
- UnsignedInt newPublicIP = SBServerGetPublicInetAddress(server);
-
- SBServer serverToRemove = NULL;
-
- for (std::map::iterator it = m_stagingServers.begin(); it != m_stagingServers.end(); ++it)
- {
- if (it->second == server)
- {
- return it->first;
- }
- else
- {
- const char *oldName = SBServerGetStringValue(it->second, "gamename", tmp);
- UnsignedInt oldPrivateIP = SBServerGetPrivateInetAddress(it->second);
- UnsignedShort oldPrivatePort = SBServerGetPrivateQueryPort(it->second);
- UnsignedInt oldPublicIP = SBServerGetPublicInetAddress(it->second);
- if (!strcmp(oldName, newName) &&
- oldPrivateIP == newPrivateIP &&
- oldPublicIP == newPublicIP &&
- oldPrivatePort == newPrivatePort)
- {
- serverToRemove = it->second;
- }
- }
- }
-
- if (serverToRemove)
- {
- // this is the same as another game - it has just migrated to another port. Remove the old and replace it.
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_STAGINGROOM;
- resp.stagingRoom.id = removeServerFromMap( serverToRemove );
- resp.stagingRoom.action = PEER_REMOVE;
- resp.stagingRoom.isStaging = TRUE;
- resp.stagingRoom.percentComplete = -1;
- TheGameSpyPeerMessageQueue->addResponse(resp);
- }
-
- return addServerToMap(server);
-}
-
-static enum CallbackType
-{
- CALLBACK_CONNECT,
- CALLBACK_ERROR,
- CALLBACK_RECVMESSAGE,
- CALLBACK_RECVREQUEST,
- CALLBACK_RECVSTATUS,
- CALLBACK_MAX
-};
-
-void connectCallbackWrapper( PEER peer, PEERBool success, int failureReason, void *param )
-{
-#ifdef SERVER_DEBUGGING
- DEBUG_LOG(("In connectCallbackWrapper()\n"));
- CheckServers(peer);
-#endif // SERVER_DEBUGGING
- if (param != NULL)
- {
- ((PeerThreadClass *)param)->connectCallback( peer, success );
- }
-}
-
-void nickErrorCallbackWrapper( PEER peer, Int type, const char *nick, int numSuggestedNicks, const gsi_char** suggestedNicks, void *param )
-{
- if (param != NULL)
- {
- ((PeerThreadClass *)param)->nickErrorCallback( peer, type, nick );
- }
-}
-
-static void joinRoomCallback(PEER peer, PEERBool success, PEERJoinResult result, RoomType roomType, void *param);
-
-//-------------------------------------------------------------------------
-
-GameSpyPeerMessageQueue::GameSpyPeerMessageQueue()
-{
- m_thread = NULL;
- m_serialAuth = SERIAL_OK;
-}
-
-GameSpyPeerMessageQueue::~GameSpyPeerMessageQueue()
-{
- endThread();
-}
-
-void GameSpyPeerMessageQueue::startThread( void )
-{
- if (!m_thread)
- {
- m_thread = NEW PeerThreadClass;
- m_thread->Execute();
- }
- else
- {
- if (!m_thread->Is_Running())
- {
- m_thread->Execute();
- }
- }
-}
-
-void GameSpyPeerMessageQueue::endThread( void )
-{
- if (m_thread)
- delete m_thread;
- m_thread = NULL;
-}
-
-Bool GameSpyPeerMessageQueue::isThreadRunning( void )
-{
- return (m_thread) ? m_thread->Is_Running() : false;
-}
-
-Bool GameSpyPeerMessageQueue::isConnected( void )
-{
- return (m_thread) ? m_thread->isConnected() : false;
-}
-
-Bool GameSpyPeerMessageQueue::isConnecting( void )
-{
- return (m_thread) ? m_thread->isConnecting() : false;
-}
-
-void GameSpyPeerMessageQueue::addRequest( const PeerRequest& req )
-{
- MutexClass::LockClass m(m_requestMutex);
- if (m.Failed())
- return;
-
- m_requests.push(req);
-}
-
-//PeerRequest GameSpyPeerMessageQueue::getRequest( void )
-Bool GameSpyPeerMessageQueue::getRequest( PeerRequest& req )
-{
- MutexClass::LockClass m(m_requestMutex, 0);
- if (m.Failed())
- return false;
-
- if (m_requests.empty())
- return false;
- req = m_requests.front();
- m_requests.pop();
- return true;
-}
-
-void GameSpyPeerMessageQueue::addResponse( const PeerResponse& resp )
-{
- if (resp.nick == "(END)")
- return;
-
- MutexClass::LockClass m(m_responseMutex);
- if (m.Failed())
- return;
-
- m_responses.push(resp);
-}
-
-//PeerResponse GameSpyPeerMessageQueue::getResponse( void )
-Bool GameSpyPeerMessageQueue::getResponse( PeerResponse& resp )
-{
- MutexClass::LockClass m(m_responseMutex, 0);
- if (m.Failed())
- return false;
-
- if (m_responses.empty())
- return false;
- resp = m_responses.front();
- m_responses.pop();
- return true;
-}
-
-PeerThreadClass* GameSpyPeerMessageQueue::getThread( void )
-{
- return m_thread;
-}
-
-//-------------------------------------------------------------------------
-static void disconnectedCallback(PEER peer, const char * reason, void * param);
-static void roomMessageCallback(PEER peer, RoomType roomType, const char * nick, const char * message, MessageType messageType, void * param);
-static void playerMessageCallback(PEER peer, const char * nick, const char * message, MessageType messageType, void * param);
-static void playerJoinedCallback(PEER peer, RoomType roomType, const char * nick, void * param);
-static void playerLeftCallback(PEER peer, RoomType roomType, const char * nick, const char * reason, void * param);
-static void playerChangedNickCallback(PEER peer, RoomType roomType, const char * oldNick, const char * newNick, void * param);
-static void playerInfoCallback(PEER peer, RoomType roomType, const char * nick, unsigned int IP, int profileID, void * param);
-static void playerFlagsChangedCallback(PEER peer, RoomType roomType, const char * nick, int oldFlags, int newFlags, void * param);
-static void listingGamesCallback(PEER peer, PEERBool success, const char * name, SBServer server, PEERBool staging, int msg, Int percentListed, void * param);
-static void roomUTMCallback(PEER peer, RoomType roomType, const char * nick, const char * command, const char * parameters, PEERBool authenticated, void * param);
-static void playerUTMCallback(PEER peer, const char * nick, const char * command, const char * parameters, PEERBool authenticated, void * param);
-static void gameStartedCallback(PEER peer, SBServer server, const char *message, void *param);
-static void globalKeyChangedCallback(PEER peer, const char *nick, const char *key, const char *val, void *param);
-static void roomKeyChangedCallback(PEER peer, RoomType roomType, const char *nick, const char *key, const char *val, void *param);
-
-// convenience function to set buddy status
-static void updateBuddyStatus( GameSpyBuddyStatus status, Int groupRoom = 0, std::string gameName = "" )
-{
- if (!TheGameSpyBuddyMessageQueue)
- return;
-
- BuddyRequest req;
- req.buddyRequestType = BuddyRequest::BUDDYREQUEST_SETSTATUS;
- switch(status)
- {
- case BUDDY_OFFLINE:
- req.arg.status.status = GP_OFFLINE;
- strcpy(req.arg.status.statusString, "Offline");
- strcpy(req.arg.status.locationString, "");
- break;
- case BUDDY_ONLINE:
- req.arg.status.status = GP_ONLINE;
- strcpy(req.arg.status.statusString, "Online");
- strcpy(req.arg.status.locationString, "");
- break;
- case BUDDY_LOBBY:
- req.arg.status.status = GP_CHATTING;
- strcpy(req.arg.status.statusString, "Chatting");
- sprintf(req.arg.status.locationString, "%d", groupRoom);
- break;
- case BUDDY_STAGING:
- req.arg.status.status = GP_STAGING;
- strcpy(req.arg.status.statusString, "Staging");
- sprintf(req.arg.status.locationString, "%s", gameName.c_str());
- break;
- case BUDDY_LOADING:
- req.arg.status.status = GP_PLAYING;
- strcpy(req.arg.status.statusString, "Loading");
- sprintf(req.arg.status.locationString, "%s", gameName.c_str());
- break;
- case BUDDY_PLAYING:
- req.arg.status.status = GP_PLAYING;
- strcpy(req.arg.status.statusString, "Playing");
- sprintf(req.arg.status.locationString, "%s", gameName.c_str());
- break;
- case BUDDY_MATCHING:
- req.arg.status.status = GP_ONLINE;
- strcpy(req.arg.status.statusString, "Matching");
- strcpy(req.arg.status.locationString, "");
- break;
- }
- DEBUG_LOG(("updateBuddyStatus %d:%s\n", req.arg.status.status, req.arg.status.statusString));
- TheGameSpyBuddyMessageQueue->addRequest(req);
-}
-
-static void createRoomCallback(PEER peer, PEERBool success, PEERJoinResult result, RoomType roomType, void *param)
-{
- Int *s = (Int *)param;
- if (s)
- *s = result;
-}
-
-static const char * KeyTypeToString(qr2_key_type type)
-{
- switch(type)
- {
- case key_server:
- return "server";
- case key_player:
- return "player";
- case key_team:
- return "team";
- }
-
- return "Unkown key type";
-}
-
-static const char * ErrorTypeToString(qr2_error_t error)
-{
- switch(error)
- {
- case e_qrnoerror:
- return "noerror";
- case e_qrwsockerror:
- return "wsockerror";
- case e_qrbinderror:
- return "rbinderror";
- case e_qrdnserror:
- return "dnserror";
- case e_qrconnerror:
- return "connerror";
- }
-
- return "Unknown error type";
-}
-
-static void QRServerKeyCallback
-(
- PEER peer,
- int key,
- qr2_buffer_t buffer,
- void * param
-)
-{
- //DEBUG_LOG(("QR_SERVER_KEY | %d (%s)\n", key, qr2_registered_key_list[key]));
- PeerThreadClass *t = (PeerThreadClass *)param;
- if (!t)
- {
- DEBUG_LOG(("QRServerKeyCallback: bailing because of no thread info\n"));
- return;
- }
-
- if (!t->isHosting())
- t->stopHostingAlready(peer);
-
-#ifdef DEBUG_LOGGING
- AsciiString val = "";
-#define ADD(x) { qr2_buffer_add(buffer, x); val = x; }
-#define ADDINT(x) { qr2_buffer_add_int(buffer, x); val.format("%d",x); }
-#else
-#define ADD(x) { qr2_buffer_add(buffer, x); }
-#define ADDINT(x) { qr2_buffer_add_int(buffer, x); }
-#endif
-
- switch(key)
- {
- case HOSTNAME_KEY:
- ADD(t->getPlayerName(0).c_str());
- break;
- case GAMEVER_KEY:
- ADDINT(t->gameVersion());
- break;
- case EXECRC_KEY:
- ADDINT(t->exeCRC());
- break;
- case INICRC_KEY:
- ADDINT(t->iniCRC());
- break;
- case GAMENAME_KEY:
- {
- std::string tmp = t->getPlayerName(0);
- tmp.append(" ");
- tmp.append(WideCharStringToMultiByte(t->getLocalStagingServerName().c_str()));
- ADD(tmp.c_str());
- }
- break;
- case MAPNAME_KEY:
- ADD(t->getMapName().c_str());
- break;
- case PW_KEY:
- ADDINT(t->hasPassword());
- break;
- case OBS_KEY:
- ADDINT(t->allowObservers());
- break;
- case LADIP_KEY:
- ADD(t->ladderIP().c_str());
- break;
- case LADPORT_KEY:
- ADDINT(t->ladderPort());
- break;
- case PINGSTR_KEY:
- ADD(t->pingStr().c_str());
- break;
- case NUMPLAYER_KEY:
- ADDINT(t->getNumPlayers());
- break;
- case MAXPLAYER_KEY:
- ADDINT(t->getMaxPlayers());
- break;
- case NUMOBS_KEY:
- ADDINT(t->getNumObservers());
- break;
- default:
- ADD("");
- //DEBUG_LOG(("QR_SERVER_KEY | %d (%s)\n", key, qr2_registered_key_list[key]));
- break;
- }
-
- DEBUG_LOG(("QR_SERVER_KEY | %d (%s) = [%s]\n", key, qr2_registered_key_list[key], val.str()));
-}
-
-static void QRPlayerKeyCallback
-(
- PEER peer,
- int key,
- int index,
- qr2_buffer_t buffer,
- void * param
-)
-{
- //DEBUG_LOG(("QR_PLAYER_KEY | %d | %d (%s)\n", key, index, qr2_registered_key_list[key]));
- PeerThreadClass *t = (PeerThreadClass *)param;
- if (!t)
- {
- DEBUG_LOG(("QRPlayerKeyCallback: bailing because of no thread info\n"));
- return;
- }
-
- if (!t->isHosting())
- t->stopHostingAlready(peer);
-
-#undef ADD
-#undef ADDINT
-#ifdef DEBUG_LOGGING
- AsciiString val = "";
-#define ADD(x) { qr2_buffer_add(buffer, x); val = x; }
-#define ADDINT(x) { qr2_buffer_add_int(buffer, x); val.format("%d",x); }
-#else
-#define ADD(x) { qr2_buffer_add(buffer, x); }
-#define ADDINT(x) { qr2_buffer_add_int(buffer, x); }
-#endif
-
- switch(key)
- {
- case NAME__KEY:
- ADD(t->getPlayerName(index).c_str());
- break;
- case WINS__KEY:
- ADDINT(t->getPlayerWins(index));
- break;
- case LOSSES__KEY:
- ADDINT(t->getPlayerLosses(index));
- break;
- case PID__KEY:
- ADDINT(t->getPlayerProfileID(index));
- break;
- case FACTION__KEY:
- ADDINT(t->getPlayerLosses(index));
- break;
- case COLOR__KEY:
- ADDINT(t->getPlayerLosses(index));
- break;
- default:
- ADD("");
- //DEBUG_LOG(("QR_PLAYER_KEY | %d | %d (%s)\n", key, index, qr2_registered_key_list[key]));
- break;
- }
-
- DEBUG_LOG(("QR_PLAYER_KEY | %d | %d (%s) = [%s]\n", key, index, qr2_registered_key_list[key], val.str()));
-}
-
-static void QRTeamKeyCallback
-(
- PEER peer,
- int key,
- int index,
- qr2_buffer_t buffer,
- void * param
-)
-{
- //DEBUG_LOG(("QR_TEAM_KEY | %d | %d\n", key, index));
-
- PeerThreadClass *t = (PeerThreadClass *)param;
- if (!t)
- {
- DEBUG_LOG(("QRTeamKeyCallback: bailing because of no thread info\n"));
- return;
- }
- if (!t->isHosting())
- t->stopHostingAlready(peer);
-
- // we don't report teams, so this shouldn't get called
- qr2_buffer_add(buffer, "");
-}
-
-static void QRKeyListCallback
-(
- PEER peer,
- qr2_key_type type,
- qr2_keybuffer_t keyBuffer,
- void * param
-)
-{
- DEBUG_LOG(("QR_KEY_LIST | %s\n", KeyTypeToString(type)));
-
- /*
- PeerThreadClass *t = (PeerThreadClass *)param;
- if (!t)
- {
- DEBUG_LOG(("QRKeyListCallback: bailing because of no thread info\n"));
- return;
- }
- if (!t->isHosting())
- t->stopHostingAlready(peer);
- */
-
- // register the keys we use
- switch(type)
- {
- case key_server:
- qr2_keybuffer_add(keyBuffer, HOSTNAME_KEY);
- qr2_keybuffer_add(keyBuffer, GAMEVER_KEY);
- //qr2_keybuffer_add(keyBuffer, GAMENAME_KEY);
- qr2_keybuffer_add(keyBuffer, MAPNAME_KEY);
- qr2_keybuffer_add(keyBuffer, EXECRC_KEY);
- qr2_keybuffer_add(keyBuffer, INICRC_KEY);
- qr2_keybuffer_add(keyBuffer, PW_KEY);
- qr2_keybuffer_add(keyBuffer, OBS_KEY);
- qr2_keybuffer_add(keyBuffer, LADIP_KEY);
- qr2_keybuffer_add(keyBuffer, LADPORT_KEY);
- qr2_keybuffer_add(keyBuffer, PINGSTR_KEY);
- qr2_keybuffer_add(keyBuffer, NUMPLAYER_KEY);
- qr2_keybuffer_add(keyBuffer, MAXPLAYER_KEY);
- qr2_keybuffer_add(keyBuffer, NUMOBS_KEY);
- break;
- case key_player:
- qr2_keybuffer_add(keyBuffer, NAME__KEY);
- qr2_keybuffer_add(keyBuffer, WINS__KEY);
- qr2_keybuffer_add(keyBuffer, LOSSES__KEY);
- qr2_keybuffer_add(keyBuffer, PID__KEY);
- qr2_keybuffer_add(keyBuffer, FACTION__KEY);
- qr2_keybuffer_add(keyBuffer, COLOR__KEY);
- break;
- case key_team:
- // no custom team keys
- break;
- }
-}
-
-static int QRCountCallback
-(
- PEER peer,
- qr2_key_type type,
- void * param
-)
-{
- PeerThreadClass *t = (PeerThreadClass *)param;
- if (!t)
- {
- DEBUG_LOG(("QRCountCallback: bailing because of no thread info\n"));
- return 0;
- }
- if (!t->isHosting())
- t->stopHostingAlready(peer);
-
- if(type == key_player)
- {
- DEBUG_LOG(("QR_COUNT | %s = %d\n", KeyTypeToString(type), t->getNumPlayers() + t->getNumObservers()));
- return t->getNumPlayers() + t->getNumObservers();
- }
- else if(type == key_team)
- {
- DEBUG_LOG(("QR_COUNT | %s = %d\n", KeyTypeToString(type), 0));
- return 0;
- }
-
- DEBUG_LOG(("QR_COUNT | %s = %d\n", KeyTypeToString(type), 0));
- return 0;
-}
-
-void PeerThreadClass::stopHostingAlready(PEER peer)
-{
- isThreadHosting = 0; // debugging
- s_lastStateChangedHeartbeat = 0;
- s_wantStateChangedHeartbeat = FALSE;
- peerStopGame(peer);
- if (qr2Sock != INVALID_SOCKET)
- {
- closesocket(qr2Sock);
- qr2Sock = INVALID_SOCKET;
- }
-}
-
-static void QRAddErrorCallback
-(
- PEER peer,
- qr2_error_t error,
- char * errorString,
- void * param
-)
-{
- DEBUG_LOG(("QR_ADD_ERROR | %s | %s\n", ErrorTypeToString(error), errorString));
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_FAILEDTOHOST;
- TheGameSpyPeerMessageQueue->addResponse(resp);
-}
-
-static void QRNatNegotiateCallback
-(
- PEER peer,
- int cookie,
- void * param
-)
-{
- DEBUG_LOG(("QR_NAT_NEGOTIATE | 0x%08X\n", cookie));
-}
-
-static void KickedCallback
-(
- PEER peer,
- RoomType roomType,
- const char * nick,
- const char * reason,
- void * param
-)
-{
- DEBUG_LOG(("Kicked from %d by %s: \"%s\"\n", roomType, nick, reason));
-}
-
-static void NewPlayerListCallback
-(
- PEER peer,
- RoomType roomType,
- void * param
-)
-{
- DEBUG_LOG(("NewPlayerListCallback\n"));
-}
-
-static void AuthenticateCDKeyCallback
-(
- PEER peer,
- int result,
- const char * message,
- void * param
-)
-{
- DEBUG_LOG(("CD Key Result: %s (%d) %X\n", message, result, param));
-#ifdef SERVER_DEBUGGING
- CheckServers(peer);
-#endif // SERVER_DEBUGGING
- SerialAuthResult *val = (SerialAuthResult *)param;
- if (val)
- {
- if (result >= 1)
- {
- *val = SERIAL_OK;
- }
- else
- {
- *val = SERIAL_AUTHFAILED;
- }
- }
-#ifdef SERVER_DEBUGGING
- CheckServers(peer);
-#endif // SERVER_DEBUGGING
-}
-
-static SerialAuthResult doCDKeyAuthentication( PEER peer )
-{
- SerialAuthResult retval = SERIAL_NONEXISTENT;
- if (!peer)
- return retval;
-
- AsciiString s = "";
- if (GetStringFromRegistry("\\ergc", "", s) && s.isNotEmpty())
- {
-#ifdef SERVER_DEBUGGING
- DEBUG_LOG(("Before peerAuthenticateCDKey()\n"));
- CheckServers(peer);
-#endif // SERVER_DEBUGGING
- peerAuthenticateCDKey(peer, s.str(), AuthenticateCDKeyCallback, &retval, PEERTrue);
-#ifdef SERVER_DEBUGGING
- DEBUG_LOG(("After peerAuthenticateCDKey()\n"));
- CheckServers(peer);
-#endif // SERVER_DEBUGGING
- }
-
- if (retval == SERIAL_OK)
- {
- PSRequest req;
- req.requestType = PSRequest::PSREQUEST_READCDKEYSTATS;
- req.cdkey = s.str();
- TheGameSpyPSMessageQueue->addRequest(req);
- }
-
- return retval;
-}
-
-#define INBUF_LEN 256
-void checkQR2Queries( PEER peer, SOCKET sock )
-{
- static char indata[INBUF_LEN];
- struct sockaddr_in saddr;
- int saddrlen = sizeof(struct sockaddr_in);
- fd_set set;
- struct timeval timeout = {0,0};
- int error;
-
- FD_ZERO ( &set );
- FD_SET ( sock, &set );
-
- while (1)
- {
- error = select(FD_SETSIZE, &set, NULL, NULL, &timeout);
- if (SOCKET_ERROR == error || 0 == error)
- return;
- //else we have data
- error = recvfrom(sock, indata, INBUF_LEN - 1, 0, (struct sockaddr *)&saddr, &saddrlen);
- if (error != SOCKET_ERROR)
- {
- indata[error] = '\0';
- peerParseQuery( peer, indata, error, (sockaddr *)&saddr );
- }
- }
-}
-
-static UnsignedInt localIP = 0;
-
-void PeerThreadClass::Thread_Function()
-{
- try {
- _set_se_translator( DumpExceptionInfo ); // Hook that allows stack trace.
-
- PEER peer;
-
- // Setup the callbacks.
- ///////////////////////
- PEERCallbacks callbacks;
- memset(&callbacks, 0, sizeof(PEERCallbacks));
- callbacks.disconnected = disconnectedCallback;
- //callbacks.readyChanged = readyChangedCallback;
- callbacks.roomMessage = roomMessageCallback;
- callbacks.playerMessage = playerMessageCallback;
- callbacks.gameStarted = gameStartedCallback;
- callbacks.playerJoined = playerJoinedCallback;
- callbacks.playerLeft = playerLeftCallback;
- callbacks.playerChangedNick = playerChangedNickCallback;
- callbacks.playerFlagsChanged = playerFlagsChangedCallback;
- callbacks.playerInfo = playerInfoCallback;
- callbacks.roomUTM = roomUTMCallback;
- callbacks.playerUTM = playerUTMCallback;
- callbacks.globalKeyChanged = globalKeyChangedCallback;
- callbacks.roomKeyChanged = roomKeyChangedCallback;
-
- callbacks.qrServerKey = QRServerKeyCallback;
- callbacks.qrPlayerKey = QRPlayerKeyCallback;
- callbacks.qrTeamKey = QRTeamKeyCallback;
- callbacks.qrKeyList = QRKeyListCallback;
- callbacks.qrCount = QRCountCallback;
- callbacks.qrAddError = QRAddErrorCallback;
- callbacks.qrNatNegotiateCallback = QRNatNegotiateCallback;
-
- callbacks.kicked = KickedCallback;
- callbacks.newPlayerList = NewPlayerListCallback;
-
- callbacks.param = this;
-
- m_qmGroupRoom = 0;
-
- peer = peerInitialize( &callbacks );
- DEBUG_ASSERTCRASH( peer != NULL, ("NULL peer!") );
- m_isConnected = m_isConnecting = false;
-
- qr2_register_key(EXECRC_KEY, EXECRC_STR);
- qr2_register_key(INICRC_KEY, INICRC_STR);
- qr2_register_key(PW_KEY, PW_STR);
- qr2_register_key(OBS_KEY, OBS_STR);
- qr2_register_key(LADIP_KEY, LADIP_STR);
- qr2_register_key(LADPORT_KEY, LADPORT_STR);
- qr2_register_key(PINGSTR_KEY, PINGSTR_STR);
- qr2_register_key(NUMOBS_KEY, NUMOBS_STR);
- qr2_register_key(NUMPLAYER_KEY, NUMPLAYER_STR);
- qr2_register_key(MAXPLAYER_KEY, MAXPLAYER_STR);
- qr2_register_key(NAME__KEY, NAME__STR "_");
- qr2_register_key(WINS__KEY, WINS__STR "_");
- qr2_register_key(LOSSES__KEY, LOSSES__STR "_");
- qr2_register_key(FACTION__KEY, FACTION__STR "_");
- qr2_register_key(COLOR__KEY, COLOR__STR "_");
-
- const Int NumKeys = 14;
- unsigned char allKeysArray[NumKeys] = {
- /*
- PID__KEY,
- NAME__KEY,
- WINS__KEY,
- LOSSES__KEY,
- FACTION__KEY,
- COLOR__KEY,
- */
- MAPNAME_KEY,
- GAMEVER_KEY,
- GAMENAME_KEY,
- EXECRC_KEY,
- INICRC_KEY,
- PW_KEY,
- OBS_KEY,
- LADIP_KEY,
- LADPORT_KEY,
- PINGSTR_KEY,
- NUMOBS_KEY,
- NUMPLAYER_KEY,
- MAXPLAYER_KEY,
- HOSTNAME_KEY
- };
-
- /*
- const char *allKeys = "\\pid_\\mapname\\gamever\\gamename" \
- "\\" EXECRC_STR "\\" INICRC_STR \
- "\\" PW_STR "\\" OBS_STR "\\" LADIP_STR "\\" LADPORT_STR \
- "\\" PINGSTR_STR "\\" NUMOBS_STR \
- "\\" NUMPLAYER_STR "\\" MAXPLAYER_STR \
- "\\" NAME__STR "_" "\\" WINS__STR "_" "\\" LOSSES__STR "_" "\\" FACTION__STR "_" "\\" COLOR__STR "_";
- */
-
- const char * key = "username";
- peerSetRoomWatchKeys(peer, StagingRoom, 1, &key, PEERTrue);
- peerSetRoomWatchKeys(peer, GroupRoom, 1, &key, PEERTrue);
-
- m_localRoomID = 0;
- m_localStagingServerName = L"";
-
- m_qmStatus = QM_IDLE;
-
- // Setup which rooms to do pings and cross-pings in.
- ////////////////////////////////////////////////////
- PEERBool pingRooms[NumRooms];
- PEERBool crossPingRooms[NumRooms];
- pingRooms[TitleRoom] = PEERFalse;
- pingRooms[GroupRoom] = PEERFalse;
- pingRooms[StagingRoom] = PEERFalse;
- crossPingRooms[TitleRoom] = PEERFalse;
- crossPingRooms[GroupRoom] = PEERFalse;
- crossPingRooms[StagingRoom] = PEERFalse;
-
- /*********
- First step, set our game authentication info
- We could do:
- strcpy(gcd_gamename,"ccgenerals");
- strcpy(gcd_secret_key,"h5T2f6");
- or
- strcpy(gcd_gamename,"ccgeneralsb");
- strcpy(gcd_secret_key,"g3T9s2");
- ...but this is more secure:
- **********/
- char gameName[12];
- char secretKey[7];
- /**
- gameName[0]='c';gameName[1]='c';gameName[2]='g';gameName[3]='e';
- gameName[4]='n';gameName[5]='e';gameName[6]='r';gameName[7]='a';
- gameName[8]='l';gameName[9]='s';gameName[10]='b';gameName[11]='\0';
- secretKey[0]='g';secretKey[1]='3';secretKey[2]='T';secretKey[3]='9';
- secretKey[4]='s';secretKey[5]='2';secretKey[6]='\0';
- /**/
- gameName[0]='c';gameName[1]='c';gameName[2]='g';gameName[3]='e';
- gameName[4]='n';gameName[5]='e';gameName[6]='r';gameName[7]='a';
- gameName[8]='l';gameName[9]='s';gameName[10]='\0';
- secretKey[0]='h';secretKey[1]='5';secretKey[2]='T';secretKey[3]='2';
- secretKey[4]='f';secretKey[5]='6';secretKey[6]='\0';
- /**/
-
- // Set the title.
- /////////////////
- if(!peerSetTitle( peer , gameName, secretKey, gameName, secretKey, GetRegistryVersion(), 30, PEERTrue, pingRooms, crossPingRooms))
- {
- DEBUG_CRASH(("Error setting title"));
- peerShutdown( peer );
- peer = NULL;
- return;
- }
-
- OptionPreferences pref;
- UnsignedInt preferredIP = INADDR_ANY;
- UnsignedInt selectedIP = pref.getOnlineIPAddress();
- DEBUG_LOG(("Looking for IP %X\n", selectedIP));
- IPEnumeration IPs;
- EnumeratedIP *IPlist = IPs.getAddresses();
- while (IPlist)
- {
- DEBUG_LOG(("Looking at IP %s\n", IPlist->getIPstring().str()));
- if (selectedIP == IPlist->getIP())
- {
- preferredIP = IPlist->getIP();
- DEBUG_LOG(("Connecting to GameSpy chat server via IP address %8.8X\n", preferredIP));
- break;
- }
- IPlist = IPlist->getNext();
- }
- //chatSetLocalIP(preferredIP);
-
- UnsignedInt preferredQRPort = 0;
- AsciiString selectedQRPort = pref["GameSpyQRPort"];
- if (selectedQRPort.isNotEmpty())
- {
- preferredQRPort = atoi(selectedQRPort.str());
- }
-
- PeerRequest incomingRequest;
- while ( running )
- {
- // deal with requests
- if (TheGameSpyPeerMessageQueue->getRequest(incomingRequest))
- {
- DEBUG_LOG(("TheGameSpyPeerMessageQueue->getRequest() got request of type %d\n", incomingRequest.peerRequestType));
- switch (incomingRequest.peerRequestType)
- {
- case PeerRequest::PEERREQUEST_LOGIN:
- {
- m_isConnecting = true;
- m_originalName = incomingRequest.nick;
- m_loginName = incomingRequest.nick;
- m_profileID = incomingRequest.login.profileID;
- m_password = incomingRequest.password;
- m_email = incomingRequest.email;
- peerConnect( peer, incomingRequest.nick.c_str(), incomingRequest.login.profileID, nickErrorCallbackWrapper, connectCallbackWrapper, this, PEERTrue );
-#ifdef SERVER_DEBUGGING
- DEBUG_LOG(("After peerConnect()\n"));
- CheckServers(peer);
-#endif // SERVER_DEBUGGING
- if (m_isConnected)
- {
- SerialAuthResult ret = doCDKeyAuthentication( peer );
- if (ret != SERIAL_OK)
- {
- m_isConnecting = m_isConnected = false;
- MESSAGE_QUEUE->setSerialAuthResult( ret );
- peerDisconnect( peer );
- }
- }
- m_isConnecting = false;
-
- // check our connection
- //if (m_isConnected)
- //{
- // GetLocalChatConnectionAddress("peerchat.gamespy.com", 6667, localIP);
- //}
- }
-
- break;
-
- case PeerRequest::PEERREQUEST_LOGOUT:
- m_isConnecting = m_isConnected = false;
- peerDisconnect( peer );
- break;
-
- case PeerRequest::PEERREQUEST_JOINGROUPROOM:
- m_groupRoomID = incomingRequest.groupRoom.id;
- isThreadHosting = 0; // debugging
- s_lastStateChangedHeartbeat = 0;
- s_wantStateChangedHeartbeat = FALSE;
- peerStopGame( peer );
- peerLeaveRoom( peer, GroupRoom, NULL );
- peerLeaveRoom( peer, StagingRoom, NULL );
- if (qr2Sock != INVALID_SOCKET)
- {
- closesocket(qr2Sock);
- qr2Sock = INVALID_SOCKET;
- }
- m_isHosting = false;
- m_localRoomID = m_groupRoomID;
- DEBUG_LOG(("Requesting to join room %d in thread %X\n", m_localRoomID, this));
- peerJoinGroupRoom( peer, incomingRequest.groupRoom.id, joinRoomCallback, (void *)this, PEERTrue );
- break;
-
- case PeerRequest::PEERREQUEST_LEAVEGROUPROOM:
- m_groupRoomID = 0;
- updateBuddyStatus( BUDDY_ONLINE );
- peerLeaveRoom( peer, GroupRoom, NULL );
- peerLeaveRoom( peer, StagingRoom, NULL ); m_isHosting = false;
- break;
-
- case PeerRequest::PEERREQUEST_JOINSTAGINGROOM:
- {
- m_groupRoomID = 0;
- updateBuddyStatus( BUDDY_ONLINE );
- peerLeaveRoom( peer, GroupRoom, NULL );
- peerLeaveRoom( peer, StagingRoom, NULL ); m_isHosting = false;
- SBServer server = findServerByID(incomingRequest.stagingRoom.id);
- m_localStagingServerName = incomingRequest.text;
- DEBUG_LOG(("Setting m_localStagingServerName to [%ls]\n", m_localStagingServerName.c_str()));
- m_localRoomID = incomingRequest.stagingRoom.id;
- DEBUG_LOG(("Requesting to join room %d\n", m_localRoomID));
- if (server)
- {
- peerJoinStagingRoom( peer, server, incomingRequest.password.c_str(), joinRoomCallback, (void *)this, PEERTrue );
- }
- else
- {
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_JOINSTAGINGROOM;
- resp.joinStagingRoom.id = incomingRequest.stagingRoom.id;
- resp.joinStagingRoom.ok = FALSE;
- resp.joinStagingRoom.result = PEERJoinFailed;
- TheGameSpyPeerMessageQueue->addResponse(resp);
- }
- }
- break;
-
- case PeerRequest::PEERREQUEST_LEAVESTAGINGROOM:
- m_groupRoomID = 0;
- updateBuddyStatus( BUDDY_ONLINE );
- peerLeaveRoom( peer, GroupRoom, NULL );
- peerLeaveRoom( peer, StagingRoom, NULL );
- isThreadHosting = 0; // debugging
- s_lastStateChangedHeartbeat = 0;
- s_wantStateChangedHeartbeat = FALSE;
- if (m_isHosting)
- {
- peerStopGame( peer );
- if (qr2Sock != INVALID_SOCKET)
- {
- closesocket(qr2Sock);
- qr2Sock = INVALID_SOCKET;
- }
- m_isHosting = false;
- }
- break;
-
- case PeerRequest::PEERREQUEST_MESSAGEPLAYER:
- {
- std::string s = WideCharStringToMultiByte(incomingRequest.text.c_str());
- peerMessagePlayer( peer, incomingRequest.nick.c_str(), s.c_str(), (incomingRequest.message.isAction)?ActionMessage:NormalMessage );
- }
- break;
-
- case PeerRequest::PEERREQUEST_MESSAGEROOM:
- {
- std::string s = WideCharStringToMultiByte(incomingRequest.text.c_str());
- peerMessageRoom( peer, (m_groupRoomID)?GroupRoom:StagingRoom, s.c_str(), (incomingRequest.message.isAction)?ActionMessage:NormalMessage );
- }
- break;
-
- case PeerRequest::PEERREQUEST_PUSHSTATS:
- {
- DEBUG_LOG(("PEERREQUEST_PUSHSTATS: stats are %d,%d,%d,%d,%d,%d\n",
- incomingRequest.statsToPush.locale, incomingRequest.statsToPush.wins, incomingRequest.statsToPush.losses, incomingRequest.statsToPush.rankPoints, incomingRequest.statsToPush.side, incomingRequest.statsToPush.preorder));
-
- // Testing alternate way to push stats
-#ifdef USE_BROADCAST_KEYS
- _snprintf(s_valueBuffers[0], 20, "%d", incomingRequest.statsToPush.locale);
- _snprintf(s_valueBuffers[1], 20, "%d", incomingRequest.statsToPush.wins);
- _snprintf(s_valueBuffers[2], 20, "%d", incomingRequest.statsToPush.losses);
- _snprintf(s_valueBuffers[3], 20, "%d", incomingRequest.statsToPush.rankPoints);
- _snprintf(s_valueBuffers[4], 20, "%d", incomingRequest.statsToPush.side);
- _snprintf(s_valueBuffers[5], 20, "%d", incomingRequest.statsToPush.preorder);
- pushStatsToRoom(peer);
-#else
- const char *keys[6] = { "locale", "wins", "losses", "points", "side", "pre" };
- char valueStrings[6][20];
- char *values[6] = { valueStrings[0], valueStrings[1], valueStrings[2],
- valueStrings[3], valueStrings[4], valueStrings[5]};
- _snprintf(values[0], 20, "%d", incomingRequest.statsToPush.locale);
- _snprintf(values[1], 20, "%d", incomingRequest.statsToPush.wins);
- _snprintf(values[2], 20, "%d", incomingRequest.statsToPush.losses);
- _snprintf(values[3], 20, "%d", incomingRequest.statsToPush.rankPoints);
- _snprintf(values[4], 20, "%d", incomingRequest.statsToPush.side);
- _snprintf(values[5], 20, "%d", incomingRequest.statsToPush.preorder);
- peerSetGlobalKeys(peer, 6, (const char **)keys, (const char **)values);
- peerSetGlobalWatchKeys(peer, GroupRoom, 0, NULL, PEERFalse);
- peerSetGlobalWatchKeys(peer, StagingRoom, 0, NULL, PEERFalse);
- peerSetGlobalWatchKeys(peer, GroupRoom, 6, keys, PEERTrue);
- peerSetGlobalWatchKeys(peer, StagingRoom, 6, keys, PEERTrue);
-#endif
- }
- break;
-
- case PeerRequest::PEERREQUEST_SETGAMEOPTIONS:
- {
- m_mapName = incomingRequest.gameOptsMapName;
- m_numPlayers = incomingRequest.gameOptions.numPlayers;
- m_numObservers = incomingRequest.gameOptions.numObservers;
- m_maxPlayers = incomingRequest.gameOptions.maxPlayers;
- DEBUG_LOG(("peerStateChanged(): Marking game options state as changed - %d players, %d observers\n", m_numPlayers, m_numObservers));
- for (Int i=0; iaddResponse(resp);
-
- if (res != PEERJoinSuccess && res != PEERAlreadyInRoom)
- {
- m_localRoomID = oldGroupID;
- DEBUG_LOG(("Requesting to join room %d\n", m_localRoomID));
- if (incomingRequest.stagingRoomCreation.restrictGameList)
- {
- peerLeaveRoom( peer, StagingRoom, NULL );
- }
- else
- {
- peerJoinGroupRoom( peer, oldGroupID, joinRoomCallback, (void *)this, PEERTrue );
- }
- m_isHosting = FALSE;
- m_localStagingServerName = L"";
- m_playerNames[0] = "";
- }
- else
- {
- if (incomingRequest.stagingRoomCreation.restrictGameList)
- {
- peerLeaveRoom( peer, GroupRoom, NULL );
- }
- isThreadHosting = 1; // debugging
- s_lastStateChangedHeartbeat = timeGetTime(); // wait the full interval before updating state
- s_wantStateChangedHeartbeat = FALSE;
- m_isHosting = TRUE;
- m_allowObservers = incomingRequest.stagingRoomCreation.allowObservers;
- m_mapName = "";
- for (Int i=0; i 0)
- m_hasPassword = true;
- else
- m_hasPassword = false;
- m_playerNames[0] = m_loginName;
- m_exeCRC = incomingRequest.stagingRoomCreation.exeCRC;
- m_iniCRC = incomingRequest.stagingRoomCreation.iniCRC;
- m_gameVersion = incomingRequest.stagingRoomCreation.gameVersion;
- m_localStagingServerName = incomingRequest.text;
- m_ladderIP = incomingRequest.ladderIP;
- m_pingStr = incomingRequest.hostPingStr;
- m_ladderPort = incomingRequest.stagingRoomCreation.ladPort;
-
-#ifdef USE_BROADCAST_KEYS
- pushStatsToRoom(peer);
-#endif // USE_BROADCAST_KEYS
-
- DEBUG_LOG(("Setting m_localStagingServerName to [%ls]\n", m_localStagingServerName.c_str()));
- updateBuddyStatus( BUDDY_STAGING, 0, WideCharStringToMultiByte(m_localStagingServerName.c_str()) );
- }
- }
- break;
-
- case PeerRequest::PEERREQUEST_STARTGAMELIST:
- {
- m_sawCompleteGameList = FALSE;
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_STAGINGROOM;
- resp.stagingRoom.action = PEER_CLEAR;
- resp.stagingRoom.isStaging = TRUE;
- resp.stagingRoom.percentComplete = 0;
- clearServers();
- TheGameSpyPeerMessageQueue->addResponse(resp);
- peerStartListingGames( peer, allKeysArray, NumKeys, (incomingRequest.gameList.restrictGameList?"~":NULL), listingGamesCallback, this );
- }
- break;
-
- case PeerRequest::PEERREQUEST_STOPGAMELIST:
- {
- peerStopListingGames( peer );
- }
- break;
-
- case PeerRequest::PEERREQUEST_STARTGAME:
- {
- peerStartGame( peer, NULL, PEER_STOP_REPORTING);
- }
- break;
-
- case PeerRequest::PEERREQUEST_UTMPLAYER:
- {
- if (incomingRequest.nick.length() > 0)
- {
- peerUTMPlayer( peer, incomingRequest.nick.c_str(), incomingRequest.id.c_str(), incomingRequest.options.c_str(), PEERFalse );
- }
- }
- break;
-
- case PeerRequest::PEERREQUEST_UTMROOM:
- {
- peerUTMRoom( peer, (incomingRequest.UTM.isStagingRoom)?StagingRoom:GroupRoom, incomingRequest.id.c_str(), incomingRequest.options.c_str(), PEERFalse );
- }
- break;
-
- case PeerRequest::PEERREQUEST_STARTQUICKMATCH:
- {
- m_qmInfo = incomingRequest;
- doQuickMatch( peer );
- }
- break;
-
- }
- }
-
- if (isThreadHosting && s_wantStateChangedHeartbeat)
- {
- UnsignedInt now = timeGetTime();
- if (now > s_lastStateChangedHeartbeat + s_heartbeatInterval)
- {
- s_lastStateChangedHeartbeat = now;
- s_wantStateChangedHeartbeat = FALSE;
- peerStateChanged( peer );
-
-#ifdef DEBUG_LOGGING
- static UnsignedInt prev = 0;
- UnsignedInt now = timeGetTime();
- UnsignedInt diff = now - prev;
- prev = now;
-#endif
- STATECHANGED_LOG(("peerStateChanged() at time %d (difference of %d ms)\n", now, diff));
- }
- }
-
- // update the network
- PEERBool isConnected = PEERTrue;
- isConnected = peerIsConnected( peer );
- if ( isConnected == PEERTrue )
- {
- if (qr2Sock != INVALID_SOCKET)
- {
- // check hosting activity
- checkQR2Queries( peer, qr2Sock );
- }
- peerThink( peer );
- }
-
- // end our timeslice
- Switch_Thread();
- }
-
- DEBUG_LOG(("voluntarily ending peer thread %d\n", running));
- peerShutdown( peer );
-
- } catch ( ... ) {
- DEBUG_CRASH(("Exception in peer thread!"));
-
- try {
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_DISCONNECT;
- resp.discon.reason = DISCONNECT_LOSTCON;
- TheGameSpyPeerMessageQueue->addResponse(resp);
- }
- catch (...)
- {
- }
- }
-}
-
-static void qmProfileIDCallback( PEER peer, PEERBool success, const char *nick, int profileID, void *param )
-{
- Int *i = (Int *)param;
- if (!i || !success || !nick)
- return;
-
- *i = profileID;
-}
-
-static Int matchbotProfileID = 0;
-void quickmatchEnumPlayersCallback( PEER peer, PEERBool success, RoomType roomType, int index, const char * nick, int flags, void * param )
-{
- PeerThreadClass *t = (PeerThreadClass *)param;
- if (!t || !success || nick == NULL || nick[0] == '\0')
- {
- t->sawEndOfEnumPlayers();
- return;
- }
-
- Int id = 0;
- peerGetPlayerProfileID(peer, nick, qmProfileIDCallback, &id, PEERTrue);
- DEBUG_LOG(("Saw player %s with id %d (looking for %d)\n", nick, id, matchbotProfileID));
- if (id == matchbotProfileID)
- {
- t->sawMatchbot(nick);
- }
-
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_PLAYERJOIN;
- resp.nick = nick;
- resp.player.roomType = roomType;
- resp.player.IP = 0;
-
- TheGameSpyPeerMessageQueue->addResponse(resp);
-}
-
-void PeerThreadClass::handleQMMatch(PEER peer, Int mapIndex, Int seed,
- char *playerName[MAX_SLOTS],
- char *playerIP[MAX_SLOTS],
- char *playerSide[MAX_SLOTS],
- char *playerColor[MAX_SLOTS],
- char *playerNAT[MAX_SLOTS])
-{
- if (m_qmStatus == QM_WORKING)
- {
- m_qmStatus = QM_MATCHED;
- peerLeaveRoom(peer, GroupRoom, "");
-
- for (Int i=0; iaddResponse(resp);
- }
-}
-
-void PeerThreadClass::doQuickMatch( PEER peer )
-{
- m_qmStatus = QM_JOININGQMCHANNEL;
- Bool done = false;
- matchbotProfileID = m_qmInfo.QM.botID;
- setQMGroupRoom( m_qmInfo.QM.roomID );
- m_sawMatchbot = false;
- updateBuddyStatus( BUDDY_MATCHING );
- while (!done && running)
- {
- if (!peerIsConnected( peer ))
- {
- done = true;
- }
- else
- {
- // update the network
- peerThink( peer );
-
- // end our timeslice
- Switch_Thread();
-
- PeerRequest incomingRequest;
- if (TheGameSpyPeerMessageQueue->getRequest(incomingRequest))
- {
- switch (incomingRequest.peerRequestType)
- {
- case PeerRequest::PEERREQUEST_WIDENQUICKMATCHSEARCH:
- {
- if (m_qmStatus != QM_IDLE && m_qmStatus != QM_STOPPED && m_sawMatchbot)
- {
- peerMessagePlayer( peer, m_matchbotName.c_str(), "\\WIDEN", NormalMessage );
- }
- }
- break;
- case PeerRequest::PEERREQUEST_STOPQUICKMATCH:
- {
- m_qmStatus = QM_STOPPED;
- peerLeaveRoom(peer, GroupRoom, "");
- done = true;
- }
- break;
- case PeerRequest::PEERREQUEST_LOGOUT:
- {
- m_qmStatus = QM_STOPPED;
- peerLeaveRoom(peer, GroupRoom, "");
- done = true;
- }
- break;
- case PeerRequest::PEERREQUEST_LEAVEGROUPROOM:
- {
- m_qmStatus = QM_STOPPED;
- peerLeaveRoom(peer, GroupRoom, "");
- done = true;
- }
- break;
- case PeerRequest::PEERREQUEST_UTMPLAYER:
- {
- peerUTMPlayer( peer, incomingRequest.nick.c_str(), incomingRequest.id.c_str(), incomingRequest.options.c_str(), PEERFalse );
- }
- break;
- default:
- {
- DEBUG_CRASH(("Unanticipated request %d to peer thread!", incomingRequest.peerRequestType));
- }
- break;
- }
- }
-
- if (!done)
- {
- // do the next bit of QM
- switch (m_qmStatus)
- {
- case QM_JOININGQMCHANNEL:
- {
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_QUICKMATCHSTATUS;
- resp.qmStatus.status = QM_JOININGQMCHANNEL;
- TheGameSpyPeerMessageQueue->addResponse(resp);
-
- m_groupRoomID = m_qmGroupRoom;
- peerLeaveRoom( peer, GroupRoom, NULL );
- peerLeaveRoom( peer, StagingRoom, NULL ); m_isHosting = false;
- m_localRoomID = m_groupRoomID;
- m_roomJoined = false;
- DEBUG_LOG(("Requesting to join room %d in thread %X\n", m_localRoomID, this));
- peerJoinGroupRoom( peer, m_localRoomID, joinRoomCallback, (void *)this, PEERTrue );
- if (m_roomJoined)
- {
- resp.peerResponseType = PeerResponse::PEERRESPONSE_QUICKMATCHSTATUS;
- resp.qmStatus.status = QM_LOOKINGFORBOT;
- TheGameSpyPeerMessageQueue->addResponse(resp);
-
- m_qmStatus = QM_LOOKINGFORBOT;
- m_sawMatchbot = false;
- m_sawEndOfEnumPlayers = false;
- peerEnumPlayers( peer, GroupRoom, quickmatchEnumPlayersCallback, this );
- }
- else
- {
- resp.peerResponseType = PeerResponse::PEERRESPONSE_QUICKMATCHSTATUS;
- resp.qmStatus.status = QM_COULDNOTFINDBOT;
- TheGameSpyPeerMessageQueue->addResponse(resp);
- done = true;
- m_qmStatus = QM_STOPPED;
- }
- }
- break;
- case QM_LOOKINGFORBOT:
- {
- if (m_sawEndOfEnumPlayers)
- {
- if (m_sawMatchbot)
- {
- char buf[64];
- buf[63] = '\0';
- std::string msg = "\\CINFO";
- _snprintf(buf, 63, "\\Widen\\%d", m_qmInfo.QM.widenTime);
- msg.append(buf);
- _snprintf(buf, 63, "\\LadID\\%d", m_qmInfo.QM.ladderID);
- msg.append(buf);
- _snprintf(buf, 63, "\\LadPass\\%d", m_qmInfo.QM.ladderPassCRC);
- msg.append(buf);
- _snprintf(buf, 63, "\\PointsMin\\%d", m_qmInfo.QM.minPointPercentage);
- msg.append(buf);
- _snprintf(buf, 63, "\\PointsMax\\%d", m_qmInfo.QM.maxPointPercentage);
- msg.append(buf);
- _snprintf(buf, 63, "\\Points\\%d", m_qmInfo.QM.points);
- msg.append(buf);
- _snprintf(buf, 63, "\\Discons\\%d", m_qmInfo.QM.discons);
- msg.append(buf);
- _snprintf(buf, 63, "\\DisconMax\\%d", m_qmInfo.QM.maxDiscons);
- msg.append(buf);
- _snprintf(buf, 63, "\\NumPlayers\\%d", m_qmInfo.QM.numPlayers);
- msg.append(buf);
- _snprintf(buf, 63, "\\Pings\\%s", m_qmInfo.QM.pings);
- msg.append(buf);
- _snprintf(buf, 63, "\\IP\\%d", ntohl(peerGetLocalIP(peer)));// not ntohl(localIP), as we need EXTERNAL address for proper NAT negotiation!
- msg.append(buf);
- _snprintf(buf, 63, "\\Side\\%d", m_qmInfo.QM.side);
- msg.append(buf);
- _snprintf(buf, 63, "\\Color\\%d", m_qmInfo.QM.color);
- msg.append(buf);
- _snprintf(buf, 63, "\\NAT\\%d", m_qmInfo.QM.NAT);
- msg.append(buf);
- _snprintf(buf, 63, "\\EXE\\%d", m_qmInfo.QM.exeCRC);
- msg.append(buf);
- _snprintf(buf, 63, "\\INI\\%d", m_qmInfo.QM.iniCRC);
- msg.append(buf);
- buf[0] = 0;
- msg.append("\\Maps\\");
- for (Int i=0; iaddResponse(resp);
- }
- else
- {
- // no QM bot. Bail.
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_QUICKMATCHSTATUS;
- resp.qmStatus.status = QM_COULDNOTFINDBOT;
- TheGameSpyPeerMessageQueue->addResponse(resp);
-
- m_qmStatus = QM_STOPPED;
- peerLeaveRoom(peer, GroupRoom, "");
- done = true;
- }
- }
- }
- break;
- case QM_WORKING:
- {
- }
- break;
- case QM_MATCHED:
- {
- // leave QM channel, and clean up. Our work here is done.
- peerLeaveRoom( peer, GroupRoom, NULL );
- peerLeaveRoom( peer, StagingRoom, NULL ); m_isHosting = false;
-
- m_qmStatus = QM_STOPPED;
- peerLeaveRoom(peer, GroupRoom, "");
- done = true;
- }
- break;
- case QM_INCHANNEL:
- {
- }
- break;
- case QM_NEGOTIATINGFIREWALLS:
- {
- }
- break;
- case QM_STARTINGGAME:
- {
- }
- break;
- case QM_COULDNOTFINDCHANNEL:
- {
- }
- break;
- case QM_COULDNOTNEGOTIATEFIREWALLS:
- {
- }
- break;
- }
- }
- }
- }
- updateBuddyStatus( BUDDY_ONLINE );
-}
-
-static void getPlayerProfileIDCallback(PEER peer, PEERBool success, const char * nick, int profileID, void * param)
-{
- if (success && param != NULL)
- {
- *((Int *)param) = profileID;
- }
-}
-
-static void stagingRoomPlayerEnum( PEER peer, PEERBool success, RoomType roomType, int index, const char * nick, int flags, void * param )
-{
- DEBUG_LOG(("Enum: success=%d, index=%d, nick=%s, flags=%d\n", success, index, nick, flags));
- if (!nick || !success)
- return;
-
- Int id = 0;
- peerGetPlayerProfileID(peer, nick, getPlayerProfileIDCallback, &id, PEERTrue);
- DEBUG_ASSERTCRASH(id != 0, ("Failed to fetch player ID!"));
-
- PeerResponse *resp = (PeerResponse *)param;
- if (flags & PEER_FLAG_OP)
- {
- resp->joinStagingRoom.isHostPresent = TRUE;
- }
- if (index < MAX_SLOTS)
- {
- resp->stagingRoomPlayerNames[index] = nick;
- }
-
- if (id)
- {
- PSRequest req;
- req.requestType = PSRequest::PSREQUEST_READPLAYERSTATS;
- req.player.id = id;
- TheGameSpyPSMessageQueue->addRequest(req);
- }
-}
-
-static void joinRoomCallback(PEER peer, PEERBool success, PEERJoinResult result, RoomType roomType, void *param)
-{
- DEBUG_LOG(("JoinRoomCallback: success==%d, result==%d\n", success, result));
- PeerThreadClass *t = (PeerThreadClass *)param;
- if (!t)
- return;
- DEBUG_LOG(("Room id was %d from thread %X\n", t->getLocalRoomID(), t));
- DEBUG_LOG(("Current staging server name is [%ls]\n", t->getLocalStagingServerName().c_str()));
- DEBUG_LOG(("Room type is %d (GroupRoom=%d, StagingRoom=%d, TitleRoom=%d)\n", roomType, GroupRoom, StagingRoom, TitleRoom));
-
-#ifdef USE_BROADCAST_KEYS
- if (success)
- {
- t->pushStatsToRoom(peer);
- t->getStatsFromRoom(peer, roomType);
- }
-#endif // USE_BROADCAST_KEYS
-
- switch (roomType)
- {
- case GroupRoom:
- {
-#ifdef USE_BROADCAST_KEYS
- t->clearPlayerStats(GroupRoom);
-#endif // USE_BROADCAST_KEYS
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_JOINGROUPROOM;
- resp.joinGroupRoom.id = t->getLocalRoomID();
- resp.joinGroupRoom.ok = success;
- TheGameSpyPeerMessageQueue->addResponse(resp);
- t->roomJoined(success == PEERTrue);
- DEBUG_LOG(("Entered group room %d, qm is %d\n", t->getLocalRoomID(), t->getQMGroupRoom()));
- if ((!t->getQMGroupRoom()) || (t->getQMGroupRoom() != t->getLocalRoomID()))
- {
- DEBUG_LOG(("Updating buddy status\n"));
- updateBuddyStatus( BUDDY_LOBBY, t->getLocalRoomID() );
- }
- }
- break;
- case StagingRoom:
- {
-#ifdef USE_BROADCAST_KEYS
- t->clearPlayerStats(StagingRoom);
-#endif // USE_BROADCAST_KEYS
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_JOINSTAGINGROOM;
- resp.joinStagingRoom.id = t->getLocalRoomID();
- resp.joinStagingRoom.ok = success;
- resp.joinStagingRoom.result = result;
- if (success)
- {
- DEBUG_LOG(("joinRoomCallback() - game name is now '%ls'\n", t->getLocalStagingServerName().c_str()));
- updateBuddyStatus( BUDDY_STAGING, 0, WideCharStringToMultiByte(t->getLocalStagingServerName().c_str()) );
- }
-
- resp.joinStagingRoom.isHostPresent = FALSE;
- DEBUG_LOG(("Enum of staging room players\n"));
- peerEnumPlayers(peer, StagingRoom, stagingRoomPlayerEnum, &resp);
- DEBUG_LOG(("Host %s present\n", (resp.joinStagingRoom.isHostPresent)?"is":"is not"));
-
- TheGameSpyPeerMessageQueue->addResponse(resp);
- }
- break;
- }
-}
-
-// Gets called once for each group room when listing group rooms.
-// After this has been called for each group room, it will be
-// called one more time with groupID==0 and name==NULL.
-/////////////////////////////////////////////////////////////////
-static void listGroupRoomsCallback(PEER peer, PEERBool success,
- int groupID, SBServer server,
- const char * name, int numWaiting,
- int maxWaiting, int numGames,
- int numPlaying, void * param)
-{
- DEBUG_LOG(("listGroupRoomsCallback, success=%d, server=%X, groupID=%d\n", success, server, groupID));
-#ifdef SERVER_DEBUGGING
- CheckServers(peer);
-#endif // SERVER_DEBUGGING
- PeerThreadClass *t = (PeerThreadClass *)param;
- if (!t)
- {
- DEBUG_LOG(("No thread! Bailing!\n"));
- return;
- }
-
- if (success)
- {
- DEBUG_LOG(("Saw group room of %d (%s) at address %X %X\n", groupID, name, server, (server)?server->keyvals:0));
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_GROUPROOM;
- resp.groupRoom.id = groupID;
- resp.groupRoom.numWaiting = numWaiting;
- resp.groupRoom.maxWaiting = maxWaiting;
- resp.groupRoom.numGames = numGames;
- resp.groupRoom.numPlaying = numPlaying;
- if (name)
- {
- resp.groupRoomName = name;
- //t->setQMGroupRoom(groupID);
- }
- else
- {
- resp.groupRoomName.empty();
- }
- TheGameSpyPeerMessageQueue->addResponse(resp);
-#ifdef SERVER_DEBUGGING
- CheckServers(peer);
- DEBUG_LOG(("\n"));
-#endif // SERVER_DEBUGGING
- }
- else
- {
- DEBUG_LOG(("Failure!\n"));
- }
-}
-
-void PeerThreadClass::connectCallback( PEER peer, PEERBool success )
-{
- PeerResponse resp;
- if(!success)
- {
- //updateBuddyStatus( BUDDY_OFFLINE );
- resp.peerResponseType = PeerResponse::PEERRESPONSE_DISCONNECT;
- resp.discon.reason = DISCONNECT_COULDNOTCONNECT;
- TheGameSpyPeerMessageQueue->addResponse(resp);
- return;
- }
-
- updateBuddyStatus( BUDDY_ONLINE );
-
- m_isConnected = true;
- DEBUG_LOG(("Connected as profile %d (%s)\n", m_profileID, m_loginName.c_str()));
- resp.peerResponseType = PeerResponse::PEERRESPONSE_LOGIN;
- resp.player.profileID = m_profileID;
- resp.nick = m_loginName;
- GetLocalChatConnectionAddress("peerchat.gamespy.com", 6667, localIP);
- //chatSetLocalIP(localIP);
- resp.player.internalIP = ntohl(localIP);
- resp.player.externalIP = ntohl(peerGetLocalIP(peer));
- TheGameSpyPeerMessageQueue->addResponse(resp);
-
- PSRequest psReq;
- psReq.requestType = PSRequest::PSREQUEST_READPLAYERSTATS;
- psReq.player.id = m_profileID;
- psReq.nick = m_originalName;
- psReq.email = m_email;
- psReq.password = m_password;
- TheGameSpyPSMessageQueue->addRequest(psReq);
-
-#ifdef SERVER_DEBUGGING
- DEBUG_LOG(("Before peerListGroupRooms()\n"));
- CheckServers(peer);
-#endif // SERVER_DEBUGGING
- peerListGroupRooms( peer, NULL, listGroupRoomsCallback, this, PEERTrue );
-#ifdef SERVER_DEBUGGING
- DEBUG_LOG(("After peerListGroupRooms()\n"));
- CheckServers(peer);
-#endif // SERVER_DEBUGGING
-}
-
-void PeerThreadClass::nickErrorCallback( PEER peer, Int type, const char *nick )
-{
- if(type == PEER_IN_USE)
- {
- Int len = strlen(nick);
- std::string nickStr = nick;
- Int newVal = 0;
- if (nick[len-1] == '}' && nick[len-3] == '{' && isdigit(nick[len-2]))
- {
- newVal = nick[len-2] - '0' + 1;
- nickStr.erase(len-3, 3);
- }
-
- DEBUG_LOG(("Nickname taken: was %s, new val = %d, new nick = %s\n", nick, newVal, nickStr.c_str()));
-
- if (newVal < 10)
- {
- nickStr.append("{");
- char tmp[2];
- tmp[0] = '0'+newVal;
- tmp[1] = '\0';
- nickStr.append(tmp);
- nickStr.append("}");
- // Retry the connect with a similar nick.
- m_loginName = nickStr;
- peerRetryWithNick(peer, nickStr.c_str());
- }
- else
- {
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_DISCONNECT;
- resp.discon.reason = DISCONNECT_NICKTAKEN;
- TheGameSpyPeerMessageQueue->addResponse(resp);
-
- // Cancel the connect.
- peerRetryWithNick(peer, NULL);
- }
- }
- else
- {
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_DISCONNECT;
- resp.discon.reason = DISCONNECT_BADNICK;
- TheGameSpyPeerMessageQueue->addResponse(resp);
-
- // Cancel the connect.
- peerRetryWithNick(peer, NULL);
- }
-}
-
-void disconnectedCallback(PEER peer, const char * reason, void * param)
-{
- DEBUG_LOG(("disconnectedCallback(): reason was '%s'\n", reason));
- PeerThreadClass *t = (PeerThreadClass *)param;
- DEBUG_ASSERTCRASH(t, ("No Peer thread!"));
- if (t)
- t->markAsDisconnected();
- //updateBuddyStatus( BUDDY_OFFLINE );
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_DISCONNECT;
- resp.discon.reason = DISCONNECT_LOSTCON;
- SerialAuthResult res = TheGameSpyPeerMessageQueue->getSerialAuthResult();
- switch (res)
- {
- case SERIAL_NONEXISTENT:
- resp.discon.reason = DISCONNECT_SERIAL_NOT_PRESENT;
- break;
- case SERIAL_AUTHFAILED:
- resp.discon.reason = DISCONNECT_SERIAL_INVALID;
- break;
- case SERIAL_BANNED:
- resp.discon.reason = DISCONNECT_SERIAL_BANNED;
- break;
- }
- TheGameSpyPeerMessageQueue->addResponse(resp);
-}
-
-void roomMessageCallback(PEER peer, RoomType roomType, const char * nick, const char * message, MessageType messageType, void * param)
-{
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_MESSAGE;
- resp.nick = nick;
- resp.text = MultiByteToWideCharSingleLine(message);
- resp.message.isPrivate = FALSE;
- resp.message.isAction = (messageType == ActionMessage);
- TheGameSpyPeerMessageQueue->addResponse(resp);
- DEBUG_LOG(("Saw text [%hs] (%ls) %d chars Orig was %s (%d chars)\n", nick, resp.text.c_str(), resp.text.length(), message, strlen(message)));
-
- UnsignedInt IP;
- peerGetPlayerInfoNoWait(peer, nick, &IP, &resp.message.profileID);
-
- PeerThreadClass *t = (PeerThreadClass *)param;
- DEBUG_ASSERTCRASH(t, ("No Peer thread!"));
- if (t && (t->getQMStatus() != QM_IDLE && t->getQMStatus() != QM_STOPPED))
- {
- if (resp.message.profileID == matchbotProfileID)
- {
- char *lastStr = NULL;
- char *cmd = strtok_r((char *)message, " ", &lastStr);
- if ( cmd && strcmp(cmd, "MBOT:POOLSIZE") == 0 )
- {
- Int poolSize = 0;
-
- while (1)
- {
- char *poolStr = strtok_r(NULL, " ", &lastStr);
- char *sizeStr = strtok_r(NULL, " ", &lastStr);
- if (poolStr && sizeStr)
- {
- Int pool = atoi(poolStr);
- Int size = atoi(sizeStr);
- if (pool == t->getQMLadder())
- {
- poolSize = size;
- break;
- }
- }
- else
- break;
- }
-
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_QUICKMATCHSTATUS;
- resp.qmStatus.status = QM_POOLSIZE;
- resp.qmStatus.poolSize = poolSize;
- TheGameSpyPeerMessageQueue->addResponse(resp);
- }
- }
- }
-}
-
-void gameStartedCallback( PEER peer, SBServer server, const char *message, void *param )
-{
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_GAMESTART;
- TheGameSpyPeerMessageQueue->addResponse(resp);
-}
-
-void playerMessageCallback(PEER peer, const char * nick, const char * message, MessageType messageType, void * param)
-{
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_MESSAGE;
- resp.nick = nick;
- resp.text = MultiByteToWideCharSingleLine(message);
- resp.message.isPrivate = TRUE;
- resp.message.isAction = (messageType == ActionMessage);
- UnsignedInt IP;
- peerGetPlayerInfoNoWait(peer, nick, &IP, &resp.message.profileID);
- TheGameSpyPeerMessageQueue->addResponse(resp);
-
-
- PeerThreadClass *t = (PeerThreadClass *)param;
- DEBUG_ASSERTCRASH(t, ("No Peer thread!"));
- if (t && (t->getQMStatus() != QM_IDLE && t->getQMStatus() != QM_STOPPED))
- {
- if (resp.message.isPrivate && resp.message.profileID == matchbotProfileID)
- {
- char *lastStr = NULL;
- char *cmd = strtok_r((char *)message, " ", &lastStr);
- if ( cmd && strcmp(cmd, "MBOT:MATCHED") == 0 )
- {
- char *mapNumStr = strtok_r(NULL, " ", &lastStr);
- char *seedStr = strtok_r(NULL, " ", &lastStr);
- char *playerStr[MAX_SLOTS];
- char *playerIPStr[MAX_SLOTS];
- char *playerSideStr[MAX_SLOTS];
- char *playerColorStr[MAX_SLOTS];
- char *playerNATStr[MAX_SLOTS];
- Int numPlayers = 0;
- for (Int i=0; i 1)
- {
- // woohoo! got everything needed for a match!
- DEBUG_LOG(("Saw %d-player QM match: map index = %s, seed = %s\n", numPlayers, mapNumStr, seedStr));
- t->handleQMMatch(peer, atoi(mapNumStr), atoi(seedStr), playerStr, playerIPStr, playerSideStr, playerColorStr, playerNATStr);
- }
- }
- else if ( cmd && strcmp(cmd, "MBOT:WORKING") == 0 )
- {
- Int poolSize = 0;
- char *poolStr = strtok_r(NULL, " ", &lastStr);
- if (poolStr)
- poolSize = atoi(poolStr);
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_QUICKMATCHSTATUS;
- resp.qmStatus.status = QM_WORKING;
- resp.qmStatus.poolSize = poolSize;
- TheGameSpyPeerMessageQueue->addResponse(resp);
- }
- else if ( cmd && strcmp(cmd, "MBOT:WIDENINGSEARCH") == 0 )
- {
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_QUICKMATCHSTATUS;
- resp.qmStatus.status = QM_WIDENINGSEARCH;
- TheGameSpyPeerMessageQueue->addResponse(resp);
- }
- }
- }
-}
-
-void roomUTMCallback(PEER peer, RoomType roomType, const char * nick, const char * command, const char * parameters, PEERBool authenticated, void * param)
-{
- DEBUG_LOG(("roomUTMCallback: %s says %s = [%s]\n", nick, command, parameters));
- if (roomType != StagingRoom)
- return;
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_ROOMUTM;
- resp.nick = nick;
- resp.command = command;
- resp.commandOptions = parameters;
- TheGameSpyPeerMessageQueue->addResponse(resp);
-}
-
-void playerUTMCallback(PEER peer, const char * nick, const char * command, const char * parameters, PEERBool authenticated, void * param)
-{
- DEBUG_LOG(("playerUTMCallback: %s says %s = [%s]\n", nick, command, parameters));
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_PLAYERUTM;
- resp.nick = nick;
- resp.command = command;
- resp.commandOptions = parameters;
- TheGameSpyPeerMessageQueue->addResponse(resp);
-}
-
-static void getPlayerInfo(PeerThreadClass *t, PEER peer, const char *nick, Int& id, UnsignedInt& IP,
- std::string& locale, Int& wins, Int& losses, Int& rankPoints, Int& side, Int& preorder,
- RoomType roomType, Int& flags)
-{
- if (!t || !nick)
- return;
- peerGetPlayerInfoNoWait(peer, nick, &IP, &id);
-#ifdef USE_BROADCAST_KEYS
- //locale.printf
- Int localeIndex = t->lookupStatForPlayer(roomType, nick, "b_locale");
- AsciiString tmp;
- tmp.format("%d", localeIndex);
- locale = tmp.str();
-
- wins = t->lookupStatForPlayer(roomType, nick, "b_wins");
- losses = t->lookupStatForPlayer(roomType, nick, "b_losses");
- rankPoints = t->lookupStatForPlayer(roomType, nick, "b_points");
- side = t->lookupStatForPlayer(roomType, nick, "b_side");
- preorder = t->lookupStatForPlayer(roomType, nick, "b_pre");
-#else // USE_BROADCAST_KEYS
- const char *s;
- s = peerGetGlobalWatchKey(peer, nick, "locale");
- locale = (s)?s:"";
- s = peerGetGlobalWatchKey(peer, nick, "wins");
- wins = atoi((s)?s:"");
- s = peerGetGlobalWatchKey(peer, nick, "losses");
- losses = atoi((s)?s:"");
- s = peerGetGlobalWatchKey(peer, nick, "points");
- rankPoints = atoi((s)?s:"");
- s = peerGetGlobalWatchKey(peer, nick, "side");
- side = atoi((s)?s:"");
- s = peerGetGlobalWatchKey(peer, nick, "pre");
- preorder = atoi((s)?s:"");
-#endif // USE_BROADCAST_KEYS
- flags = 0;
- peerGetPlayerFlags(peer, nick, roomType, &flags);
- DEBUG_LOG(("getPlayerInfo(%d) - %s has locale %s, wins:%d, losses:%d, rankPoints:%d, side:%d, preorder:%d\n",
- id, nick, locale.c_str(), wins, losses, rankPoints, side, preorder));
-}
-
-static void roomKeyChangedCallback(PEER peer, RoomType roomType, const char *nick, const char *key, const char *val, void *param)
-{
-#ifdef USE_BROADCAST_KEYS
- PeerThreadClass *t = (PeerThreadClass *)param;
- DEBUG_ASSERTCRASH(t, ("No Peer thread!"));
- DEBUG_ASSERTCRASH(nick && key && val, ("Bad values %X %X %X\n", nick, key, val));
- if (!t || !nick || !key || !val)
- {
- DEBUG_ASSERTLOG(!nick, ("nick = %s\n", nick));
- DEBUG_ASSERTLOG(!key, ("key = %s\n", key));
- DEBUG_ASSERTLOG(!val, ("val = %s\n", val));
- return;
- }
-
-#ifdef DEBUG_LOGGING
- if (strcmp(key, "username") && strcmp(key, "b_flags"))
- {
- DEBUG_LOG(("roomKeyChangedCallback() - %s set %s=%s\n", nick, key, val));
- }
-#endif
-
- t->trackStatsForPlayer(roomType, nick, key, val);
-
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_PLAYERINFO;
- resp.nick = nick;
- resp.player.roomType = roomType;
-
- getPlayerInfo(t, peer, nick, resp.player.profileID, resp.player.IP,
- resp.locale, resp.player.wins, resp.player.losses,
- resp.player.rankPoints, resp.player.side, resp.player.preorder,
- resp.player.roomType, resp.player.flags);
- TheGameSpyPeerMessageQueue->addResponse(resp);
-#endif // USE_BROADCAST_KEYS
-}
-
-#ifdef USE_BROADCAST_KEYS
-void getRoomKeysCallback(PEER peer, PEERBool success, RoomType roomType, const char *nick, int num, char **keys, char **values, void *param)
-{
- PeerThreadClass *t = (PeerThreadClass *)param;
- DEBUG_ASSERTCRASH(t, ("No Peer thread!"));
- DEBUG_ASSERTCRASH(keys && values, ("bad key/value %X/%X", keys, values));
- if (!t || !nick || !num || !success || !keys || !values)
- return;
-
- for (Int i=0; itrackStatsForPlayer(roomType, nick, keys[i], values[i]);
- }
-
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_PLAYERINFO;
- resp.nick = nick;
- resp.player.roomType = roomType;
-
- getPlayerInfo(t, peer, nick, resp.player.profileID, resp.player.IP,
- resp.locale, resp.player.wins, resp.player.losses,
- resp.player.rankPoints, resp.player.side, resp.player.preorder,
- resp.player.roomType, resp.player.flags);
- TheGameSpyPeerMessageQueue->addResponse(resp);
-}
-#endif // USE_BROADCAST_KEYS
-
-static void globalKeyChangedCallback(PEER peer, const char *nick, const char *key, const char *val, void *param)
-{
- if (!nick)
- return;
-
- PeerThreadClass *t = (PeerThreadClass *)param;
- DEBUG_ASSERTCRASH(t, ("No Peer thread!"));
- if (!t)
- return;
-
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_PLAYERINFO;
- resp.nick = nick;
- resp.player.roomType = t->getCurrentGroupRoom()?GroupRoom:StagingRoom;
-
- getPlayerInfo(t, peer, nick, resp.player.profileID, resp.player.IP,
- resp.locale, resp.player.wins, resp.player.losses,
- resp.player.rankPoints, resp.player.side, resp.player.preorder,
- resp.player.roomType, resp.player.flags);
- TheGameSpyPeerMessageQueue->addResponse(resp);
-}
-
-void playerJoinedCallback(PEER peer, RoomType roomType, const char * nick, void * param)
-{
- if (!nick)
- return;
-
- PeerThreadClass *t = (PeerThreadClass *)param;
- DEBUG_ASSERTCRASH(t, ("No Peer thread!"));
- if (!t)
- return;
-
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_PLAYERJOIN;
- resp.nick = nick;
- resp.player.roomType = roomType;
-
- getPlayerInfo(t, peer, nick, resp.player.profileID, resp.player.IP,
- resp.locale, resp.player.wins, resp.player.losses,
- resp.player.rankPoints, resp.player.side, resp.player.preorder,
- roomType, resp.player.flags);
- TheGameSpyPeerMessageQueue->addResponse(resp);
-}
-
-void playerLeftCallback(PEER peer, RoomType roomType, const char * nick, const char * reason, void * param)
-{
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_PLAYERLEFT;
- resp.nick = nick;
- resp.player.roomType = roomType;
- resp.player.profileID = 0;
-
- PeerThreadClass *t = (PeerThreadClass *)param;
- DEBUG_ASSERTCRASH(t, ("No Peer thread!"));
- if (!t)
- return;
-
- getPlayerInfo(t, peer, nick, resp.player.profileID, resp.player.IP,
- resp.locale, resp.player.wins, resp.player.losses,
- resp.player.rankPoints, resp.player.side, resp.player.preorder,
- roomType, resp.player.flags);
- TheGameSpyPeerMessageQueue->addResponse(resp);
-
- if (t->getQMStatus() != QM_IDLE && t->getQMStatus() != QM_STOPPED)
- {
- if (!stricmp(t->getQMBotName().c_str(), nick))
- {
- // matchbot left - bail
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_QUICKMATCHSTATUS;
- resp.qmStatus.status = QM_COULDNOTFINDBOT;
- TheGameSpyPeerMessageQueue->addResponse(resp);
-
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_STOPQUICKMATCH;
- TheGameSpyPeerMessageQueue->addRequest(req);
- }
- }
-}
-
-void playerChangedNickCallback(PEER peer, RoomType roomType, const char * oldNick, const char * newNick, void * param)
-{
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_PLAYERCHANGEDNICK;
- resp.nick = newNick;
- resp.oldNick = oldNick;
- resp.player.roomType = roomType;
-
- PeerThreadClass *t = (PeerThreadClass *)param;
- DEBUG_ASSERTCRASH(t, ("No Peer thread!"));
- if (!t)
- return;
-
- getPlayerInfo(t, peer, newNick, resp.player.profileID, resp.player.IP,
- resp.locale, resp.player.wins, resp.player.losses,
- resp.player.rankPoints, resp.player.side, resp.player.preorder,
- roomType, resp.player.flags);
- TheGameSpyPeerMessageQueue->addResponse(resp);
-}
-
-static void playerInfoCallback(PEER peer, RoomType roomType, const char * nick, unsigned int IP, int profileID, void * param)
-{
- if (!nick)
- return;
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_PLAYERINFO;
- resp.nick = nick;
- resp.player.roomType = roomType;
-
- PeerThreadClass *t = (PeerThreadClass *)param;
- DEBUG_ASSERTCRASH(t, ("No Peer thread!"));
- if (!t)
- return;
-
- getPlayerInfo(t, peer, nick, resp.player.profileID, resp.player.IP,
- resp.locale, resp.player.wins, resp.player.losses,
- resp.player.rankPoints, resp.player.side, resp.player.preorder,
- roomType, resp.player.flags);
- TheGameSpyPeerMessageQueue->addResponse(resp);
-}
-
-static void playerFlagsChangedCallback(PEER peer, RoomType roomType, const char * nick, int oldFlags, int newFlags, void * param)
-{
- if (!nick)
- return;
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_PLAYERCHANGEDFLAGS;
- resp.nick = nick;
- resp.player.roomType = roomType;
-
- PeerThreadClass *t = (PeerThreadClass *)param;
- DEBUG_ASSERTCRASH(t, ("No Peer thread!"));
- if (!t)
- return;
-
- getPlayerInfo(t, peer, nick, resp.player.profileID, resp.player.IP,
- resp.locale, resp.player.wins, resp.player.losses,
- resp.player.rankPoints, resp.player.side, resp.player.preorder,
- roomType, resp.player.flags);
- TheGameSpyPeerMessageQueue->addResponse(resp);
-}
-
-#ifdef DEBUG_LOGGING
-/*
-static void enumFunc(char *key, char *val, void *param)
-{
- DEBUG_LOG((" [%s] = [%s]\n", key, val));
-}
-*/
-#endif
-
-static void listingGamesCallback(PEER peer, PEERBool success, const char * name, SBServer server, PEERBool staging, int msg, Int percentListed, void * param)
-{
-#ifdef DEBUG_LOGGING
- AsciiString cmdStr = "";
- switch(msg)
- {
- case PEER_ADD:
- cmdStr = "PEER_ADD";
- break;
- case PEER_UPDATE:
- cmdStr = "PEER_UPDATE";
- break;
- case PEER_REMOVE:
- cmdStr = "PEER_REMOVE";
- break;
- case PEER_CLEAR:
- cmdStr = "PEER_CLEAR";
- break;
- case PEER_COMPLETE:
- cmdStr = "PEER_COMPLETE";
- break;
- }
- DEBUG_LOG(("listingGamesCallback() - doing command %s on server %X\n", cmdStr.str(), server));
-#endif // DEBUG_LOGGING
-
- PeerThreadClass *t = (PeerThreadClass *)param;
- DEBUG_ASSERTCRASH(name, ("Game has no name!\n"));
- if (!t || !success || (!name && (msg == PEER_ADD || msg == PEER_UPDATE)))
- {
- DEBUG_LOG(("Bailing from listingGamesCallback() - success=%d, name=%X, server=%X, msg=%X\n", success, name, server, msg));
- return;
- }
- if (!name)
- name = "bogus";
-
- if (server && (msg == PEER_ADD || msg == PEER_UPDATE))
- {
- DEBUG_ASSERTCRASH(server->keyvals, ("Looking at an already-freed server for msg type %d!", msg));
- if (!server->keyvals)
- {
- msg = PEER_REMOVE;
- }
- }
-
- if (server && success && (msg == PEER_ADD || msg == PEER_UPDATE))
- {
- DEBUG_LOG(("Game name is '%s'\n", name));
- const char *newname = SBServerGetStringValue(server, "gamename", (char *)name);
- if (strcmp(newname, "ccgenerals"))
- name = newname;
- DEBUG_LOG(("Game name is now '%s'\n", name));
- }
-
- DEBUG_LOG(("listingGamesCallback - got percent complete %d\n", percentListed));
- if (percentListed == 100)
- {
- if (!t->getSawCompleteGameList())
- {
- t->setSawCompleteGameList(TRUE);
- PeerResponse completeResp;
- completeResp.peerResponseType = PeerResponse::PEERRESPONSE_STAGINGROOMLISTCOMPLETE;
- TheGameSpyPeerMessageQueue->addResponse(completeResp);
- }
- }
-
- AsciiString gameName = name;
- AsciiString tmp = gameName;
- AsciiString hostName;
- tmp.nextToken(&hostName, " ");
- const char *firstSpace = gameName.find(' ');
- if(firstSpace)
- {
- gameName.set(firstSpace + 1);
- //gameName.trim();
- DEBUG_LOG(("Hostname/Gamename split leaves '%s' hosting '%s'\n", hostName.str(), gameName.str()));
- }
- PeerResponse resp;
- resp.peerResponseType = PeerResponse::PEERRESPONSE_STAGINGROOM;
- resp.stagingRoom.action = msg;
- resp.stagingRoom.isStaging = staging;
- resp.stagingRoom.percentComplete = percentListed;
-
- if (server && (msg == PEER_ADD || msg == PEER_UPDATE))
- {
- Bool hasPassword = (Bool)SBServerGetIntValue(server, PW_STR, FALSE);
- Bool allowObservers = (Bool)SBServerGetIntValue(server, OBS_STR, FALSE);
- const char *verStr = SBServerGetStringValue(server, "gamever", "000000");
- const char *exeStr = SBServerGetStringValue(server, EXECRC_STR, "000000");
- const char *iniStr = SBServerGetStringValue(server, INICRC_STR, "000000");
- const char *ladIPStr = SBServerGetStringValue(server, LADIP_STR, "000000");
- const char *pingStr = SBServerGetStringValue(server, PINGSTR_STR, "FFFFFFFFFFFFFFFF");
- UnsignedShort ladPort = (UnsignedShort)SBServerGetIntValue(server, LADPORT_STR, 0);
- UnsignedInt verVal = strtoul(verStr, NULL, 10);
- UnsignedInt exeVal = strtoul(exeStr, NULL, 10);
- UnsignedInt iniVal = strtoul(iniStr, NULL, 10);
- resp.stagingRoom.requiresPassword = hasPassword;
- resp.stagingRoom.allowObservers = allowObservers;
- resp.stagingRoom.version = verVal;
- resp.stagingRoom.exeCRC = exeVal;
- resp.stagingRoom.iniCRC = iniVal;
- resp.stagingServerLadderIP = ladIPStr;
- resp.stagingServerPingString = pingStr;
- resp.stagingRoom.ladderPort = ladPort;
- resp.stagingRoom.numPlayers = SBServerGetIntValue(server, NUMPLAYER_STR, 0);
- resp.stagingRoom.numObservers = SBServerGetIntValue(server, NUMOBS_STR, 0);
- resp.stagingRoom.maxPlayers = SBServerGetIntValue(server, MAXPLAYER_STR, 8);
- resp.stagingRoomMapName = SBServerGetStringValue(server, "mapname", "");
- for (Int i=0; ifindServer( server );
- DEBUG_LOG(("Add/update a 0/0 server %X (%d, %s) - requesting full update to see if that helps.\n",
- server, resp.stagingRoom.id, gameName.str()));
- TheGameSpyPeerMessageQueue->addRequest(req);
- }
- return; // don't actually try to list it.
- }
- }
-
- switch (msg)
- {
- case PEER_CLEAR:
- t->clearServers();
- break;
- case PEER_ADD:
- case PEER_UPDATE:
- resp.stagingRoom.id = t->findServer( server );
- DEBUG_LOG(("Add/update on server %X (%d, %s)\n", server, resp.stagingRoom.id, gameName.str()));
- resp.stagingServerName = MultiByteToWideCharSingleLine( gameName.str() );
- DEBUG_LOG(("Server had basic=%d, full=%d\n", SBServerHasBasicKeys(server), SBServerHasFullKeys(server)));
-#ifdef DEBUG_LOGGING
- //SBServerEnumKeys(server, enumFunc, NULL);
-#endif
- break;
- case PEER_REMOVE:
- DEBUG_LOG(("Removing server %X (%d)\n", server, resp.stagingRoom.id));
- resp.stagingRoom.id = t->removeServerFromMap( server );
- break;
- }
-
- TheGameSpyPeerMessageQueue->addResponse(resp);
-}
-
-//-------------------------------------------------------------------------
-
diff --git a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/PersistentStorageThread.cpp b/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/PersistentStorageThread.cpp
deleted file mode 100644
index 9a5df716b06..00000000000
--- a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/PersistentStorageThread.cpp
+++ /dev/null
@@ -1,1513 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: PersistentStorageThread.cpp //////////////////////////////////////////////////////
-// GameSpy Persistent Storage thread
-// This thread communicates with GameSpy's persistent storage server
-// and talks through a message queue with the rest of
-// the game.
-// Author: Matthew D. Campbell, July 2002
-
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/UserPreferences.h"
-#include "Common/PlayerTemplate.h"
-#include "GameNetwork/GameSpy/PersistentStorageThread.h"
-
-#include "mutex.h"
-#include "thread.h"
-
-#include "Common/StackDump.h"
-#include "Common/SubsystemInterface.h"
-
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-
-//-------------------------------------------------------------------------
-
-PSRequest::PSRequest()
-{
- player.reset();
- requestType = PSREQUEST_READPLAYERSTATS;
- addDiscon = addDesync = FALSE;
- lastHouse = -1;
-}
-
-//-------------------------------------------------------------------------
-
-#define DEBUG_MAP(x) for (it = stats.x.begin(); it != stats.x.end(); ++it) \
-{ \
- if (it->second > 0) \
- { \
- DEBUG_LOG(("%s(%d): %d\n", #x, it->first, it->second)); \
- } \
-}
-
-static void debugDumpPlayerStats( const PSPlayerStats& stats )
-{
- DEBUG_LOG(("-----------------------------------------\n"));
- DEBUG_LOG(("Tracking player stats for player %d:\n", stats.id));
- PerGeneralMap::const_iterator it;
- DEBUG_MAP(wins);
- DEBUG_MAP(losses);
- DEBUG_MAP(games);
- DEBUG_MAP(duration);
- DEBUG_MAP(unitsKilled);
- DEBUG_MAP(unitsLost);
- DEBUG_MAP(unitsBuilt);
- DEBUG_MAP(buildingsKilled);
- DEBUG_MAP(buildingsLost);
- DEBUG_MAP(buildingsBuilt);
- DEBUG_MAP(earnings);
- DEBUG_MAP(techCaptured);
- DEBUG_MAP(discons);
- DEBUG_MAP(desyncs);
- DEBUG_MAP(surrenders);
- DEBUG_MAP(gamesOf2p);
- DEBUG_MAP(gamesOf3p);
- DEBUG_MAP(gamesOf4p);
- DEBUG_MAP(gamesOf5p);
- DEBUG_MAP(gamesOf6p);
- DEBUG_MAP(gamesOf7p);
- DEBUG_MAP(gamesOf8p);
- DEBUG_MAP(customGames);
- DEBUG_MAP(QMGames);
-
- if (stats.locale > 0)
- {
- DEBUG_LOG(("Locale: %d\n", stats.locale));
- }
-
- if (stats.gamesAsRandom > 0)
- {
- DEBUG_LOG(("gamesAsRandom: %d\n", stats.gamesAsRandom));
- }
-
- if (stats.options.length())
- {
- DEBUG_LOG(("Options: %s\n", stats.options.c_str()));
- }
-
- if (stats.systemSpec.length())
- {
- DEBUG_LOG(("systemSpec: %s\n", stats.systemSpec.c_str()));
- }
-
- if (stats.lastFPS > 0.0f)
- {
- DEBUG_LOG(("lastFPS: %g\n", stats.lastFPS));
- }
-
- if (stats.battleHonors > 0)
- {
- DEBUG_LOG(("battleHonors: %x\n", stats.battleHonors));
- }
- if (stats.challengeMedals > 0)
- {
- DEBUG_LOG(("challengeMedals: %x\n", stats.challengeMedals));
- }
- if (stats.lastGeneral >= 0)
- {
- DEBUG_LOG(("lastGeneral: %d\n", stats.lastGeneral));
- }
- if (stats.gamesInRowWithLastGeneral >= 0)
- {
- DEBUG_LOG(("gamesInRowWithLastGeneral: %d\n", stats.gamesInRowWithLastGeneral));
- }
- if (stats.builtSCUD >= 0)
- {
- DEBUG_LOG(("builtSCUD: %d\n", stats.builtSCUD));
- }
- if (stats.builtNuke >= 0)
- {
- DEBUG_LOG(("builtNuke: %d\n", stats.builtNuke));
- }
- if (stats.builtParticleCannon >= 0)
- {
- DEBUG_LOG(("builtParticleCannon: %d\n", stats.builtParticleCannon));
- }
-
- if (stats.winsInARow >= 0)
- {
- DEBUG_LOG(("winsInARow: %d\n", stats.winsInARow));
- }
- if (stats.maxWinsInARow >= 0)
- {
- DEBUG_LOG(("maxWinsInARow: %d\n", stats.maxWinsInARow));
- }
- if (stats.disconsInARow >= 0)
- {
- DEBUG_LOG(("disconsInARow: %d\n", stats.disconsInARow));
- }
- if (stats.maxDisconsInARow >= 0)
- {
- DEBUG_LOG(("maxDisconsInARow: %d\n", stats.maxDisconsInARow));
- }
- if (stats.lossesInARow >= 0)
- {
- DEBUG_LOG(("lossesInARow: %d\n", stats.lossesInARow));
- }
- if (stats.maxLossesInARow >= 0)
- {
- DEBUG_LOG(("maxLossesInARow: %d\n", stats.maxLossesInARow));
- }
- if (stats.desyncsInARow >= 0)
- {
- DEBUG_LOG(("desyncsInARow: %d\n", stats.desyncsInARow));
- }
- if (stats.maxDesyncsInARow >= 0)
- {
- DEBUG_LOG(("maxDesyncsInARow: %d\n", stats.maxDesyncsInARow));
- }
-
- if (stats.lastLadderPort >= 0)
- {
- DEBUG_LOG(("lastLadderPort: %d\n", stats.lastLadderPort));
- }
-
- if (stats.lastLadderHost.length())
- {
- DEBUG_LOG(("lastLadderHost: %s\n", stats.lastLadderHost.c_str()));
- }
-
-
-
-}
-
-//-------------------------------------------------------------------------
-
-#define INCORPORATE_MAP(x) for (it = other.x.begin(); it != other.x.end(); ++it) \
-{ \
- if (it->second > 0) \
- { \
- x[it->first] = it->second; \
- } \
-}
-
-void PSPlayerStats::incorporate( const PSPlayerStats& other )
-{
- PerGeneralMap::const_iterator it;
- INCORPORATE_MAP(wins);
- INCORPORATE_MAP(losses);
- INCORPORATE_MAP(games);
- INCORPORATE_MAP(duration);
- INCORPORATE_MAP(unitsKilled);
- INCORPORATE_MAP(unitsLost);
- INCORPORATE_MAP(unitsBuilt);
- INCORPORATE_MAP(buildingsKilled);
- INCORPORATE_MAP(buildingsLost);
- INCORPORATE_MAP(buildingsBuilt);
- INCORPORATE_MAP(earnings);
- INCORPORATE_MAP(techCaptured);
-
- //GS Clear all disconnects so that we don't retain any that were
- //previously reported as 1 by updateAdditionalGameSpyDisconnections
- discons.clear();
- INCORPORATE_MAP(discons);
-
- INCORPORATE_MAP(desyncs);
- INCORPORATE_MAP(surrenders);
- INCORPORATE_MAP(gamesOf2p);
- INCORPORATE_MAP(gamesOf3p);
- INCORPORATE_MAP(gamesOf4p);
- INCORPORATE_MAP(gamesOf5p);
- INCORPORATE_MAP(gamesOf6p);
- INCORPORATE_MAP(gamesOf7p);
- INCORPORATE_MAP(gamesOf8p);
- INCORPORATE_MAP(customGames);
- INCORPORATE_MAP(QMGames);
-
- if (other.locale > 0)
- {
- locale = other.locale;
- }
-
- if (other.gamesAsRandom > 0)
- {
- gamesAsRandom = other.gamesAsRandom;
- }
-
- if (other.options.length())
- {
- options = other.options;
- }
-
- if (other.systemSpec.length())
- {
- systemSpec = other.systemSpec;
- }
-
- if (other.lastFPS > 0.0f)
- {
- lastFPS = other.lastFPS;
- }
-
- if (other.battleHonors > 0)
- {
- battleHonors |= other.battleHonors;
- }
- if (other.challengeMedals > 0)
- {
- challengeMedals |= other.challengeMedals;
- }
- if (other.lastGeneral >= 0)
- {
- lastGeneral = other.lastGeneral;
- }
- if (other.gamesInRowWithLastGeneral >= 0)
- {
- gamesInRowWithLastGeneral = other.gamesInRowWithLastGeneral;
- }
- if (other.builtParticleCannon >= 0)
- {
- builtParticleCannon = other.builtParticleCannon;
- }
- if (other.builtNuke >= 0)
- {
- builtNuke = other.builtNuke;
- }
- if (other.builtSCUD >= 0)
- {
- builtSCUD = other.builtSCUD;
- }
- if (other.winsInARow >= 0)
- {
- winsInARow = other.winsInARow;
- }
- if (other.maxWinsInARow >= 0)
- {
- maxWinsInARow = other.maxWinsInARow;
- }
- if (other.lossesInARow >= 0)
- {
- lossesInARow = other.lossesInARow;
- }
- if (other.maxLossesInARow >= 0)
- {
- maxLossesInARow = other.maxLossesInARow;
- }
- if (other.disconsInARow >= 0)
- {
- disconsInARow = other.disconsInARow;
- }
- if (other.maxDisconsInARow >= 0)
- {
- maxDisconsInARow = other.maxDisconsInARow;
- }
- if (other.desyncsInARow >= 0)
- {
- desyncsInARow = other.desyncsInARow;
- }
- if (other.maxDesyncsInARow >= 0)
- {
- maxDesyncsInARow = other.maxDesyncsInARow;
- }
- if (other.lastLadderPort >= 0)
- {
- lastLadderPort = other.lastLadderPort;
- }
- if (other.lastLadderHost.length())
- {
- lastLadderHost = other.lastLadderHost;
- }
-}
-
-PSPlayerStats::PSPlayerStats( const PSPlayerStats& other )
-{
- incorporate(other);
- id = other.id;
- locale = other.locale;
- gamesAsRandom = other.gamesAsRandom;
- options = other.options;
- systemSpec = other.systemSpec;
- lastFPS = other.lastFPS;
- lastGeneral = other.lastGeneral;
- gamesInRowWithLastGeneral = other.gamesInRowWithLastGeneral;
- builtParticleCannon = other.builtParticleCannon;
- builtNuke = other.builtNuke;
- builtSCUD = other.builtSCUD;
- challengeMedals = other.challengeMedals;
- battleHonors = other.battleHonors;
- winsInARow = other.winsInARow;
- maxWinsInARow = other.maxWinsInARow;
- lossesInARow = other.lossesInARow;
- maxLossesInARow = other.maxLossesInARow;
- disconsInARow = other.disconsInARow;
- maxDisconsInARow = other.maxDisconsInARow;
- desyncsInARow = other.desyncsInARow;
- maxDesyncsInARow = other.maxDesyncsInARow;
- lastLadderHost = other.lastLadderHost;
- lastLadderPort = other.lastLadderPort;
-}
-
-//-------------------------------------------------------------------------
-
-typedef std::queue RequestQueue;
-typedef std::queue ResponseQueue;
-class PSThreadClass;
-
-class GameSpyPSMessageQueue : public GameSpyPSMessageQueueInterface
-{
-public:
- virtual ~GameSpyPSMessageQueue();
- GameSpyPSMessageQueue();
- virtual void startThread( void );
- virtual void endThread( void );
- virtual Bool isThreadRunning( void );
-
- virtual void addRequest( const PSRequest& req );
- virtual Bool getRequest( PSRequest& req );
-
- virtual void addResponse( const PSResponse& resp );
- virtual Bool getResponse( PSResponse& resp );
-
- virtual void trackPlayerStats( PSPlayerStats stats );
- virtual PSPlayerStats findPlayerStatsByID( Int id );
-
- PSThreadClass* getThread( void );
-
- Int getLocalPlayerID(void) { return m_localPlayerID; }
- void setLocalPlayerID(Int localPlayerID) { m_localPlayerID = localPlayerID; }
-
- std::string getEmail() { return m_email; }
- std::string getNick() { return m_nick; }
- std::string getPassword() { return m_password; }
-
- void setEmail(std::string email) { m_email = email; }
- void setNick(std::string nick) { m_nick = nick; }
- void setPassword(std::string password) { m_password = password; }
-
-private:
- MutexClass m_requestMutex;
- MutexClass m_responseMutex;
- RequestQueue m_requests;
- ResponseQueue m_responses;
- PSThreadClass *m_thread;
- Int m_localPlayerID;
-
- std::string m_email;
- std::string m_nick;
- std::string m_password;
-
- std::map m_playerStats;
-};
-
-GameSpyPSMessageQueueInterface* GameSpyPSMessageQueueInterface::createNewMessageQueue( void )
-{
- return NEW GameSpyPSMessageQueue;
-}
-
-GameSpyPSMessageQueueInterface *TheGameSpyPSMessageQueue = NULL;
-#define MESSAGE_QUEUE ((GameSpyPSMessageQueue *)TheGameSpyPSMessageQueue)
-
-//-------------------------------------------------------------------------
-
-class PSThreadClass : public ThreadClass
-{
-
-public:
- PSThreadClass() : ThreadClass()
- {
- m_loginOK = m_sawLocalData = m_doneTryingToLogin = false;
- m_opCount = 0;
- }
-
- void Thread_Function();
-
- void persAuthCallback( Bool val ) { m_loginOK = val; m_doneTryingToLogin = true; }
- void decrOpCount( void ) { --m_opCount; }
- void incrOpCount( void ) { ++m_opCount; }
- Int getOpCount( void ) { return m_opCount; }
- Bool sawLocalPlayerData( void ) { return m_sawLocalData; }
- void gotLocalPlayerData( void ) { m_sawLocalData = TRUE; }
-
-private:
- Bool tryConnect( void );
- Bool tryLogin( Int id, std::string nick, std::string password, std::string email );
- Bool m_loginOK;
- Bool m_doneTryingToLogin;
- Int m_opCount;
- Bool m_sawLocalData;
-};
-
-
-//-------------------------------------------------------------------------
-
-GameSpyPSMessageQueue::GameSpyPSMessageQueue()
-{
- m_thread = NULL;
- m_localPlayerID = 0;
-}
-
-GameSpyPSMessageQueue::~GameSpyPSMessageQueue()
-{
- endThread();
-}
-
-void GameSpyPSMessageQueue::startThread( void )
-{
- if (!m_thread)
- {
- m_thread = NEW PSThreadClass;
- m_thread->Execute();
- }
- else
- {
- if (!m_thread->Is_Running())
- {
- m_thread->Execute();
- }
- }
-}
-
-void GameSpyPSMessageQueue::endThread( void )
-{
- if (m_thread)
- delete m_thread;
- m_thread = NULL;
-}
-
-Bool GameSpyPSMessageQueue::isThreadRunning( void )
-{
- return (m_thread) ? m_thread->Is_Running() : false;
-}
-
-void GameSpyPSMessageQueue::addRequest( const PSRequest& req )
-{
- MutexClass::LockClass m(m_requestMutex);
- if (m.Failed())
- return;
-
- m_requests.push(req);
-}
-
-Bool GameSpyPSMessageQueue::getRequest( PSRequest& req )
-{
- MutexClass::LockClass m(m_requestMutex, 0);
- if (m.Failed())
- return false;
-
- if (m_requests.empty())
- return false;
- req = m_requests.front();
- m_requests.pop();
- return true;
-}
-
-void GameSpyPSMessageQueue::addResponse( const PSResponse& resp )
-{
- MutexClass::LockClass m(m_responseMutex);
- if (m.Failed())
- return;
-
- m_responses.push(resp);
-}
-
-Bool GameSpyPSMessageQueue::getResponse( PSResponse& resp )
-{
- MutexClass::LockClass m(m_responseMutex, 0);
- if (m.Failed())
- return false;
-
- if (m_responses.empty())
- return false;
- resp = m_responses.front();
- m_responses.pop();
- return true;
-}
-
-PSThreadClass* GameSpyPSMessageQueue::getThread( void )
-{
- return m_thread;
-}
-
-void GameSpyPSMessageQueue::trackPlayerStats( PSPlayerStats stats )
-{
-#ifdef DEBUG_LOGGING
- debugDumpPlayerStats( stats );
- DEBUG_ASSERTCRASH(stats.id != 0, ("Tracking stats with ID of 0\n"));
-#endif
- PSPlayerStats newStats;
- std::map::iterator it = m_playerStats.find(stats.id);
- if (it != m_playerStats.end())
- {
- newStats = it->second;
- newStats.incorporate(stats);
- m_playerStats[stats.id] = newStats;
- }
- else
- {
- m_playerStats[stats.id] = stats;
- }
-}
-
-PSPlayerStats GameSpyPSMessageQueue::findPlayerStatsByID( Int id )
-{
- std::map::iterator it = m_playerStats.find(id);
- if (it != m_playerStats.end())
- {
- return it->second;
- }
-
- PSPlayerStats empty;
- empty.id = 0;
- return empty;
-}
-
-//-------------------------------------------------------------------------
-
-Bool PSThreadClass::tryConnect( void )
-{
- Int result;
-
- DEBUG_LOG(("m_opCount = %d - opening connection\n", m_opCount));
-
- if (IsStatsConnected())
- {
- DEBUG_LOG(("connection already open!\n"));
- return true;
- }
-
- // this may block for 1-2 seconds (according to GS) so it's nice we're not in the UI thread :)
- result = InitStatsConnection(0);
-
-#ifdef DEBUG_LOGGING
- static const char *retValStrings[6] = {
- "GE_NOERROR",
- "GE_NOSOCKET",
- "GE_NODNS",
- "GE_NOCONNECT",
- "GE_BUSY",
- "GE_DATAERROR"
- };
-#endif // DEBUG_LOGGING
-
- if (result != GE_NOERROR)
- {
- DEBUG_LOG(("InitStatsConnection() returned %d (%s)\n", result, retValStrings[result]));
- return false;
- }
- else
- {
- DEBUG_LOG(("InitStatsConnection() succeeded\n"));
- }
-
- return true;
-}
-
-static void persAuthCallback(int localid, int profileid, int authenticated, char *errmsg, void *instance)
-{
- PSThreadClass *t = (PSThreadClass *)instance;
- DEBUG_LOG(("Auth callback: localid: %d profileid: %d auth: %d err: %s\n",localid, profileid, authenticated, errmsg));
- if (t)
- t->persAuthCallback(authenticated != 0);
-}
-
-Bool PSThreadClass::tryLogin( Int id, std::string nick, std::string password, std::string email )
-{
- char validate[33];
- DEBUG_LOG(("PSThreadClass::tryLogin id = %d, nick = %s, password = %s, email = %s\n", id, nick.c_str(), password.c_str(), email.c_str()));
- /***********
- We'll go ahead and start the authentication, using a Presence & Messaging SDK
- profileid / password. To generate the new validation token, we'll need to pass
- in the password for the profile we are authenticating.
- Again, if this is done in a client/server setting, with the Persistent Storage
- access being done on the server, and the P&M SDK is used on the client, the
- server will need to send the challenge (GetChallenge(NULL)) to the client, the
- client will create the validation token using GenerateAuth, and send it
- back to the server for use in PreAuthenticatePlayerPM
- ***********/
- char *munkeeHack = strdup(password.c_str()); // GenerateAuth takes a char*, not a const char* :P
- GenerateAuth(GetChallenge(NULL), munkeeHack, validate);
- free (munkeeHack);
-
- /************
- After we get the validation token, we pass it and the profileid of the user
- we are authenticating into PreAuthenticatePlayerPM.
- We pass the same authentication callback as for the first user, but a different
- localid this time.
- ************/
- m_loginOK = false;
- m_doneTryingToLogin = false;
- PreAuthenticatePlayerPM(id, id, validate, ::persAuthCallback, this);
- while (!m_doneTryingToLogin && IsStatsConnected())
- PersistThink();
- DEBUG_LOG(("Persistant Storage Login success %d\n", m_loginOK));
- return m_loginOK;
-}
-
-static void getPersistentDataCallback(int localid, int profileid, persisttype_t type, int index, int success, time_t modified, char *data, int len, void *instance)
-{
- DEBUG_LOG(("Data get callback: localid: %d profileid: %d success: %d len: %d data: %s\n",localid, profileid, success, len, data));
- PSThreadClass *t = (PSThreadClass *)instance;
- if (!t)
- return;
-
- t->decrOpCount();
-
- PSResponse resp;
-
- if (!success)
- {
- resp.responseType = PSResponse::PSRESPONSE_COULDNOTCONNECT;
- resp.player.id = profileid;
- TheGameSpyPSMessageQueue->addResponse(resp);
- if (!t->getOpCount() && !t->sawLocalPlayerData())
- {
- // we haven't gotten stats for ourselves - try again
- DEBUG_LOG(("Requesting retry for reading local player's stats\n"));
- PSRequest req;
- req.requestType = PSRequest::PSREQUEST_READPLAYERSTATS;
- req.player.id = MESSAGE_QUEUE->getLocalPlayerID();
- TheGameSpyPSMessageQueue->addRequest(req);
- }
- return;
- }
-
- if (profileid == MESSAGE_QUEUE->getLocalPlayerID())
- {
- t->gotLocalPlayerData();
- DEBUG_LOG(("getPersistentDataCallback() - got local player info\n"));
-
- // check if we have discons we should update on the server
- UserPreferences pref;
- AsciiString userPrefFilename;
- userPrefFilename.format("GeneralsOnline\\MiscPref%d.ini", MESSAGE_QUEUE->getLocalPlayerID());
- DEBUG_LOG(("using the file %s\n", userPrefFilename.str()));
- pref.load(userPrefFilename);
- Int addedInDesyncs2 = pref.getInt("0", 0);
- DEBUG_LOG(("addedInDesyncs2 = %d\n", addedInDesyncs2));
- if (addedInDesyncs2 < 0)
- addedInDesyncs2 = 10;
- Int addedInDesyncs3 = pref.getInt("1", 0);
- DEBUG_LOG(("addedInDesyncs3 = %d\n", addedInDesyncs3));
- if (addedInDesyncs3 < 0)
- addedInDesyncs3 = 10;
- Int addedInDesyncs4 = pref.getInt("2", 0);
- DEBUG_LOG(("addedInDesyncs4 = %d\n", addedInDesyncs4));
- if (addedInDesyncs4 < 0)
- addedInDesyncs4 = 10;
- Int addedInDiscons2 = pref.getInt("3", 0);
- DEBUG_LOG(("addedInDiscons2 = %d\n", addedInDiscons2));
- if (addedInDiscons2 < 0)
- addedInDiscons2 = 10;
- Int addedInDiscons3 = pref.getInt("4", 0);
- DEBUG_LOG(("addedInDiscons3 = %d\n", addedInDiscons3));
- if (addedInDiscons3 < 0)
- addedInDiscons3 = 10;
- Int addedInDiscons4 = pref.getInt("5", 0);
- DEBUG_LOG(("addedInDiscons4 = %d\n", addedInDiscons4));
- if (addedInDiscons4 < 0)
- addedInDiscons4 = 10;
-
- DEBUG_LOG(("addedInDesync=%d,%d,%d, addedInDiscon=%d,%d,%d\n",
- addedInDesyncs2, addedInDesyncs3, addedInDesyncs4,
- addedInDiscons2, addedInDiscons3, addedInDiscons4));
-
- if (addedInDesyncs2 || addedInDesyncs3 || addedInDesyncs4 || addedInDiscons2 || addedInDiscons3 || addedInDiscons4)
- {
- DEBUG_LOG(("We have a previous discon we can attempt to update! Bummer...\n"));
-
- PSRequest req;
- req.requestType = PSRequest::PSREQUEST_UPDATEPLAYERSTATS;
- req.email = MESSAGE_QUEUE->getEmail();
- req.nick = MESSAGE_QUEUE->getNick();
- req.password = MESSAGE_QUEUE->getPassword();
- req.player = GameSpyPSMessageQueueInterface::parsePlayerKVPairs((len)?data:"");
- req.player.id = profileid;
- req.addDesync = FALSE;
- req.addDiscon = FALSE;
- req.lastHouse = 0;
- TheGameSpyPSMessageQueue->addRequest(req);
- }
- }
-
- resp.responseType = PSResponse::PSRESPONSE_PLAYERSTATS;
- resp.player = GameSpyPSMessageQueueInterface::parsePlayerKVPairs((len)?data:"");
- resp.player.id = profileid;
-
- TheGameSpyPSMessageQueue->addResponse(resp);
-}
-
-static void setPersistentDataLocaleCallback(int localid, int profileid, persisttype_t type, int index, int success, time_t modified, void *instance)
-{
- DEBUG_LOG(("Data save callback: localid: %d profileid: %d success: %d\n", localid, profileid, success));
-
- PSThreadClass *t = (PSThreadClass *)instance;
- if (!t)
- return;
-
- t->decrOpCount();
-}
-
-static void setPersistentDataCallback(int localid, int profileid, persisttype_t type, int index, int success, time_t modified, void *instance)
-{
- DEBUG_LOG(("Data save callback: localid: %d profileid: %d success: %d\n", localid, profileid, success));
-
- PSThreadClass *t = (PSThreadClass *)instance;
- if (!t)
- return;
-
- if (success)
- {
- UserPreferences pref;
- AsciiString userPrefFilename;
- userPrefFilename.format("GeneralsOnline\\MiscPref%d.ini", profileid);
- DEBUG_LOG(("setPersistentDataCallback - writing stats to file %s\n", userPrefFilename.str()));
- pref.load(userPrefFilename);
- pref.clear();
- pref.write();
- }
- t->decrOpCount();
-}
-
-struct CDAuthInfo
-{
- Bool success;
- Bool done;
- Int id;
-};
-
-void preAuthCDCallback(int localid, int profileid, int authenticated, char *errmsg, void *instance)
-{
- DEBUG_LOG(("preAuthCDCallback(): profileid: %d auth: %d err: %s\n", profileid, authenticated, errmsg));
-
- CDAuthInfo *authInfo = (CDAuthInfo *)instance;
- authInfo->success = authenticated;
- authInfo->done = TRUE;
- authInfo->id = profileid;
-}
-
-static void getPreorderCallback(int localid, int profileid, persisttype_t type, int index, int success, time_t modified, char *data, int len, void *instance)
-{
- PSThreadClass *t = (PSThreadClass *)instance;
- if (!t)
- return;
-
- t->decrOpCount();
-
- PSResponse resp;
-
- if (!success)
- {
- DEBUG_LOG(("Failed getPreorderCallback()\n"));
- return;
- }
-
- resp.responseType = PSResponse::PSRESPONSE_PREORDER;
- resp.preorder = (data && strcmp(data, "\\preorder\\1") == 0);
- DEBUG_LOG(("getPreorderCallback() - data was '%s'\n", data));
-
- TheGameSpyPSMessageQueue->addResponse(resp);
-}
-
-void PSThreadClass::Thread_Function()
-{
- try {
- _set_se_translator( DumpExceptionInfo ); // Hook that allows stack trace.
- /*********
- First step, set our game authentication info
- We could do:
- strcpy(gcd_gamename,"ccgenerals");
- strcpy(gcd_secret_key,"h5T2f6");
- or
- strcpy(gcd_gamename,"ccgeneralsb");
- strcpy(gcd_secret_key,"g3T9s2");
- ...but this is more secure:
- **********/
- /**
- gcd_gamename[0]='c';gcd_gamename[1]='c';gcd_gamename[2]='g';gcd_gamename[3]='e';
- gcd_gamename[4]='n';gcd_gamename[5]='e';gcd_gamename[6]='r';gcd_gamename[7]='a';
- gcd_gamename[8]='l';gcd_gamename[9]='s';gcd_gamename[10]='b';gcd_gamename[11]='\0';
- gcd_secret_key[0]='g';gcd_secret_key[1]='3';gcd_secret_key[2]='T';gcd_secret_key[3]='9';
- gcd_secret_key[4]='s';gcd_secret_key[5]='2';gcd_secret_key[6]='\0';
- /**/
- gcd_gamename[0]='c';gcd_gamename[1]='c';gcd_gamename[2]='g';gcd_gamename[3]='e';
- gcd_gamename[4]='n';gcd_gamename[5]='e';gcd_gamename[6]='r';gcd_gamename[7]='a';
- gcd_gamename[8]='l';gcd_gamename[9]='s';gcd_gamename[10]='\0';
- gcd_secret_key[0]='h';gcd_secret_key[1]='5';gcd_secret_key[2]='T';gcd_secret_key[3]='2';
- gcd_secret_key[4]='f';gcd_secret_key[5]='6';gcd_secret_key[6]='\0';
- /**/
-
- //strcpy(StatsServerHostname, "sdkdev.gamespy.com");
-
- PSRequest req;
- while ( running )
- {
- // deal with requests
- if (TheGameSpyPSMessageQueue->getRequest(req))
- {
- switch (req.requestType)
- {
- case PSRequest::PSREQUEST_SENDGAMERESTOGAMESPY:
- {
- if (tryConnect())
- {
- NewGame(0);
-#ifdef DEBUG_LOGGING
- Int res =
-#endif // DEBUG_LOGGING
- SendGameSnapShot(NULL, req.results.c_str(), SNAP_FINAL);
- DEBUG_LOG(("Just sent game results - res was %d\n", res));
- FreeGame(NULL);
- }
- }
- break;
- case PSRequest::PSREQUEST_READPLAYERSTATS:
- {
- Bool initialConnection = FALSE;
- if (!MESSAGE_QUEUE->getLocalPlayerID())
- {
- MESSAGE_QUEUE->setLocalPlayerID(req.player.id); // first request is for ourselves
- MESSAGE_QUEUE->setEmail(req.email);
- MESSAGE_QUEUE->setNick(req.nick);
- MESSAGE_QUEUE->setPassword(req.password);
- DEBUG_LOG(("Setting email/nick/password = %s/%s/%s\n", req.email.c_str(), req.nick.c_str(), req.password.c_str()));
- initialConnection = TRUE;
- }
- DEBUG_LOG(("Processing PSRequest::PSREQUEST_READPLAYERSTATS\n"));
- if (tryConnect())
- {
- DEBUG_LOG(("Successful login\n"));
- incrOpCount();
- GetPersistDataValues(0, req.player.id, pd_public_rw, 0, "", getPersistentDataCallback, this);
- }
- else
- {
- DEBUG_LOG(("Unsuccessful login - retry=%d\n", initialConnection));
- PSResponse resp;
- resp.responseType = PSResponse::PSRESPONSE_COULDNOTCONNECT;
- resp.player.id = req.player.id;
- TheGameSpyPSMessageQueue->addResponse(resp);
- if (initialConnection)
- {
- // we haven't gotten stats for ourselves - try again
- DEBUG_LOG(("Requesting retry for reading local player's stats\n"));
- PSRequest req;
- req.requestType = PSRequest::PSREQUEST_READPLAYERSTATS;
- req.player.id = MESSAGE_QUEUE->getLocalPlayerID();
- TheGameSpyPSMessageQueue->addRequest(req);
- }
- }
- }
- break;
- case PSRequest::PSREQUEST_UPDATEPLAYERLOCALE:
- {
- DEBUG_LOG(("Processing PSRequest::PSREQUEST_UPDATEPLAYERLOCALE\n"));
- if (tryConnect() && tryLogin(req.player.id, req.nick, req.password, req.email))
- {
- char kvbuf[256];
- sprintf(kvbuf, "\\locale\\%d", req.player.locale);
- incrOpCount();
- SetPersistDataValues(0, req.player.id, pd_public_rw, 0, kvbuf, setPersistentDataLocaleCallback, this);
- }
- }
- break;
- case PSRequest::PSREQUEST_UPDATEPLAYERSTATS:
- {
- /*
- ** NOTE THAT THIS IS HIGHLY DEPENDENT ON INI ORDERING FOR THE PLAYERTEMPLATES!!!
- */
- DEBUG_LOG(("Processing PSRequest::PSREQUEST_UPDATEPLAYERSTATS\n"));
- UserPreferences pref;
- AsciiString userPrefFilename;
- userPrefFilename.format("GeneralsOnline\\MiscPref%d.ini", MESSAGE_QUEUE->getLocalPlayerID());
- DEBUG_LOG(("using the file %s\n", userPrefFilename.str()));
- pref.load(userPrefFilename);
- Int addedInDesyncs2 = pref.getInt("0", 0);
- DEBUG_LOG(("addedInDesyncs2 = %d\n", addedInDesyncs2));
- if (addedInDesyncs2 < 0)
- addedInDesyncs2 = 10;
- Int addedInDesyncs3 = pref.getInt("1", 0);
- DEBUG_LOG(("addedInDesyncs3 = %d\n", addedInDesyncs3));
- if (addedInDesyncs3 < 0)
- addedInDesyncs3 = 10;
- Int addedInDesyncs4 = pref.getInt("2", 0);
- DEBUG_LOG(("addedInDesyncs4 = %d\n", addedInDesyncs4));
- if (addedInDesyncs4 < 0)
- addedInDesyncs4 = 10;
- Int addedInDiscons2 = pref.getInt("3", 0);
- DEBUG_LOG(("addedInDiscons2 = %d\n", addedInDiscons2));
- if (addedInDiscons2 < 0)
- addedInDiscons2 = 10;
- Int addedInDiscons3 = pref.getInt("4", 0);
- DEBUG_LOG(("addedInDiscons3 = %d\n", addedInDiscons3));
- if (addedInDiscons3 < 0)
- addedInDiscons3 = 10;
- Int addedInDiscons4 = pref.getInt("5", 0);
- DEBUG_LOG(("addedInDiscons4 = %d\n", addedInDiscons4));
- if (addedInDiscons4 < 0)
- addedInDiscons4 = 10;
-
- DEBUG_LOG(("req.addDesync=%d, req.addDiscon=%d, addedInDesync=%d,%d,%d, addedInDiscon=%d,%d,%d\n",
- req.addDesync, req.addDiscon, addedInDesyncs2, addedInDesyncs3, addedInDesyncs4,
- addedInDiscons2, addedInDiscons3, addedInDiscons4));
-
- if (req.addDesync || req.addDiscon)
- {
- AsciiString val;
- if (req.lastHouse == 2)
- {
- val.format("%d", addedInDesyncs2 + req.addDesync);
- pref["0"] = val;
- val.format("%d", addedInDiscons2 + req.addDiscon);
- pref["3"] = val;
- DEBUG_LOG(("house 2 req.addDesync || req.addDiscon: %d %d\n",
- addedInDesyncs2 + req.addDesync, addedInDiscons2 + req.addDiscon));
- }
- else if (req.lastHouse == 3)
- {
- val.format("%d", addedInDesyncs3 + req.addDesync);
- pref["1"] = val;
- val.format("%d", addedInDiscons3 + req.addDiscon);
- pref["4"] = val;
- DEBUG_LOG(("house 3 req.addDesync || req.addDiscon: %d %d\n",
- addedInDesyncs3 + req.addDesync, addedInDiscons3 + req.addDiscon));
- }
- else
- {
- val.format("%d", addedInDesyncs4 + req.addDesync);
- pref["2"] = val;
- val.format("%d", addedInDiscons4 + req.addDiscon);
- pref["5"] = val;
- DEBUG_LOG(("house 4 req.addDesync || req.addDiscon: %d %d\n",
- addedInDesyncs4 + req.addDesync, addedInDiscons4 + req.addDiscon));
- }
- pref.write();
- if (req.password.size() == 0)
- return;
- }
- if (!req.player.id)
- {
- DEBUG_LOG(("Bailing because ID is NULL!\n"));
- return;
- }
- req.player.desyncs[2] += addedInDesyncs2;
- req.player.games[2] += addedInDesyncs2;
- req.player.discons[2] += addedInDiscons2;
- req.player.games[2] += addedInDiscons2;
- req.player.desyncs[3] += addedInDesyncs3;
- req.player.games[3] += addedInDesyncs3;
- req.player.discons[3] += addedInDiscons3;
- req.player.games[3] += addedInDiscons3;
- req.player.desyncs[4] += addedInDesyncs4;
- req.player.games[4] += addedInDesyncs4;
- req.player.discons[4] += addedInDiscons4;
- req.player.games[4] += addedInDiscons4;
- DEBUG_LOG(("House2: %d/%d/%d, House3: %d/%d/%d, House4: %d/%d/%d\n",
- req.player.desyncs[2], req.player.discons[2], req.player.games[2],
- req.player.desyncs[3], req.player.discons[3], req.player.games[3],
- req.player.desyncs[4], req.player.discons[4], req.player.games[4]
- ));
- if (tryConnect() && tryLogin(req.player.id, req.nick, req.password, req.email))
- {
- DEBUG_LOG(("Logged in!\n"));
- if (TheGameSpyPSMessageQueue)
- TheGameSpyPSMessageQueue->trackPlayerStats(req.player);
-
- char *munkeeHack = strdup(GameSpyPSMessageQueueInterface::formatPlayerKVPairs(req.player).c_str()); // GS takes a char* for some reason
- incrOpCount();
- DEBUG_LOG(("Setting values %s\n", munkeeHack));
- SetPersistDataValues(0, req.player.id, pd_public_rw, 0, munkeeHack, setPersistentDataCallback, this);
- free(munkeeHack);
- }
- else
- {
- DEBUG_LOG(("Cannot connect!\n"));
- //if (IsStatsConnected())
- //CloseStatsConnection();
- }
- }
- break;
- case PSRequest::PSREQUEST_READCDKEYSTATS:
- {
- DEBUG_LOG(("Processing PSRequest::PSREQUEST_READCDKEYSTATS\n"));
- if (tryConnect())
- {
- incrOpCount();
- CDAuthInfo cdAuthInfo;
- cdAuthInfo.done = FALSE;
- cdAuthInfo.success = FALSE;
- cdAuthInfo.id = 0;
- char cdkeyHash[33] = "";
- char validationToken[33] = "";
- char *munkeeHack = strdup(req.cdkey.c_str()); // GenerateAuth takes a char*, not a const char* :P
-
- GenerateAuth(GetChallenge(NULL), munkeeHack, validationToken); // validation token
- GenerateAuth("", munkeeHack, cdkeyHash); // cdkey hash
-
- free (munkeeHack);
-
- PreAuthenticatePlayerCD( 0, "preorder", cdkeyHash, validationToken, preAuthCDCallback , &cdAuthInfo);
-
- while (running && IsStatsConnected() && !cdAuthInfo.done)
- PersistThink();
-
- DEBUG_LOG(("Looking for preorder status for %d (success=%d, done=%d) from CDKey %s with hash %s\n",
- cdAuthInfo.id, cdAuthInfo.success, cdAuthInfo.done, req.cdkey.c_str(), cdkeyHash));
- if (cdAuthInfo.done && cdAuthInfo.success)
- GetPersistDataValues(0, cdAuthInfo.id, pd_public_ro, 0, "\\preorder", getPreorderCallback, this);
- else
- decrOpCount();
- }
- }
- break;
- }
- }
-
- // update the network
- if (IsStatsConnected())
- {
- PersistThink();
- if (m_opCount <= 0)
- {
- DEBUG_ASSERTCRASH(m_opCount == 0, ("Negative operations pending!!!"));
- DEBUG_LOG(("m_opCount = %d - closing connection\n", m_opCount));
- CloseStatsConnection();
- m_opCount = 0;
- }
- }
-
- // end our timeslice
- Switch_Thread();
- }
-
- if (IsStatsConnected())
- CloseStatsConnection();
- } catch ( ... ) {
- DEBUG_CRASH(("Exception in storage thread!"));
- }
-}
-
-//-------------------------------------------------------------------------
-PSPlayerStats::PSPlayerStats( void )
-{
- reset();
-}
-
-void PSPlayerStats::reset( void )
-{
- id = 0;
- locale = 0;
- gamesAsRandom = 0;
- lastFPS = 0;
- lastGeneral = 0;
- gamesInRowWithLastGeneral = 0;
- builtNuke = 0;
- builtSCUD = 0;
- builtParticleCannon = 0;
- challengeMedals = 0;
- battleHonors = 0;
- winsInARow = 0;
- maxWinsInARow = 0;
- lossesInARow = 0;
- maxLossesInARow = 0;
- disconsInARow = 0;
- maxDisconsInARow = 0;
- desyncsInARow = 0;
- maxDesyncsInARow = 0;
- lastLadderPort = 0;
-
- //Added By Sadullah Nader
- maxQMwinsInARow = 0;
- QMwinsInARow = 0;
- //
-}
-
-//-------------------------------------------------------------------------
-#define CHECK(x) if (k == #x && generalMarker >= 0) { s.x[generalMarker] = atoi(v.c_str()); continue; }
-
-PSPlayerStats GameSpyPSMessageQueueInterface::parsePlayerKVPairs( std::string kvPairs )
-{
- PSPlayerStats s;
- kvPairs.append("\\");
-
- Int offset = 0;
- while (1)
- {
- Int firstMarker = kvPairs.find_first_of('\\', offset);
- if (firstMarker < 0)
- break;
- Int secondMarker = kvPairs.find_first_of('\\', firstMarker + 1);
- if (secondMarker < 0)
- break;
- Int thirdMarker = kvPairs.find_first_of('\\', secondMarker + 1);
- if (thirdMarker < 0)
- break;
- Int generalMarker = kvPairs.find_last_not_of("0123456789", secondMarker - 1);
- std::string k, v, g;
- if (generalMarker == secondMarker - 1)
- {
- k = kvPairs.substr(firstMarker + 1, secondMarker - firstMarker - 1);
- generalMarker = -1;
- }
- else
- {
- k = kvPairs.substr(firstMarker + 1, generalMarker - firstMarker);
- g = kvPairs.substr(generalMarker + 1, secondMarker - generalMarker - 1);
- generalMarker = atoi(g.c_str());
- }
- v = kvPairs.substr(secondMarker + 1, thirdMarker - secondMarker - 1);
- //DEBUG_LOG(("%d [%s] [%s]\n", generalMarker, k.c_str(), v.c_str()));
- offset = thirdMarker - 1;
-
- CHECK(wins);
- CHECK(losses);
- CHECK(games);
- CHECK(duration);
- CHECK(unitsKilled);
- CHECK(unitsLost);
- CHECK(unitsBuilt);
- CHECK(buildingsKilled);
- CHECK(buildingsLost);
- CHECK(buildingsBuilt);
- CHECK(earnings);
- CHECK(techCaptured);
- CHECK(discons);
- CHECK(desyncs);
- CHECK(surrenders);
- CHECK(gamesOf2p);
- CHECK(gamesOf3p);
- CHECK(gamesOf4p);
- CHECK(gamesOf5p);
- CHECK(gamesOf6p);
- CHECK(gamesOf7p);
- CHECK(gamesOf8p);
- CHECK(customGames);
- CHECK(QMGames);
-
- if (k == "locale" && generalMarker < 0)
- {
- s.locale = atoi(v.c_str());
- continue;
- }
-
- if (k == "random" && generalMarker < 0)
- {
- s.gamesAsRandom = atoi(v.c_str());
- continue;
- }
-
- if (k == "options" && generalMarker < 0)
- {
- s.options = v;
- continue;
- }
-
- if (k == "systemSpec" && generalMarker < 0)
- {
- s.systemSpec = v;
- continue;
- }
-
- if (k == "fps" && generalMarker < 0)
- {
- s.lastFPS = atof(v.c_str());
- continue;
- }
-
- if (k == "lastGeneral" && generalMarker < 0)
- {
- s.lastGeneral = atoi(v.c_str());
- continue;
- }
- if (k == "genInRow" && generalMarker < 0)
- {
- s.gamesInRowWithLastGeneral = atoi(v.c_str());
- continue;
- }
- if (k == "builtNuke" && generalMarker < 0)
- {
- s.builtNuke = atoi(v.c_str());
- continue;
- }
- if (k == "builtSCUD" && generalMarker < 0)
- {
- s.builtSCUD = atoi(v.c_str());
- continue;
- }
- if (k == "builtCannon" && generalMarker < 0)
- {
- s.builtParticleCannon = atoi(v.c_str());
- continue;
- }
- if (k == "challenge" && generalMarker < 0)
- {
- s.challengeMedals = atoi(v.c_str());
- continue;
- }
- if (k == "battle" && generalMarker < 0)
- {
- s.battleHonors = atoi(v.c_str());
- continue;
- }
-
- if (k == "WinRow" && generalMarker < 0)
- {
- s.winsInARow = atoi(v.c_str());
- continue;
- }
- if (k == "WinRowMax" && generalMarker < 0)
- {
- s.maxWinsInARow = atoi(v.c_str());
- continue;
- }
-
- if (k == "LossRow" && generalMarker < 0)
- {
- s.lossesInARow = atoi(v.c_str());
- continue;
- }
- if (k == "LossRowMax" && generalMarker < 0)
- {
- s.maxLossesInARow = atoi(v.c_str());
- continue;
- }
-
- if (k == "DSRow" && generalMarker < 0)
- {
- s.desyncsInARow = atoi(v.c_str());
- continue;
- }
- if (k == "DSRowMax" && generalMarker < 0)
- {
- s.maxDesyncsInARow = atoi(v.c_str());
- continue;
- }
-
- if (k == "DCRow" && generalMarker < 0)
- {
- s.disconsInARow = atoi(v.c_str());
- continue;
- }
- if (k == "DCRowMax" && generalMarker < 0)
- {
- s.maxDisconsInARow = atoi(v.c_str());
- continue;
- }
-
- if (k == "ladderPort" && generalMarker < 0)
- {
- s.lastLadderPort = atoi(v.c_str());
- continue;
- }
- if (k == "ladderHost" && generalMarker < 0)
- {
- s.lastLadderHost = v;
- continue;
- }
-
- //DEBUG_ASSERTCRASH(generalMarker >= 0, ("Unknown KV Pair in persistent storage: [%s] = [%s]\n", k.c_str(), v.c_str()));
- //DEBUG_ASSERTCRASH(generalMarker < 0, ("Unknown KV Pair in persistent storage for PlayerTemplate %d: [%s] = [%s]\n", generalMarker, k.c_str(), v.c_str()));
- }
-
- return s;
-}
-
-#define ITERATE_OVER(x) for (it = stats.x.begin(); it != stats.x.end(); ++it) \
-{ \
- if (it->second > 0) \
- { \
- sprintf(kvbuf, "\\" #x "%d\\%d", it->first, it->second); \
- s.append(kvbuf); \
- } \
-}
-
-std::string GameSpyPSMessageQueueInterface::formatPlayerKVPairs( PSPlayerStats stats )
-{
- char kvbuf[256];
- std::string s = "";
- PerGeneralMap::iterator it;
-
- ITERATE_OVER(wins);
- ITERATE_OVER(losses);
- ITERATE_OVER(games);
- ITERATE_OVER(duration);
- ITERATE_OVER(unitsKilled);
- ITERATE_OVER(unitsLost);
- ITERATE_OVER(unitsBuilt);
- ITERATE_OVER(buildingsKilled);
- ITERATE_OVER(buildingsLost);
- ITERATE_OVER(buildingsBuilt);
- ITERATE_OVER(earnings);
- ITERATE_OVER(techCaptured);
-
- //GS Report all disconnects, even if zero, because might have been
- //previously reported as 1 by updateAdditionalGameSpyDisconnections
-// ITERATE_OVER(discons);
- for (Int ptIdx = 0; ptIdx < ThePlayerTemplateStore->getPlayerTemplateCount(); ++ptIdx)
- {
-// const PlayerTemplate* pTemplate = ThePlayerTemplateStore->getNthPlayerTemplate(ptIdx);
-// const GeneralPersona* pGeneral = TheChallengeGenerals->getGeneralByTemplateName(pTemplate->getName());
-// BOOL isReported = pGeneral ? pGeneral->isStartingEnabled() : FALSE;
-// if( !isReported )
-// continue; //don't report unplayable templates (observer, boss, etc.)
-
- sprintf(kvbuf, "\\discons%d\\%d", ptIdx, stats.discons[ptIdx]);
- s.append(kvbuf);
- }
-
- ITERATE_OVER(desyncs);
- ITERATE_OVER(surrenders);
- ITERATE_OVER(gamesOf2p);
- ITERATE_OVER(gamesOf3p);
- ITERATE_OVER(gamesOf4p);
- ITERATE_OVER(gamesOf5p);
- ITERATE_OVER(gamesOf6p);
- ITERATE_OVER(gamesOf7p);
- ITERATE_OVER(gamesOf8p);
- ITERATE_OVER(customGames);
- ITERATE_OVER(QMGames);
-
- if (stats.locale > 0)
- {
- sprintf(kvbuf, "\\locale\\%d", stats.locale);
- s.append(kvbuf);
- }
-
- if (stats.gamesAsRandom > 0)
- {
- sprintf(kvbuf, "\\random\\%d", stats.gamesAsRandom);
- s.append(kvbuf);
- }
-
- if (stats.options.length())
- {
- _snprintf(kvbuf, 256, "\\options\\%s", stats.options.c_str());
- kvbuf[255] = 0;
- s.append(kvbuf);
- }
-
- if (stats.systemSpec.length())
- {
- _snprintf(kvbuf, 256, "\\systemSpec\\%s", stats.systemSpec.c_str());
- kvbuf[255] = 0;
- s.append(kvbuf);
- }
-
- if (stats.lastFPS > 0.0f)
- {
- sprintf(kvbuf, "\\fps\\%g", stats.lastFPS);
- s.append(kvbuf);
- }
- if (stats.lastGeneral >= 0)
- {
- sprintf(kvbuf, "\\lastGeneral\\%d", stats.lastGeneral);
- s.append(kvbuf);
- }
- if (stats.gamesInRowWithLastGeneral >= 0)
- {
- sprintf(kvbuf, "\\genInRow\\%d", stats.gamesInRowWithLastGeneral);
- s.append(kvbuf);
- }
- if (stats.builtParticleCannon >= 0)
- {
- sprintf(kvbuf, "\\builtCannon\\%d", stats.builtParticleCannon);
- s.append(kvbuf);
- }
- if (stats.builtNuke >= 0)
- {
- sprintf(kvbuf, "\\builtNuke\\%d", stats.builtNuke);
- s.append(kvbuf);
- }
- if (stats.builtSCUD >= 0)
- {
- sprintf(kvbuf, "\\builtSCUD\\%d", stats.builtSCUD);
- s.append(kvbuf);
- }
- if (stats.challengeMedals > 0)
- {
- sprintf(kvbuf, "\\challenge\\%d", stats.challengeMedals);
- s.append(kvbuf);
- }
- if (stats.battleHonors > 0)
- {
- sprintf(kvbuf, "\\battle\\%d", stats.battleHonors);
- s.append(kvbuf);
- }
-
- //if (stats.winsInARow > 0)
- {
- sprintf(kvbuf, "\\WinRow\\%d", stats.winsInARow);
- s.append(kvbuf);
- }
- if (stats.maxWinsInARow > 0)
- {
- sprintf(kvbuf, "\\WinRowMax\\%d", stats.maxWinsInARow);
- s.append(kvbuf);
- }
-
- //if (stats.lossesInARow > 0)
- {
- sprintf(kvbuf, "\\LossRow\\%d", stats.lossesInARow);
- s.append(kvbuf);
- }
- if (stats.maxLossesInARow > 0)
- {
- sprintf(kvbuf, "\\LossRowMax\\%d", stats.maxLossesInARow);
- s.append(kvbuf);
- }
-
- //if (stats.disconsInARow > 0)
- {
- sprintf(kvbuf, "\\DCRow\\%d", stats.disconsInARow);
- s.append(kvbuf);
- }
- if (stats.maxDisconsInARow > 0)
- {
- sprintf(kvbuf, "\\DCRowMax\\%d", stats.maxDisconsInARow);
- s.append(kvbuf);
- }
-
- //if (stats.desyncsInARow > 0)
- {
- sprintf(kvbuf, "\\DSRow\\%d", stats.desyncsInARow);
- s.append(kvbuf);
- }
- if (stats.maxDesyncsInARow > 0)
- {
- sprintf(kvbuf, "\\DSRowMax\\%d", stats.maxDesyncsInARow);
- s.append(kvbuf);
- }
-
- if (stats.lastLadderPort > 0)
- {
- sprintf(kvbuf, "\\ladderPort\\%d", stats.lastLadderPort);
- s.append(kvbuf);
- }
- if (stats.lastLadderHost.length())
- {
- _snprintf(kvbuf, 256, "\\ladderHost\\%s", stats.lastLadderHost.c_str());
- kvbuf[255] = 0;
- s.append(kvbuf);
- }
-
- DEBUG_LOG(("Formatted persistent values as '%s'\n", s.c_str()));
- return s;
-}
-
-//-------------------------------------------------------------------------
diff --git a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/PingThread.cpp b/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/PingThread.cpp
deleted file mode 100644
index ea814f758a4..00000000000
--- a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/PingThread.cpp
+++ /dev/null
@@ -1,575 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: PingThread.cpp //////////////////////////////////////////////////////
-// Ping thread
-// Author: Matthew D. Campbell, August 2002
-
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include // This one has to be here. Prevents collisions with windsock2.h
-
-#include "GameNetwork/GameSpy/PingThread.h"
-#include "mutex.h"
-#include "thread.h"
-
-#include "Common/StackDump.h"
-#include "Common/SubsystemInterface.h"
-
-//-------------------------------------------------------------------------
-
-static const Int NumWorkerThreads = 10;
-
-typedef std::queue RequestQueue;
-typedef std::queue ResponseQueue;
-class PingThreadClass;
-
-class Pinger : public PingerInterface
-{
-public:
- virtual ~Pinger();
- Pinger();
- virtual void startThreads( void );
- virtual void endThreads( void );
- virtual Bool areThreadsRunning( void );
-
- virtual void addRequest( const PingRequest& req );
- virtual Bool getRequest( PingRequest& resp );
-
- virtual void addResponse( const PingResponse& resp );
- virtual Bool getResponse( PingResponse& resp );
-
- virtual Bool arePingsInProgress( void );
- virtual Int getPing( AsciiString hostname );
-
- virtual void clearPingMap( void );
- virtual AsciiString getPingString( Int timeout );
-
-private:
- MutexClass m_requestMutex;
- MutexClass m_responseMutex;
- MutexClass m_pingMapMutex;
- RequestQueue m_requests;
- ResponseQueue m_responses;
- Int m_requestCount;
- Int m_responseCount;
-
- std::map m_pingMap;
-
- PingThreadClass *m_workerThreads[NumWorkerThreads];
-};
-
-PingerInterface* PingerInterface::createNewPingerInterface( void )
-{
- return NEW Pinger;
-}
-
-PingerInterface *ThePinger;
-
-//-------------------------------------------------------------------------
-
-class PingThreadClass : public ThreadClass
-{
-
-public:
- PingThreadClass() : ThreadClass() {}
-
- void Thread_Function();
-
-private:
- Int doPing( UnsignedInt IP, Int timeout );
-};
-
-
-//-------------------------------------------------------------------------
-
-Pinger::Pinger() : m_requestCount(0), m_responseCount(0)
-{
- for (Int i=0; iExecute();
- }
-}
-
-void Pinger::endThreads( void )
-{
- for (Int i=0; iIs_Running())
- return true;
- }
- }
- return false;
-}
-
-void Pinger::addRequest( const PingRequest& req )
-{
- MutexClass::LockClass m(m_requestMutex);
-
- ++m_requestCount;
- m_requests.push(req);
-}
-
-Bool Pinger::getRequest( PingRequest& req )
-{
- MutexClass::LockClass m(m_requestMutex, 0);
- if (m.Failed())
- return false;
-
- if (m_requests.empty())
- return false;
- req = m_requests.front();
- m_requests.pop();
- return true;
-}
-
-void Pinger::addResponse( const PingResponse& resp )
-{
- {
- MutexClass::LockClass m(m_pingMapMutex);
-
- m_pingMap[resp.hostname] = resp.avgPing;
- }
- {
- MutexClass::LockClass m(m_responseMutex);
-
- ++m_responseCount;
- m_responses.push(resp);
- }
-}
-
-Bool Pinger::getResponse( PingResponse& resp )
-{
- MutexClass::LockClass m(m_responseMutex, 0);
- if (m.Failed())
- return false;
-
- if (m_responses.empty())
- return false;
- resp = m_responses.front();
- m_responses.pop();
- return true;
-}
-
-Bool Pinger::arePingsInProgress( void )
-{
- return (m_requestCount != m_responseCount);
-}
-
-Int Pinger::getPing( AsciiString hostname )
-{
- MutexClass::LockClass m(m_pingMapMutex, 0);
- if (m.Failed())
- return false;
-
- std::map::const_iterator it = m_pingMap.find(hostname.str());
- if (it != m_pingMap.end())
- return it->second;
-
- return -1;
-}
-
-void Pinger::clearPingMap( void )
-{
- MutexClass::LockClass m(m_pingMapMutex);
- m_pingMap.clear();
-}
-
-AsciiString Pinger::getPingString( Int timeout )
-{
- MutexClass::LockClass m(m_pingMapMutex);
-
- AsciiString pingString;
- AsciiString tmp;
- for (std::map::const_iterator it = m_pingMap.begin(); it != m_pingMap.end(); ++it)
- {
- Int ping = it->second;
- if (ping < 0 || ping > timeout)
- ping = timeout;
- ping = ping * 255 / timeout;
- tmp.format("%2.2X", ping);
- pingString.concat(tmp);
- }
- return pingString;
-}
-
-//-------------------------------------------------------------------------
-
-void PingThreadClass::Thread_Function()
-{
- try {
- _set_se_translator( DumpExceptionInfo ); // Hook that allows stack trace.
- PingRequest req;
-
- WSADATA wsaData;
-
- // Fire up winsock (prob already done, but doesn't matter)
- WORD wVersionRequested = MAKEWORD(1, 1);
- WSAStartup( wVersionRequested, &wsaData );
-
- while ( running )
- {
- // deal with requests
- if (ThePinger->getRequest(req))
- {
- // resolve the hostname
- const char *hostnameBuffer = req.hostname.c_str();
- UnsignedInt IP = 0xFFFFFFFF;
- if (isdigit(hostnameBuffer[0]))
- {
- IP = inet_addr(hostnameBuffer);
- in_addr hostNode;
- hostNode.s_addr = IP;
- DEBUG_LOG(("pinging %s - IP = %s\n", hostnameBuffer, inet_ntoa(hostNode) ));
- }
- else
- {
- HOSTENT *hostStruct;
- in_addr *hostNode;
- hostStruct = gethostbyname(hostnameBuffer);
- if (hostStruct == NULL)
- {
- DEBUG_LOG(("pinging %s - host lookup failed\n", hostnameBuffer));
-
- // Even though this failed to resolve IP, still need to send a
- // callback.
- IP = 0xFFFFFFFF; // flag for IP resolve failed
- }
- hostNode = (in_addr *) hostStruct->h_addr;
- IP = hostNode->s_addr;
- DEBUG_LOG(("pinging %s IP = %s\n", hostnameBuffer, inet_ntoa(*hostNode) ));
- }
-
- // do ping
- Int totalPing = 0;
- Int goodReps = 0;
- Int reps = req.repetitions;
- while (reps-- && running && IP != 0xFFFFFFFF)
- {
- Int ping = doPing(IP, req.timeout);
- if (ping >= 0)
- {
- totalPing += ping;
- ++goodReps;
- }
-
- // end our timeslice
- Switch_Thread();
- }
- if (!goodReps)
- totalPing = -1;
- else
- totalPing = totalPing / goodReps;
-
- PingResponse resp;
- resp.hostname = req.hostname;
- resp.avgPing = totalPing;
- resp.repetitions = goodReps;
- ThePinger->addResponse(resp);
- }
-
- // end our timeslice
- Switch_Thread();
- }
-
- WSACleanup();
- } catch ( ... ) {
- DEBUG_CRASH(("Exception in ping thread!"));
- }
-}
-
-//-------------------------------------------------------------------------
-//-------------------------------------------------------------------------
-//-------------------------------------------------------------------------
-//-------------------------------------------------------------------------
-//-------------------------------------------------------------------------
-//-------------------------------------------------------------------------
-
-HANDLE WINAPI IcmpCreateFile(VOID); /* INVALID_HANDLE_VALUE on error */
-BOOL WINAPI IcmpCloseHandle(HANDLE IcmpHandle); /* FALSE on error */
-
-/* Note 2: For the most part, you can refer to RFC 791 for detials
- * on how to fill in values for the IP option information structure.
- */
-typedef struct ip_option_information
-{
- UnsignedByte Ttl; /* Time To Live (used for traceroute) */
- UnsignedByte Tos; /* Type Of Service (usually 0) */
- UnsignedByte Flags; /* IP header flags (usually 0) */
- UnsignedByte OptionsSize; /* Size of options data (usually 0, max 40) */
- UnsignedByte FAR *OptionsData; /* Options data buffer */
-}
-IPINFO, *PIPINFO, FAR *LPIPINFO;
-
-
-/* Note 1: The Reply Buffer will have an array of ICMP_ECHO_REPLY
- * structures, followed by options and the data in ICMP echo reply
- * datagram received. You must have room for at least one ICMP
- * echo reply structure, plus 8 bytes for an ICMP header.
- */
-typedef struct icmp_echo_reply
-{
- UnsignedInt Address; /* source address */
- ////////UnsignedInt Status; /* IP status value (see below) */
- UnsignedInt RTTime; /* Round Trip Time in milliseconds */
- UnsignedShort DataSize; /* reply data size */
- UnsignedShort Reserved; /* */
- void FAR *Data; /* reply data buffer */
- struct ip_option_information Options; /* reply options */
-}
-ICMPECHO, *PICMPECHO, FAR *LPICMPECHO;
-
-
-DWORD WINAPI IcmpSendEcho(
- HANDLE IcmpHandle, /* handle returned from IcmpCreateFile() */
- UnsignedInt DestAddress, /* destination IP address (in network order) */
- LPVOID RequestData, /* pointer to buffer to send */
- WORD RequestSize, /* length of data in buffer */
- LPIPINFO RequestOptns, /* see Note 2 */
- LPVOID ReplyBuffer, /* see Note 1 */
- DWORD ReplySize, /* length of reply (must allow at least 1 reply) */
- DWORD Timeout /* time in milliseconds to wait for reply */
-);
-
-
-#define IP_STATUS_BASE 11000
-#define IP_SUCCESS 0
-#define IP_BUF_TOO_SMALL (IP_STATUS_BASE + 1)
-#define IP_DEST_NET_UNREACHABLE (IP_STATUS_BASE + 2)
-#define IP_DEST_HOST_UNREACHABLE (IP_STATUS_BASE + 3)
-#define IP_DEST_PROT_UNREACHABLE (IP_STATUS_BASE + 4)
-#define IP_DEST_PORT_UNREACHABLE (IP_STATUS_BASE + 5)
-#define IP_NO_RESOURCES (IP_STATUS_BASE + 6)
-#define IP_BAD_OPTION (IP_STATUS_BASE + 7)
-#define IP_HW_ERROR (IP_STATUS_BASE + 8)
-#define IP_PACKET_TOO_BIG (IP_STATUS_BASE + 9)
-#define IP_REQ_TIMED_OUT (IP_STATUS_BASE + 10)
-#define IP_BAD_REQ (IP_STATUS_BASE + 11)
-#define IP_BAD_ROUTE (IP_STATUS_BASE + 12)
-#define IP_TTL_EXPIRED_TRANSIT (IP_STATUS_BASE + 13)
-#define IP_TTL_EXPIRED_REASSEM (IP_STATUS_BASE + 14)
-#define IP_PARAM_PROBLEM (IP_STATUS_BASE + 15)
-#define IP_SOURCE_QUENCH (IP_STATUS_BASE + 16)
-#define IP_OPTION_TOO_BIG (IP_STATUS_BASE + 17)
-#define IP_BAD_DESTINATION (IP_STATUS_BASE + 18)
-#define IP_ADDR_DELETED (IP_STATUS_BASE + 19)
-#define IP_SPEC_MTU_CHANGE (IP_STATUS_BASE + 20)
-#define IP_MTU_CHANGE (IP_STATUS_BASE + 21)
-#define IP_UNLOAD (IP_STATUS_BASE + 22)
-#define IP_GENERAL_FAILURE (IP_STATUS_BASE + 50)
-#define MAX_IP_STATUS IP_GENERAL_FAILURE
-#define IP_PENDING (IP_STATUS_BASE + 255)
-
-
-#define BUFSIZE 8192
-#define DEFAULT_LEN 32
-#define LOOPLIMIT 4
-#define DEFAULT_TTL 64
-
-Int PingThreadClass::doPing(UnsignedInt IP, Int timeout)
-{
- /*
- * Initialize default settings
- */
-
- IPINFO stIPInfo, *lpstIPInfo;
- HANDLE hICMP, hICMP_DLL;
- int i, j, nDataLen, nLoopLimit, nTimeOut, nTTL, nTOS;
- DWORD dwReplyCount;
- ///////IN_ADDR stDestAddr;
- BOOL fRet, fDontStop;
- ///BOOL fTraceRoute;
-
- nDataLen = DEFAULT_LEN;
- nLoopLimit = LOOPLIMIT;
- nTimeOut = timeout;
- fDontStop = FALSE;
- lpstIPInfo = NULL;
- nTTL = DEFAULT_TTL;
- nTOS = 0;
-
- Int pingTime = -1; // in case of error
-
- char achReqData[BUFSIZE];
- char achRepData[sizeof(ICMPECHO) + BUFSIZE];
-
-
- HANDLE ( WINAPI *lpfnIcmpCreateFile )( VOID ) = NULL;
- BOOL ( WINAPI *lpfnIcmpCloseHandle )( HANDLE ) = NULL;
- DWORD (WINAPI *lpfnIcmpSendEcho)(HANDLE, DWORD, LPVOID, WORD, LPVOID,
- LPVOID, DWORD, DWORD) = NULL;
-
-
- /*
- * Load the ICMP.DLL
- */
- hICMP_DLL = LoadLibrary("ICMP.DLL");
- if (hICMP_DLL == 0)
- {
- DEBUG_LOG(("LoadLibrary() failed: Unable to locate ICMP.DLL!\n"));
- goto cleanup;
- }
-
- /*
- * Get pointers to ICMP.DLL functions
- */
- lpfnIcmpCreateFile = (void * (__stdcall *)(void))GetProcAddress( (HINSTANCE)hICMP_DLL, "IcmpCreateFile");
- lpfnIcmpCloseHandle = (int (__stdcall *)(void *))GetProcAddress( (HINSTANCE)hICMP_DLL, "IcmpCloseHandle");
- lpfnIcmpSendEcho = (unsigned long (__stdcall *)(void *, unsigned long, void *, unsigned short,
- void *, void *, unsigned long, unsigned long))GetProcAddress( (HINSTANCE)hICMP_DLL, "IcmpSendEcho" );
-
- if ((!lpfnIcmpCreateFile) ||
- (!lpfnIcmpCloseHandle) ||
- (!lpfnIcmpSendEcho))
- {
- DEBUG_LOG(("GetProcAddr() failed for at least one function.\n"));
- goto cleanup;
- }
-
-
- /*
- * IcmpCreateFile() - Open the ping service
- */
- hICMP = (HANDLE) lpfnIcmpCreateFile();
- if (hICMP == INVALID_HANDLE_VALUE)
- {
- DEBUG_LOG(("IcmpCreateFile() failed"));
- goto cleanup;
- }
-
- /*
- * Init data buffer printable ASCII
- * 32 (space) through 126 (tilde)
- */
- for (j = 0, i = 32; j < nDataLen; j++, i++)
- {
- if (i >= 126)
- i = 32;
- achReqData[j] = i;
- }
-
- /*
- * Init IPInfo structure
- */
- lpstIPInfo = &stIPInfo;
- stIPInfo.Ttl = nTTL;
- stIPInfo.Tos = nTOS;
- stIPInfo.Flags = 0;
- stIPInfo.OptionsSize = 0;
- stIPInfo.OptionsData = NULL;
-
-
-
- /*
- * IcmpSendEcho() - Send the ICMP Echo Request
- * and read the Reply
- */
- dwReplyCount = lpfnIcmpSendEcho(
- hICMP,
- IP,
- achReqData,
- nDataLen,
- lpstIPInfo,
- achRepData,
- sizeof(achRepData),
- nTimeOut);
- if (dwReplyCount != 0)
- {
- //////////IN_ADDR stDestAddr;
- DWORD dwStatus;
-
- pingTime = (*(UnsignedInt *) & (achRepData[8]));
-
- // I've seen the ping time bigger than the timeout by a little
- // bit. How lame.
- if (pingTime > timeout)
- pingTime = timeout;
-
- dwStatus = *(DWORD *) & (achRepData[4]);
- if (dwStatus != IP_SUCCESS)
- {
- DEBUG_LOG(("ICMPERR: %d\n", dwStatus));
- }
-
- }
- else
- {
- DEBUG_LOG(("IcmpSendEcho() failed: %d\n", dwReplyCount));
- // Ok we didn't get a packet, just say everything's OK
- // and the time was -1
- pingTime = -1;
- goto cleanup;
- }
-
-
- /*
- * IcmpCloseHandle - Close the ICMP handle
- */
- fRet = lpfnIcmpCloseHandle(hICMP);
- if (fRet == FALSE)
- {
- DEBUG_LOG(("Error closing ICMP handle\n"));
- }
-
- // Say what you will about goto's but it's handy for stuff like this
-cleanup:
-
- // Shut down...
- if (hICMP_DLL)
- FreeLibrary((HINSTANCE)hICMP_DLL);
-
- return pingTime;
-}
-
-
-//-------------------------------------------------------------------------
diff --git a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/ThreadUtils.cpp b/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/ThreadUtils.cpp
deleted file mode 100644
index 274ea55f575..00000000000
--- a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/ThreadUtils.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: ThreadUtils.cpp //////////////////////////////////////////////////////
-// GameSpy thread utils
-// Author: Matthew D. Campbell, July 2002
-
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-//-------------------------------------------------------------------------
-
-std::wstring MultiByteToWideCharSingleLine( const char *orig )
-{
- Int len = strlen(orig);
- WideChar *dest = NEW WideChar[len+1];
-
- MultiByteToWideChar(CP_UTF8, 0, orig, -1, dest, len);
- WideChar *c = NULL;
- do
- {
- c = wcschr(dest, L'\n');
- if (c)
- {
- *c = L' ';
- }
- }
- while ( c != NULL );
- do
- {
- c = wcschr(dest, L'\r');
- if (c)
- {
- *c = L' ';
- }
- }
- while ( c != NULL );
-
- dest[len] = 0;
- std::wstring ret = dest;
- delete dest;
- return ret;
-}
-
-std::string WideCharStringToMultiByte( const WideChar *orig )
-{
- std::string ret;
- Int len = WideCharToMultiByte( CP_UTF8, 0, orig, wcslen(orig), NULL, 0, NULL, NULL ) + 1;
- if (len > 0)
- {
- char *dest = NEW char[len];
- WideCharToMultiByte( CP_UTF8, 0, orig, -1, dest, len, NULL, NULL );
- dest[len-1] = 0;
- ret = dest;
- delete dest;
- }
- return ret;
-}
-
-//-------------------------------------------------------------------------
-
diff --git a/Generals/Code/GameEngine/Source/GameNetwork/GameSpyChat.cpp b/Generals/Code/GameEngine/Source/GameNetwork/GameSpyChat.cpp
deleted file mode 100644
index 2d17ff3db4f..00000000000
--- a/Generals/Code/GameEngine/Source/GameNetwork/GameSpyChat.cpp
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: GameSpyChat.cpp //////////////////////////////////////////////////////
-// GameSpy chat handlers
-// Author: Matthew D. Campbell, February 2002
-
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "GameClient/GameText.h"
-#include "GameClient/GadgetListBox.h"
-#include "GameClient/LanguageFilter.h"
-#include "GameNetwork/GameSpy.h"
-#include "GameNetwork/GameSpyChat.h"
-#include "Common/QuotedPrintable.h"
-
-typedef set::const_iterator AsciiSetIter;
-
-/**
- * handleSlashCommands looks for slash ccommands and handles them,
- * returning true if it found one, false otherwise.
- * /i,/ignore list ignored players
- * /i,/ignore +name1 -name2 ignore name1, stop ignoring name2
- * /m,/me: shorthand for an action
- * /o,/on: find command to look up a user's location
- * /f,/find: find command to look up a user's location
- * /p,/page: page user(s)
- * /r,/reply: reply to last page
- * /raw: raw IRC command (only in debug & internal)
- * /oper: become an IRC op (only in debug & internal)
- * /quit: send the IRC quit command to exit WOL
- */
-static Bool handleSlashCommands( UnicodeString message, Bool isAction, GameWindow *playerListbox )
-{
- /*
- if (message.getCharAt(0) == L'/')
- {
- UnicodeString remainder = UnicodeString(message.str() + 1);
- UnicodeString token;
-
- switch (message.getCharAt(1))
- {
- case L'i':
- case L'I':
- remainder.nextToken(&token);
- if (token.compareNoCase(L"i") == 0 || token.compareNoCase(L"ignore") == 0)
- {
- if (remainder.isEmpty())
- {
- // List the people we're ignoring
- TheWOL->addText(TheGameText->fetch("WOL:BeginIgnoreList"));
- set *ignoreList = getIgnoreList();
- if (ignoreList)
- {
- UnicodeString msg;
- UnicodeString uName;
- AsciiSetIter iter = ignoreList->begin();
- while (iter != ignoreList->end())
- {
- uName.translate(*iter);
- msg.format(TheGameText->fetch("WOL:IgnoredUser"), uName.str());
- TheWOL->addText(msg);
- iter++;
- }
- }
- TheWOL->addText(TheGameText->fetch("WOL:EndIgnoreList"));
- }
-
- while ( remainder.nextToken(&token) )
- {
- AsciiString name;
- int doIgnore = 0;
- if (token.getCharAt(0) == L'+')
- {
- // Ignore somebody
- token = UnicodeString(token.str() + 1);
- name.translate(token);
- doIgnore = 1;
- }
- else if (token.getCharAt(0) == L'-')
- {
- // Listen to someone again
- token = UnicodeString(token.str() + 1);
- name.translate(token);
- doIgnore = 0;
- }
- else
- {
- // Ignore somebody
- token = UnicodeString(token.str());
- name.translate(token);
- doIgnore = 1;
- }
- IChat *ichat = TheWOL->getIChat();
- User user;
- strncpy((char *)user.name, name.str(), 9);
- user.name[9] = 0;
- ichat->SetSquelch(&user, doIgnore);
-
- if (doIgnore)
- addIgnore(name);
- else
- removeIgnore(name);
-
- UnicodeString msg;
- UnicodeString uName;
- uName.translate(name);
- msg.format(TheGameText->fetch("WOL:IgnoredUser"), uName.str());
- TheWOL->addText(msg);
- }
- return true;
- }
- break;
- case L'r':
- case L'R':
- remainder.nextToken(&token);
-#if defined _DEBUG || defined _INTERNAL
- if (token.compareNoCase(L"raw") == 0)
- {
- // Send raw IRC commands (Ascii only)
- AsciiString str;
- str.translate(remainder);
- str.concat('\n');
- IChat *ichat = TheWOL->getIChat();
- ichat->RequestRawMessage(str.str());
- TheWOL->addText(remainder);
- return true; // show it anyway
- }
-#endif
- break;
-#if defined _DEBUG || defined _INTERNAL
- case L'k':
- case L'K':
- remainder.nextToken(&token);
- if (token.compareNoCase(L"kick") == 0)
- {
-
- while ( remainder.nextToken(&token) )
- {
- AsciiString name;
- name.translate(token);
- IChat *ichat = TheWOL->getIChat();
- User user;
- strncpy((char *)user.name, name.str(), 9);
- user.name[9] = 0;
- ichat->RequestUserKick(&user);
- }
- return true;
- }
- break;
-#endif
- case L'o':
- case L'O':
- remainder.nextToken(&token);
- if (token.compareNoCase(L"on") == 0 || token.compareNoCase(L"o") == 0)
- {
- remainder.nextToken(&token);
- AsciiString userName;
- userName.translate(token);
- User user;
- strncpy((char *)user.name, userName.str(), 10);
- user.name[9] = 0;
- if (user.name[0] == 0)
- {
- // didn't enter a name
- TheWOL->addText(message);
- }
- else
- {
- // Send find command
- IChat *ichat = TheWOL->getIChat();
- ichat->RequestGlobalFind(&user);
- }
- return true; // show it anyway
- }
-#if defined _DEBUG || defined _INTERNAL
- else if (token.compareNoCase(L"oper") == 0)
- {
- // Send raw IRC oper command
- AsciiString str;
- str.translate(message);
- str.concat('\n');
- IChat *ichat = TheWOL->getIChat();
- ichat->RequestRawMessage(str.str());
- TheWOL->addText(message);
- return true; // show it anyway
- }
-#endif
- break;
- case L'p':
- case L'P':
- remainder.nextToken(&token);
- if (token.compareNoCase(L"page") == 0 || token.compareNoCase(L"p") == 0)
- {
- remainder.nextToken(&token);
- AsciiString userName;
- userName.translate(token);
- User user;
- strncpy((char *)user.name, userName.str(), 10);
- user.name[9] = 0;
- remainder.trim();
- if (user.name[0] == 0 || remainder.isEmpty())
- {
- // didn't enter a name or message
- TheWOL->addText(message);
- }
- else
- {
- // Send page command
- IChat *ichat = TheWOL->getIChat();
- ichat->RequestGlobalUnicodePage(&user, remainder.str());
- }
- return true; // show it anyway
- }
- break;
- case L'q':
- case L'Q':
- remainder.nextToken(&token);
- if (token.compareNoCase(L"quit") == 0)
- {
- TheWOL->setState(WOLAPI_LOGIN);
- TheWOL->addCommand(WOLCOMMAND_LOGOUT);
- //TheWOL->setScreen(WOLAPI_MENU_WELCOME);
- return true; // show it anyway
- }
- break;
-#if defined _DEBUG || defined _INTERNAL
- case L'c':
- case L'C':
- remainder.nextToken(&token);
- if (token.compareNoCase(L"colortest") == 0)
- {
- addColorText(token, 0xDD, 0xE2, 0x0D, 0xff);
- addColorText(token, 0xFF, 0x19, 0x19, 0xff);
- addColorText(token, 0x2A, 0x74, 0xE2, 0xff);
- addColorText(token, 0x3E, 0xD1, 0x2E, 0xff);
- addColorText(token, 0xFF, 0xA0, 0x19, 0xff);
- addColorText(token, 0x32, 0xD7, 0xE6, 0xff);
- addColorText(token, 0x95, 0x28, 0xBD, 0xff);
- addColorText(token, 0xFF, 0x9A, 0xEB, 0xff);
- return true; // show it anyway
- }
- break;
-#endif // _DEBUG || defined _INTERNAL
- }
- }
- */
- return false;
-}
-
-static handleUnicodeMessage( const char *nick, UnicodeString msg, Bool isPublic, Bool isAction );
-
-Bool GameSpySendChat( UnicodeString message, Bool isAction, GameWindow *playerListbox )
-{
- RoomType roomType = StagingRoom;
- if (TheGameSpyChat->getCurrentGroupRoomID())
- roomType = GroupRoom;
-
- message.trim();
- // Echo the user's input to the chat window
- if (!message.isEmpty())
- {
- // Check for slash commands
- if (handleSlashCommands(message, isAction, playerListbox))
- {
- return false; // already handled
- }
-
- if (!playerListbox)
- {
- // Public message
- if (isAction)
- {
- peerMessageRoom(TheGameSpyChat->getPeer(), roomType, UnicodeStringToQuotedPrintable(message).str(), ActionMessage);
- //if (roomType == StagingRoom)
- //handleUnicodeMessage(TheGameSpyChat->getloginName().str(), message, true, true);
- }
- else
- {
- peerMessageRoom(TheGameSpyChat->getPeer(), roomType, UnicodeStringToQuotedPrintable(message).str(), NormalMessage);
- //if (roomType == StagingRoom)
- //handleUnicodeMessage(TheGameSpyChat->getloginName().str(), message, true, false);
- }
- return false;
- }
-
- // Get the selections (is this a private message?)
- Int maxSel = GadgetListBoxGetListLength(playerListbox);
- Int *selections;
- GadgetListBoxGetSelected(playerListbox, (Int *)&selections);
-
- if (selections[0] == -1)
- {
- // Public message
- if (isAction)
- {
- peerMessageRoom(TheGameSpyChat->getPeer(), roomType, UnicodeStringToQuotedPrintable(message).str(), ActionMessage);
- //if (roomType == StagingRoom)
- //handleUnicodeMessage(TheGameSpyChat->getloginName().str(), message, true, true);
- }
- else
- {
- peerMessageRoom(TheGameSpyChat->getPeer(), roomType, UnicodeStringToQuotedPrintable(message).str(), NormalMessage);
- //if (roomType == StagingRoom)
- //handleUnicodeMessage(TheGameSpyChat->getloginName().str(), message, true, false);
- }
- return false;
- }
- else
- {
- // Private message
-
- // Construct a list
- AsciiString names = AsciiString::TheEmptyString;
- AsciiString tmp = AsciiString::TheEmptyString;
- AsciiString aStr; // AsciiString buf for translating Unicode entries
- names.format("%s", TheGameSpyChat->getLoginName().str());
- for (int i=0; igetLoginName()))
- {
- tmp.format(",%s", aStr.str());
- names.concat(tmp);
- }
- }
- else
- {
- break;
- }
- }
-
- if (!names.isEmpty())
- {
- if (isAction)
- {
- peerMessagePlayer(TheGameSpyChat->getPeer(), names.str(), UnicodeStringToQuotedPrintable(message).str(), ActionMessage);
- }
- else
- {
- peerMessagePlayer(TheGameSpyChat->getPeer(), names.str(), UnicodeStringToQuotedPrintable(message).str(), NormalMessage);
- }
- }
-
- return true;
- }
- }
- return false;
-}
-
-void RoomMessageCallback(PEER peer, RoomType roomType,
- const char * nick, const char * message,
- MessageType messageType, void * param)
-{
- DEBUG_LOG(("RoomMessageCallback\n"));
- handleUnicodeMessage(nick, QuotedPrintableToUnicodeString(message), true, (messageType == ActionMessage));
-}
-
-void PlayerMessageCallback(PEER peer,
- const char * nick, const char * message,
- MessageType messageType, void * param)
-{
- DEBUG_LOG(("PlayerMessageCallback\n"));
- handleUnicodeMessage(nick, QuotedPrintableToUnicodeString(message), false, (messageType == ActionMessage));
-}
-
-static handleUnicodeMessage( const char *nick, UnicodeString msg, Bool isPublic, Bool isAction )
-{
- GameSpyColors style;
-
- Bool isOwner = false;
- Int flags = 0;
- if (TheGameSpyChat->getCurrentGroupRoomID())
- peerGetPlayerFlags(TheGameSpyChat->getPeer(), nick, GroupRoom, &flags);
- else
- peerGetPlayerFlags(TheGameSpyChat->getPeer(), nick, StagingRoom, &flags);
- isOwner = flags & PEER_FLAG_OP;
-
- if (isPublic && isAction)
- {
- style = (isOwner)?GSCOLOR_CHAT_OWNER_EMOTE:GSCOLOR_CHAT_EMOTE;
- }
- else if (isPublic)
- {
- style = (isOwner)?GSCOLOR_CHAT_OWNER:GSCOLOR_CHAT_NORMAL;
- }
- else if (isAction)
- {
- style = (isOwner)?GSCOLOR_CHAT_PRIVATE_OWNER_EMOTE:GSCOLOR_CHAT_PRIVATE_EMOTE;
- }
- else
- {
- style = (isOwner)?GSCOLOR_CHAT_PRIVATE_OWNER:GSCOLOR_CHAT_PRIVATE;
- }
-
- UnicodeString name;
- name.translate(nick);
-
- // filters language
-// if( TheGlobalData->m_languageFilterPref )
-// {
- TheLanguageFilter->filterLine(msg);
-// }
-
- UnicodeString fullMsg;
- if (isAction)
- {
- fullMsg.format( L"%ls %ls", name.str(), msg.str() );
- }
- else
- {
- fullMsg.format( L"[%ls] %ls", name.str(), msg.str() );
- }
- GameSpyAddText(fullMsg, style);
-}
-
-void GameSpyAddText( UnicodeString message, GameSpyColors color )
-{
- GameWindow *textWindow = NULL;
-
- if (!textWindow)
- textWindow = listboxLobbyChat;
- if (!textWindow)
- textWindow = listboxGameSetupChat;
-
- if (!textWindow)
- return;
-
- GadgetListBoxAddEntryText(textWindow, message, GameSpyColor[color], -1, -1);
-
-}
-
diff --git a/Generals/Code/GameEngine/Source/GameNetwork/GameSpyGP.cpp b/Generals/Code/GameEngine/Source/GameNetwork/GameSpyGP.cpp
deleted file mode 100644
index 751d81d21f0..00000000000
--- a/Generals/Code/GameEngine/Source/GameNetwork/GameSpyGP.cpp
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: GameSpyGP.cpp //////////////////////////////////////////////////////
-// GameSpy GP callbacks, utils, etc
-// Author: Matthew D. Campbell, February 2002
-
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "GameClient/GameText.h"
-#include "GameNetwork/GameSpy.h"
-#include "GameNetwork/GameSpyGP.h"
-#include "GameNetwork/GameSpyOverlay.h"
-
-GPConnection TheGPConnectionObj;
-GPConnection *TheGPConnection = &TheGPConnectionObj;
-GPProfile GameSpyLocalProfile = 0;
-char GameSpyProfilePassword[64];
-
-void GPRecvBuddyMessageCallback(GPConnection * pconnection, GPRecvBuddyMessageArg * arg, void * param)
-{
- DEBUG_LOG(("GPRecvBuddyMessageCallback: message from %d is %s\n", arg->profile, arg->message));
-
- //gpGetInfo(pconn, arg->profile, GP_DONT_CHECK_CACHE, GP_BLOCKING, (GPCallback)Whois, NULL);
- //printf("MESSAGE (%d): %s: %s\n", msgCount,whois, arg->message);
-}
-
-static void buddyTryReconnect( void )
-{
- TheGameSpyChat->reconnectProfile();
-}
-
-void GPErrorCallback(GPConnection * pconnection, GPErrorArg * arg, void * param)
-{
- DEBUG_LOG(("GPErrorCallback\n"));
-
- AsciiString errorCodeString;
- AsciiString resultString;
-
- #define RESULT(x) case x: resultString = #x; break;
- switch(arg->result)
- {
- RESULT(GP_NO_ERROR)
- RESULT(GP_MEMORY_ERROR)
- RESULT(GP_PARAMETER_ERROR)
- RESULT(GP_NETWORK_ERROR)
- RESULT(GP_SERVER_ERROR)
- default:
- resultString = "Unknown result!";
- }
- #undef RESULT
-
- #define ERRORCODE(x) case x: errorCodeString = #x; break;
- switch(arg->errorCode)
- {
- ERRORCODE(GP_GENERAL)
- ERRORCODE(GP_PARSE)
- ERRORCODE(GP_NOT_LOGGED_IN)
- ERRORCODE(GP_BAD_SESSKEY)
- ERRORCODE(GP_DATABASE)
- ERRORCODE(GP_NETWORK)
- ERRORCODE(GP_FORCED_DISCONNECT)
- ERRORCODE(GP_CONNECTION_CLOSED)
- ERRORCODE(GP_LOGIN)
- ERRORCODE(GP_LOGIN_TIMEOUT)
- ERRORCODE(GP_LOGIN_BAD_NICK)
- ERRORCODE(GP_LOGIN_BAD_EMAIL)
- ERRORCODE(GP_LOGIN_BAD_PASSWORD)
- ERRORCODE(GP_LOGIN_BAD_PROFILE)
- ERRORCODE(GP_LOGIN_PROFILE_DELETED)
- ERRORCODE(GP_LOGIN_CONNECTION_FAILED)
- ERRORCODE(GP_LOGIN_SERVER_AUTH_FAILED)
- ERRORCODE(GP_NEWUSER)
- ERRORCODE(GP_NEWUSER_BAD_NICK)
- ERRORCODE(GP_NEWUSER_BAD_PASSWORD)
- ERRORCODE(GP_UPDATEUI)
- ERRORCODE(GP_UPDATEUI_BAD_EMAIL)
- ERRORCODE(GP_NEWPROFILE)
- ERRORCODE(GP_NEWPROFILE_BAD_NICK)
- ERRORCODE(GP_NEWPROFILE_BAD_OLD_NICK)
- ERRORCODE(GP_UPDATEPRO)
- ERRORCODE(GP_UPDATEPRO_BAD_NICK)
- ERRORCODE(GP_ADDBUDDY)
- ERRORCODE(GP_ADDBUDDY_BAD_FROM)
- ERRORCODE(GP_ADDBUDDY_BAD_NEW)
- ERRORCODE(GP_ADDBUDDY_ALREADY_BUDDY)
- ERRORCODE(GP_AUTHADD)
- ERRORCODE(GP_AUTHADD_BAD_FROM)
- ERRORCODE(GP_AUTHADD_BAD_SIG)
- ERRORCODE(GP_STATUS)
- ERRORCODE(GP_BM)
- ERRORCODE(GP_BM_NOT_BUDDY)
- ERRORCODE(GP_GETPROFILE)
- ERRORCODE(GP_GETPROFILE_BAD_PROFILE)
- ERRORCODE(GP_DELBUDDY)
- ERRORCODE(GP_DELBUDDY_NOT_BUDDY)
- ERRORCODE(GP_DELPROFILE)
- ERRORCODE(GP_DELPROFILE_LAST_PROFILE)
- ERRORCODE(GP_SEARCH)
- ERRORCODE(GP_SEARCH_CONNECTION_FAILED)
- default:
- errorCodeString = "Unknown error code!";
- }
- #undef ERRORCODE
-
- if(arg->fatal)
- {
- DEBUG_LOG(( "-----------\n"));
- DEBUG_LOG(( "GP FATAL ERROR\n"));
- DEBUG_LOG(( "-----------\n"));
-
- // if we're still connected to the chat server, tell the user. He can always hit the buddy
- // button to try reconnecting. Oh yes, also hide the buddy popup.
- GameSpyCloseOverlay(GSOVERLAY_BUDDY);
- if (TheGameSpyChat->isConnected())
- {
- GSMessageBoxYesNo(TheGameText->fetch("GUI:GPErrorTitle"), TheGameText->fetch("GUI:GPDisconnected"), buddyTryReconnect, NULL);
- }
- }
- else
- {
- DEBUG_LOG(( "-----\n"));
- DEBUG_LOG(( "GP ERROR\n"));
- DEBUG_LOG(( "-----\n"));
- }
- DEBUG_LOG(( "RESULT: %s (%d)\n", resultString.str(), arg->result));
- DEBUG_LOG(( "ERROR CODE: %s (0x%X)\n", errorCodeString.str(), arg->errorCode));
- DEBUG_LOG(( "ERROR STRING: %s\n", arg->errorString));
-}
-
-void GPRecvBuddyStatusCallback(GPConnection * connection, GPRecvBuddyStatusArg * arg, void * param)
-{
- DEBUG_LOG(("GPRecvBuddyStatusCallback: info on %d is in %d\n", arg->profile, arg->index));
-
- //GameSpyUpdateBuddyOverlay();
-}
-
-void GPRecvBuddyRequestCallback(GPConnection * connection, GPRecvBuddyRequestArg * arg, void * param)
-{
- DEBUG_LOG(("GPRecvBuddyRequestCallback: %d wants to be our buddy because '%s'\n", arg->profile, arg->reason));
-}
diff --git a/Generals/Code/GameEngine/Source/GameNetwork/GameSpyGameInfo.cpp b/Generals/Code/GameEngine/Source/GameNetwork/GameSpyGameInfo.cpp
deleted file mode 100644
index 4fecf7a8d77..00000000000
--- a/Generals/Code/GameEngine/Source/GameNetwork/GameSpyGameInfo.cpp
+++ /dev/null
@@ -1,754 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: GameSpyGameInfo.cpp //////////////////////////////////////////////////////
-// GameSpy game setup state info
-// Author: Matthew D. Campbell, December 2001
-
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/GameEngine.h"
-#include "Common/Player.h"
-#include "Common/PlayerList.h"
-#include "Common/RandomValue.h"
-#include "Common/Scorekeeper.h"
-#include "GameClient/Shell.h"
-#include "GameClient/GameText.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpyGameInfo.h"
-#include "GameNetwork/NetworkInterface.h"
-#include "GameNetwork/NetworkUtil.h"
-#include "GameNetwork/NetworkDefs.h"
-#include "GameNetwork/NAT.h"
-#include "GameLogic/GameLogic.h"
-#include "GameLogic/VictoryConditions.h"
-
-// Singleton ------------------------------------------
-
-GameSpyGameInfo *TheGameSpyGame = NULL;
-
-// Helper Functions ----------------------------------------
-
-GameSpyGameSlot::GameSpyGameSlot()
-{
- GameSlot();
- m_gameSpyLogin.clear();
- m_gameSpyLocale.clear();
- m_profileID = 0;
-}
-
-// Helper Functions ----------------------------------------
-/*
-** Function definitions for the MIB-II entry points.
-*/
-
-BOOL (__stdcall *SnmpExtensionInitPtr)(IN DWORD dwUpTimeReference, OUT HANDLE *phSubagentTrapEvent, OUT AsnObjectIdentifier *pFirstSupportedRegion);
-BOOL (__stdcall *SnmpExtensionQueryPtr)(IN BYTE bPduType, IN OUT RFC1157VarBindList *pVarBindList, OUT AsnInteger32 *pErrorStatus, OUT AsnInteger32 *pErrorIndex);
-LPVOID (__stdcall *SnmpUtilMemAllocPtr)(IN DWORD bytes);
-VOID (__stdcall *SnmpUtilMemFreePtr)(IN LPVOID pMem);
-
-typedef struct tConnInfoStruct {
- unsigned int State;
- unsigned long LocalIP;
- unsigned short LocalPort;
- unsigned long RemoteIP;
- unsigned short RemotePort;
-} ConnInfoStruct;
-
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
-#endif
-
-/***********************************************************************************************
- * Get_Local_Chat_Connection_Address -- Which address are we using to talk to the chat server? *
- * *
- * *
- * *
- * INPUT: Ptr to address to return local address * *
- * *
- * OUTPUT: True if success *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 10/27/00 3:24PM ST : Created *
- *=============================================================================================*/
-Bool GetLocalChatConnectionAddress(AsciiString serverName, UnsignedShort serverPort, UnsignedInt& localIP)
-{
- //return false;
- /*
- ** Local defines.
- */
- enum {
- CLOSED = 1,
- LISTENING,
- SYN_SENT,
- SEN_RECEIVED,
- ESTABLISHED,
- FIN_WAIT,
- FIN_WAIT2,
- CLOSE_WAIT,
- LAST_ACK,
- CLOSING,
- TIME_WAIT,
- DELETE_TCB
- };
-
- enum {
- tcpConnState = 1,
- tcpConnLocalAddress,
- tcpConnLocalPort,
- tcpConnRemAddress,
- tcpConnRemPort
- };
-
-
- /*
- ** Locals.
- */
- unsigned char serverAddress[4];
- unsigned char remoteAddress[4];
- HANDLE trap_handle;
- AsnObjectIdentifier first_supported_region;
- std::vector connectionVector;
- int last_field;
- int index;
- AsnInteger error_status;
- AsnInteger error_index;
- int conn_entry_type_index;
- int conn_entry_type;
- Bool found;
-
- /*
- ** Statics.
- */
- static char _conn_state[][32] = {
- "?",
- "CLOSED",
- "LISTENING",
- "SYN_SENT",
- "SEN_RECEIVED",
- "ESTABLISHED",
- "FIN_WAIT",
- "FIN_WAIT2",
- "CLOSE_WAIT",
- "LAST_ACK",
- "CLOSING",
- "TIME_WAIT",
- "DELETE_TCB"
- };
-
- DEBUG_LOG(("Finding local address used to talk to the chat server\n"));
- DEBUG_LOG(("Current chat server name is %s\n", serverName.str()));
- DEBUG_LOG(("Chat server port is %d\n", serverPort));
-
- /*
- ** Get the address of the chat server.
- */
- DEBUG_LOG( ("About to call gethostbyname\n"));
- struct hostent *host_info = gethostbyname(serverName.str());
-
- if (!host_info) {
- DEBUG_LOG( ("gethostbyname failed! Error code %d\n", WSAGetLastError()));
- return(false);
- }
-
- memcpy(serverAddress, &host_info->h_addr_list[0][0], 4);
- unsigned long temp = *((unsigned long*)(&serverAddress[0]));
- temp = ntohl(temp);
- *((unsigned long*)(&serverAddress[0])) = temp;
-
- DEBUG_LOG(("Host address is %d.%d.%d.%d\n", serverAddress[3], serverAddress[2], serverAddress[1], serverAddress[0]));
-
- /*
- ** Load the MIB-II SNMP DLL.
- */
- DEBUG_LOG(("About to load INETMIB1.DLL\n"));
-
- HINSTANCE mib_ii_dll = LoadLibrary("inetmib1.dll");
- if (mib_ii_dll == NULL) {
- DEBUG_LOG(("Failed to load INETMIB1.DLL\n"));
- return(false);
- }
-
- DEBUG_LOG(("About to load SNMPAPI.DLL\n"));
-
- HINSTANCE snmpapi_dll = LoadLibrary("snmpapi.dll");
- if (snmpapi_dll == NULL) {
- DEBUG_LOG(("Failed to load SNMPAPI.DLL\n"));
- FreeLibrary(mib_ii_dll);
- return(false);
- }
-
- /*
- ** Get the function pointers into the .dll
- */
- SnmpExtensionInitPtr = (int (__stdcall *)(unsigned long,void ** ,AsnObjectIdentifier *)) GetProcAddress(mib_ii_dll, "SnmpExtensionInit");
- SnmpExtensionQueryPtr = (int (__stdcall *)(unsigned char,SnmpVarBindList *,long *,long *)) GetProcAddress(mib_ii_dll, "SnmpExtensionQuery");
- SnmpUtilMemAllocPtr = (void *(__stdcall *)(unsigned long)) GetProcAddress(snmpapi_dll, "SnmpUtilMemAlloc");
- SnmpUtilMemFreePtr = (void (__stdcall *)(void *)) GetProcAddress(snmpapi_dll, "SnmpUtilMemFree");
- if (SnmpExtensionInitPtr == NULL || SnmpExtensionQueryPtr == NULL || SnmpUtilMemAllocPtr == NULL || SnmpUtilMemFreePtr == NULL) {
- DEBUG_LOG(("Failed to get proc addresses for linked functions\n"));
- FreeLibrary(snmpapi_dll);
- FreeLibrary(mib_ii_dll);
- return(false);
- }
-
-
- RFC1157VarBindList *bind_list_ptr = (RFC1157VarBindList *) SnmpUtilMemAllocPtr(sizeof(RFC1157VarBindList));
- RFC1157VarBind *bind_ptr = (RFC1157VarBind *) SnmpUtilMemAllocPtr(sizeof(RFC1157VarBind));
-
- /*
- ** OK, here we go. Try to initialise the .dll
- */
- DEBUG_LOG(("About to init INETMIB1.DLL\n"));
- int ok = SnmpExtensionInitPtr(GetCurrentTime(), &trap_handle, &first_supported_region);
-
- if (!ok) {
- /*
- ** Aw crap.
- */
- DEBUG_LOG(("Failed to init the .dll\n"));
- SnmpUtilMemFreePtr(bind_list_ptr);
- SnmpUtilMemFreePtr(bind_ptr);
- FreeLibrary(snmpapi_dll);
- FreeLibrary(mib_ii_dll);
- return(false);
- }
-
- /*
- ** Name of mib_ii object we want to query. See RFC 1213.
- **
- ** iso.org.dod.internet.mgmt.mib-2.tcp.tcpConnTable.TcpConnEntry.tcpConnState
- ** 1 3 6 1 2 1 6 13 1 1
- */
- unsigned int mib_ii_name[] = {1,3,6,1,2,1,6,13,1,1};
- unsigned int *mib_ii_name_ptr = (unsigned int *) SnmpUtilMemAllocPtr(sizeof(mib_ii_name));
- memcpy(mib_ii_name_ptr, mib_ii_name, sizeof(mib_ii_name));
-
- /*
- ** Get the index of the conn entry data.
- */
- conn_entry_type_index = ARRAY_SIZE(mib_ii_name) - 1;
-
- /*
- ** Set up the bind list.
- */
- bind_ptr->name.idLength = ARRAY_SIZE(mib_ii_name);
- bind_ptr->name.ids = mib_ii_name;
- bind_list_ptr->list = bind_ptr;
- bind_list_ptr->len = 1;
-
-
- /*
- ** We start with the tcpConnLocalAddress field.
- */
- last_field = 1;
-
- /*
- ** First connection.
- */
- index = 0;
-
- /*
- ** Suck out that tcp connection info....
- */
- while (true) {
-
- if (!SnmpExtensionQueryPtr(SNMP_PDU_GETNEXT, bind_list_ptr, &error_status, &error_index)) {
- //if (!SnmpExtensionQueryPtr(ASN_RFC1157_GETNEXTREQUEST, bind_list_ptr, &error_status, &error_index)) {
- DEBUG_LOG(("SnmpExtensionQuery returned false\n"));
- SnmpUtilMemFreePtr(bind_list_ptr);
- SnmpUtilMemFreePtr(bind_ptr);
- FreeLibrary(snmpapi_dll);
- FreeLibrary(mib_ii_dll);
- return(false);
- }
-
- /*
- ** If this is something new we aren't looking for then we are done.
- */
- if (bind_ptr->name.idLength < ARRAY_SIZE(mib_ii_name)) {
- break;
- }
-
- /*
- ** Get the type of info we are looking at. See RFC1213.
- **
- ** 1 = tcpConnState
- ** 2 = tcpConnLocalAddress
- ** 3 = tcpConnLocalPort
- ** 4 = tcpConnRemAddress
- ** 5 = tcpConnRemPort
- **
- ** tcpConnState is one of the following...
- **
- ** 1 closed
- ** 2 listen
- ** 3 synSent
- ** 4 synReceived
- ** 5 established
- ** 6 finWait1
- ** 7 finWait2
- ** 8 closeWait
- ** 9 lastAck
- ** 10 closing
- ** 11 timeWait
- ** 12 deleteTCB
- */
- conn_entry_type = bind_ptr->name.ids[conn_entry_type_index];
-
- if (last_field != conn_entry_type) {
- index = 0;
- last_field = conn_entry_type;
- }
-
- switch (conn_entry_type) {
-
- /*
- ** 1. First field in the entry. Need to create a new connection info struct
- ** here to store this connection in.
- */
- case tcpConnState:
- {
- ConnInfoStruct new_conn;
- new_conn.State = bind_ptr->value.asnValue.number;
- connectionVector.push_back(new_conn);
- break;
- }
-
- /*
- ** 2. Local address field.
- */
- case tcpConnLocalAddress:
- DEBUG_ASSERTCRASH(index < connectionVector.size(), ("Bad connection index"));
- connectionVector[index].LocalIP = *((unsigned long*)bind_ptr->value.asnValue.address.stream);
- index++;
- break;
-
- /*
- ** 3. Local port field.
- */
- case tcpConnLocalPort:
- DEBUG_ASSERTCRASH(index < connectionVector.size(), ("Bad connection index"));
- connectionVector[index].LocalPort = bind_ptr->value.asnValue.number;
- //connectionVector[index]->LocalPort = ntohs(connectionVector[index]->LocalPort);
- index++;
- break;
-
- /*
- ** 4. Remote address field.
- */
- case tcpConnRemAddress:
- DEBUG_ASSERTCRASH(index < connectionVector.size(), ("Bad connection index"));
- connectionVector[index].RemoteIP = *((unsigned long*)bind_ptr->value.asnValue.address.stream);
- index++;
- break;
-
- /*
- ** 5. Remote port field.
- */
- case tcpConnRemPort:
- DEBUG_ASSERTCRASH(index < connectionVector.size(), ("Bad connection index"));
- connectionVector[index].RemotePort = bind_ptr->value.asnValue.number;
- //connectionVector[index]->RemotePort = ntohs(connectionVector[index]->RemotePort);
- index++;
- break;
- }
- }
-
- SnmpUtilMemFreePtr(bind_list_ptr);
- SnmpUtilMemFreePtr(bind_ptr);
- SnmpUtilMemFreePtr(mib_ii_name_ptr);
-
- DEBUG_LOG(("Got %d connections in list, parsing...\n", connectionVector.size()));
-
- /*
- ** Right, we got the lot. Lets see if any of them have the same address as the chat
- ** server we think we are talking to.
- */
- found = false;
- for (Int i=0; igetSlot(i);
- if (slot && slot->isOccupied())
- numUsers++;
- }
-
- if (numUsers < 2)
- {
- if (TheGameSpyGame->amIHost())
- {
- UnicodeString text;
- text.format(TheGameText->fetch("LAN:NeedMorePlayers"),numUsers);
- TheGameSpyInfo->addText(text, GSCOLOR_DEFAULT, NULL);
- }
- return;
- }
-
- TheGameSpyGame->startGame(0);
- }
-}
-
-void GameSpyLaunchGame( void )
-{
- if (TheGameSpyGame)
- {
-
- // Set up the game network
- AsciiString user;
- AsciiString userList;
- DEBUG_ASSERTCRASH(TheNetwork == NULL, ("For some reason TheNetwork isn't NULL at the start of this game. Better look into that."));
-
- if (TheNetwork != NULL) {
- delete TheNetwork;
- TheNetwork = NULL;
- }
-
- // Time to initialize TheNetwork for this game.
- TheNetwork = NetworkInterface::createNetwork();
- TheNetwork->init();
- /*
- if (!TheGameSpyGame->amIHost())
- TheNetwork->setLocalAddress((207<<24) | (138<<16) | (47<<8) | 15, 8088);
- else
- */
- TheNetwork->setLocalAddress(TheGameSpyGame->getLocalIP(), TheNAT->getSlotPort(TheGameSpyGame->getLocalSlotNum()));
- TheNetwork->attachTransport(TheNAT->getTransport());
-
- user = TheGameSpyInfo->getLocalName();
- for (Int i=0; igetSlot(i);
- if (!slot)
- {
- DEBUG_CRASH(("No GameSlot[%d]!", i));
- delete TheNetwork;
- TheNetwork = NULL;
- return;
- }
-
-// UnsignedInt ip = htonl(slot->getIP());
- UnsignedInt ip = slot->getIP();
- AsciiString tmpUserName;
- tmpUserName.translate(slot->getName());
- if (ip)
- {
- /*
- if (i == 1)
- {
- user.format(",%s@207.138.47.15:8088", tmpUserName.str());
- }
- else
- */
- {
- user.format(",%s@%d.%d.%d.%d:%d", tmpUserName.str(),
- ((ip & 0xff000000) >> 24),
- ((ip & 0xff0000) >> 16),
- ((ip & 0xff00) >> 8),
- ((ip & 0xff)),
- TheNAT->getSlotPort(i)
- );
- }
- userList.concat(user);
- }
- }
- userList.trim();
-
- TheNetwork->parseUserList(TheGameSpyGame);
-
- // shutdown the top, but do not pop it off the stack
-// TheShell->hideShell();
- // setup the Global Data with the Map and Seed
- TheGlobalData->m_pendingFile = TheGameSpyGame->getMap();
-
- if (TheGameLogic->isInGame()) {
- TheGameLogic->clearGameData();
- }
- // send a message to the logic for a new game
- GameMessage *msg = TheMessageStream->appendMessage( GameMessage::MSG_NEW_GAME );
- msg->appendIntegerArgument(GAME_INTERNET);
-
- TheGlobalData->m_useFpsLimit = false;
-
- // Set the random seed
- InitGameLogicRandom( TheGameSpyGame->getSeed() );
- DEBUG_LOG(("InitGameLogicRandom( %d )\n", TheGameSpyGame->getSeed()));
-
- if (TheNAT != NULL) {
- delete TheNAT;
- TheNAT = NULL;
- }
- }
-}
-
-void GameSpyGameInfo::init( void )
-{
- GameInfo::init();
-
- m_hasBeenQueried = false;
-}
-
-void GameSpyGameInfo::resetAccepted( void )
-{
- GameInfo::resetAccepted();
-
- if (m_hasBeenQueried && amIHost())
- {
- // ANCIENTMUNKEE peerStateChanged(TheGameSpyChat->getPeer());
- m_hasBeenQueried = false;
- DEBUG_LOG(("resetAccepted() called peerStateChange()\n"));
- }
-}
-
-Int GameSpyGameInfo::getLocalSlotNum( void ) const
-{
- DEBUG_ASSERTCRASH(m_inGame, ("Looking for local game slot while not in game"));
- if (!m_inGame)
- return -1;
-
- AsciiString localName = TheGameSpyInfo->getLocalName();
-
- for (Int i=0; iisPlayer(localName))
- return i;
- }
- return -1;
-}
-
-void GameSpyGameInfo::gotGOACall( void )
-{
- DEBUG_LOG(("gotGOACall()\n"));
- m_hasBeenQueried = true;
-}
-
-void GameSpyGameInfo::startGame(Int gameID)
-{
- DEBUG_LOG(("GameSpyGameInfo::startGame - game id = %d\n", gameID));
- DEBUG_ASSERTCRASH(m_transport == NULL, ("m_transport is not NULL when it should be"));
- DEBUG_ASSERTCRASH(TheNAT == NULL, ("TheNAT is not NULL when it should be"));
-
- // fill in GS-specific info
- for (Int i=0; igetPlayerInfoMap();
- PlayerInfoMap::iterator it = pInfoMap->find(gsName);
- if (it != pInfoMap->end())
- {
- m_GameSpySlot[i].setProfileID(it->second.m_profileID);
- m_GameSpySlot[i].setLocale(it->second.m_locale);
- }
- else
- {
- DEBUG_CRASH(("No player info for %s", gsName.str()));
- }
- }
- }
-
- if (TheNAT != NULL) {
- delete TheNAT;
- TheNAT = NULL;
- }
- TheNAT = NEW NAT();
- TheNAT->attachSlotList(m_slot, getLocalSlotNum(), m_localIP);
- TheNAT->establishConnectionPaths();
-}
-
-AsciiString GameSpyGameInfo::generateGameResultsPacket( void )
-{
- Int i;
- Int endFrame = TheVictoryConditions->getEndFrame();
- Int localSlotNum = getLocalSlotNum();
- //GameSlot *localSlot = getSlot(localSlotNum);
- Bool sawGameEnd = (endFrame > 0);// && localSlot->lastFrameInGame() <= endFrame);
- Int winningTeam = -1;
- Int numPlayers = 0;
- Int numTeamsAtGameEnd = 0;
- Int lastTeamAtGameEnd = -1;
- for (i=0; ifindPlayerWithNameKey(NAMEKEY(playerName));
- if (p)
- {
- ++numPlayers;
- if (TheVictoryConditions->hasAchievedVictory(p))
- {
- winningTeam = getSlot(i)->getTeamNumber();
- }
-
- // check if he lasted
- GameSlot *slot = getSlot(i);
- if (!slot->disconnected())
- {
- if (slot->getTeamNumber() != lastTeamAtGameEnd || numTeamsAtGameEnd == 0)
- {
- lastTeamAtGameEnd = slot->getTeamNumber();
- ++numTeamsAtGameEnd;
- }
- }
- }
- }
-
- AsciiString results;
- results.format("seed=%d,slotNum=%d,sawDesync=%d,sawGameEnd=%d,winningTeam=%d,disconEnd=%d,duration=%d,numPlayers=%d,isQM=%d",
- getSeed(), localSlotNum, TheNetwork->sawCRCMismatch(), sawGameEnd, winningTeam, (numTeamsAtGameEnd != 0),
- endFrame, numPlayers, m_isQM);
-
- Int playerID = 0;
- for (i=0; ifindPlayerWithNameKey(NAMEKEY(playerName));
- if (p)
- {
- GameSpyGameSlot *slot = &(m_GameSpySlot[i]);
- ScoreKeeper *keeper = p->getScoreKeeper();
- AsciiString playerName = slot->getLoginName();
- Int gsPlayerID = slot->getProfileID();
- AsciiString locale = slot->getLocale();
- Int fps = TheNetwork->getAverageFPS();
- Int unitsKilled = keeper->getTotalUnitsDestroyed();
- Int unitsLost = keeper->getTotalUnitsLost();
- Int unitsBuilt = keeper->getTotalUnitsBuilt();
- Int buildingsKilled = keeper->getTotalBuildingsDestroyed();
- Int buildingsLost = keeper->getTotalBuildingsLost();
- Int buildingsBuilt = keeper->getTotalBuildingsBuilt();
- Int earnings = keeper->getTotalMoneyEarned();
- Int techCaptured = keeper->getTotalTechBuildingsCaptured();
- Bool disconnected = slot->disconnected();
-
- AsciiString playerStr;
- playerStr.format(",player%d=%s,playerID%d=%d,locale%d=%s",
- playerID, playerName.str(), playerID, gsPlayerID, playerID, locale.str());
- results.concat(playerStr);
- playerStr.format(",unitsKilled%d=%d,unitsLost%d=%d,unitsBuilt%d=%d",
- playerID, unitsKilled, playerID, unitsLost, playerID, unitsBuilt);
- results.concat(playerStr);
- playerStr.format(",buildingsKilled%d=%d,buildingsLost%d=%d,buildingsBuilt%d=%d",
- playerID, buildingsKilled, playerID, buildingsLost, playerID, buildingsBuilt);
- results.concat(playerStr);
- playerStr.format(",fps%d=%d,cash%d=%d,capturedTech%d=%d,discon%d=%d",
- playerID, fps, playerID, earnings, playerID, techCaptured, playerID, disconnected);
- results.concat(playerStr);
-
- ++playerID;
- }
- }
-
- // Add a trailing size value (so the server can ensure it got the entire packet)
- int resultsLen = results.getLength()+10;
- AsciiString tail;
- tail.format("%10.10d", resultsLen);
- results.concat(tail);
-
- return results;
-}
-
diff --git a/Generals/Code/GameEngine/Source/GameNetwork/GameSpyOverlay.cpp b/Generals/Code/GameEngine/Source/GameNetwork/GameSpyOverlay.cpp
deleted file mode 100644
index c44709d3d76..00000000000
--- a/Generals/Code/GameEngine/Source/GameNetwork/GameSpyOverlay.cpp
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: wolscreens.cpp //////////////////////////////////////////////////////
-// Westwood Online screen setup/teardown
-// Author: Matthew D. Campbell, November 2001
-
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-#include "Common/AudioEventRTS.h"
-
-#include "GameClient/GadgetListBox.h"
-#include "GameClient/GameText.h"
-#include "GameClient/MessageBox.h"
-#include "GameClient/ShellHooks.h"
-//#include "GameNetwork/GameSpy.h"
-//#include "GameNetwork/GameSpyGP.h"
-
-#include "GameNetwork/GameSpyOverlay.h"
-//#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpy/BuddyThread.h"
-
-void deleteNotificationBox( void );
-static void raiseOverlays( void );
-
-// Message boxes -------------------------------------
-static GameWindow *messageBoxWindow = NULL;
-static GameWinMsgBoxFunc okFunc = NULL;
-static GameWinMsgBoxFunc cancelFunc = NULL;
-static Bool reOpenPlayerInfoFlag = FALSE;
-/**
- * messageBoxOK is called when a message box is destroyed
- * by way of an OK button, so we can clear our pointers to it.
- */
-static void messageBoxOK( void )
-{
- DEBUG_ASSERTCRASH(messageBoxWindow, ("Message box window went away without being there in the first place!"));
- messageBoxWindow = NULL;
- if (okFunc)
- {
- okFunc();
- okFunc = NULL;
- }
-}
-
-/**
- * messageBoxCancel is called when a message box is destroyed
- * by way of a Cancel button, so we can clear our pointers to it.
- */
-static void messageBoxCancel( void )
-{
- DEBUG_ASSERTCRASH(messageBoxWindow, ("Message box window went away without being there in the first place!"));
- messageBoxWindow = NULL;
- if (cancelFunc)
- {
- cancelFunc();
- cancelFunc = NULL;
- }
-}
-
-/**
- * clearGSMessageBoxes removes the current message box if
- * one is present. This is usually done when putting up a
- * second messageBox.
- */
-void ClearGSMessageBoxes( void )
-{
- if (messageBoxWindow)
- {
- TheWindowManager->winDestroy(messageBoxWindow);
- messageBoxWindow = NULL;
- }
-
- if (okFunc)
- {
- okFunc = NULL;
- }
-
- if (cancelFunc)
- {
- cancelFunc = NULL;
- }
-}
-
-/**
- * GSMessageBoxOk puts up an OK dialog box and saves the
- * pointers to it and its callbacks.
- */
-void GSMessageBoxOk(UnicodeString title, UnicodeString message, GameWinMsgBoxFunc newOkFunc)
-{
- ClearGSMessageBoxes();
- messageBoxWindow = MessageBoxOk(title, message, messageBoxOK);
- okFunc = newOkFunc;
-}
-
-/**
- * GSMessageBoxOkCancel puts up an OK/Cancel dialog box and saves the
- * pointers to it and its callbacks.
- */
-void GSMessageBoxOkCancel(UnicodeString title, UnicodeString message, GameWinMsgBoxFunc newOkFunc, GameWinMsgBoxFunc newCancelFunc)
-{
- ClearGSMessageBoxes();
- messageBoxWindow = MessageBoxOkCancel(title, message, messageBoxOK, messageBoxCancel);
- okFunc = newOkFunc;
- cancelFunc = newCancelFunc;
-}
-
-/**
- * GSMessageBoxYesNo puts up a Yes/No dialog box and saves the
- * pointers to it and its callbacks.
- */
-void GSMessageBoxYesNo(UnicodeString title, UnicodeString message, GameWinMsgBoxFunc newYesFunc, GameWinMsgBoxFunc newNoFunc)
-{
- ClearGSMessageBoxes();
- messageBoxWindow = MessageBoxYesNo(title, message, messageBoxOK, messageBoxCancel);
- okFunc = newYesFunc;
- cancelFunc = newNoFunc;
-}
-
-/**
- * If the screen transitions underneath the dialog box, we
- * need to raise it to keep it visible.
- */
-void RaiseGSMessageBox( void )
-{
- raiseOverlays();
-
- if (!messageBoxWindow)
- return;
-
- messageBoxWindow->winBringToTop();
-}
-
-// Overlay screens -------------------------------------
-
-/**
- * gsOverlays holds a list of the .wnd files used in GS overlays.
- * The entries *MUST* be in the same order as the GSOverlayType enum.
- */
-static const char * gsOverlays[GSOVERLAY_MAX] =
-{
- "Menus/PopupPlayerInfo.wnd", // Player info (right-click)
- "Menus/WOLMapSelectMenu.wnd", // Map select
- "Menus/WOLBuddyOverlay.wnd", // Buddy list
- "Menus/WOLPageOverlay.wnd", // Find/page
- "Menus/PopupHostGame.wnd", // Hosting options (game name, password, etc)
- "Menus/PopupJoinGame.wnd", // Joining options (password, etc)
- "Menus/PopupLadderSelect.wnd",// LadderSelect
- "Menus/PopupLocaleSelect.wnd",// Prompt for user's locale
- "Menus/OptionsMenu.wnd", // popup options
-};
-
-static WindowLayout *overlayLayouts[GSOVERLAY_MAX] =
-{
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
-};
-
-static void buddyTryReconnect( void )
-{
- BuddyRequest req;
- req.buddyRequestType = BuddyRequest::BUDDYREQUEST_RELOGIN;
- TheGameSpyBuddyMessageQueue->addRequest( req );
-}
-
-void GameSpyOpenOverlay( GSOverlayType overlay )
-{
- if (overlay == GSOVERLAY_BUDDY)
- {
- if (!TheGameSpyBuddyMessageQueue->isConnected())
- {
- // not connected - is it because we were disconnected?
- if (TheGameSpyBuddyMessageQueue->getLocalProfileID())
- {
- // used to be connected
- GSMessageBoxYesNo(TheGameText->fetch("GUI:GPErrorTitle"), TheGameText->fetch("GUI:GPDisconnected"), buddyTryReconnect, NULL);
- }
- else
- {
- // no profile
- GSMessageBoxOk(TheGameText->fetch("GUI:GPErrorTitle"), TheGameText->fetch("GUI:GPNoProfile"), NULL);
- }
- return;
- }
- AudioEventRTS buttonClick("GUICommunicatorOpen");
-
- if( TheAudio )
- {
- TheAudio->addAudioEvent( &buttonClick );
- } // end if
- }
- if (overlayLayouts[overlay])
- {
- overlayLayouts[overlay]->hide( FALSE );
- overlayLayouts[overlay]->bringForward();
- }
- else
- {
- overlayLayouts[overlay] = TheWindowManager->winCreateLayout( AsciiString( gsOverlays[overlay] ) );
- overlayLayouts[overlay]->runInit();
- overlayLayouts[overlay]->hide( FALSE );
- overlayLayouts[overlay]->bringForward();
- }
-}
-
-void GameSpyCloseOverlay( GSOverlayType overlay )
-{
- switch(overlay)
- {
- case GSOVERLAY_PLAYERINFO:
- DEBUG_LOG(("Closing overlay GSOVERLAY_PLAYERINFO\n"));
- break;
- case GSOVERLAY_MAPSELECT:
- DEBUG_LOG(("Closing overlay GSOVERLAY_MAPSELECT\n"));
- break;
- case GSOVERLAY_BUDDY:
- DEBUG_LOG(("Closing overlay GSOVERLAY_BUDDY\n"));
- break;
- case GSOVERLAY_PAGE:
- DEBUG_LOG(("Closing overlay GSOVERLAY_PAGE\n"));
- break;
- case GSOVERLAY_GAMEOPTIONS:
- DEBUG_LOG(("Closing overlay GSOVERLAY_GAMEOPTIONS\n"));
- break;
- case GSOVERLAY_GAMEPASSWORD:
- DEBUG_LOG(("Closing overlay GSOVERLAY_GAMEPASSWORD\n"));
- break;
- case GSOVERLAY_LADDERSELECT:
- DEBUG_LOG(("Closing overlay GSOVERLAY_LADDERSELECT\n"));
- break;
- case GSOVERLAY_OPTIONS:
- DEBUG_LOG(("Closing overlay GSOVERLAY_OPTIONS\n"));
- if( overlayLayouts[overlay] )
- {
- SignalUIInteraction(SHELL_SCRIPT_HOOK_OPTIONS_CLOSED);
- }
- break;
- }
- if( overlayLayouts[overlay] )
- {
- overlayLayouts[overlay]->runShutdown();
- overlayLayouts[overlay]->destroyWindows();
- overlayLayouts[overlay]->deleteInstance();
- overlayLayouts[overlay] = NULL;
- }
-}
-
-Bool GameSpyIsOverlayOpen( GSOverlayType overlay )
-{
- return (overlayLayouts[overlay] != NULL);
-}
-
-void GameSpyToggleOverlay( GSOverlayType overlay )
-{
- if (GameSpyIsOverlayOpen(overlay))
- GameSpyCloseOverlay(overlay);
- else
- GameSpyOpenOverlay(overlay);
-}
-
-void raiseOverlays( void )
-{
- for (int i=0; ibringForward();
- }
- }
-}
-
-void GameSpyCloseAllOverlays( void )
-{
- for (int i=0; irunUpdate();
- }
- }
-}
-
-void ReOpenPlayerInfo( void )
-{
- reOpenPlayerInfoFlag = TRUE;
-}
-void CheckReOpenPlayerInfo(void )
-{
- if(!reOpenPlayerInfoFlag)
- return;
-
- GameSpyOpenOverlay(GSOVERLAY_PLAYERINFO);
- reOpenPlayerInfoFlag = FALSE;
-
-}
diff --git a/Generals/Code/GameEngine/Source/GameNetwork/GameSpyPersistentStorage.cpp b/Generals/Code/GameEngine/Source/GameNetwork/GameSpyPersistentStorage.cpp
deleted file mode 100644
index 742f9737653..00000000000
--- a/Generals/Code/GameEngine/Source/GameNetwork/GameSpyPersistentStorage.cpp
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: GameSpyPersistentStorage.cpp //////////////////////////////////////////////////////
-// GameSpy Persistent Storage callbacks, utils, etc
-// Author: Matthew D. Campbell, March 2002
-
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "GameSpy/gstats/gpersist.h"
-
-#include "GameClient/Shell.h"
-#include "GameClient/MessageBox.h"
-#include "GameNetwork/GameSpy.h"
-#include "GameNetwork/GameSpyGP.h"
-#include "GameNetwork/GameSpyPersistentStorage.h"
-#include "GameNetwork/GameSpyThread.h"
-
-static Bool isProfileAuthorized = false;
-
-static Bool gameSpyInitPersistentStorageConnection( void );
-static void getPersistentDataCallback(int localid, int profileid, persisttype_t type, int index, int success, char *data, int len, void *instance);
-static void setPersistentDataCallback(int localid, int profileid, persisttype_t type, int index, int success, void *instance);
-
-
-class GameSpyPlayerInfo : public GameSpyPlayerInfoInterface
-{
-public:
- GameSpyPlayerInfo() { m_locale.clear(); m_wins = m_losses = m_operationCount = 0; m_shouldDisconnect = false; }
- virtual ~GameSpyPlayerInfo() { reset(); }
-
- virtual void init( void ) { m_locale.clear(); m_wins = m_losses = m_operationCount = 0; queueDisconnect(); };
- virtual void reset( void ) { m_locale.clear(); m_wins = m_losses = m_operationCount = 0; queueDisconnect(); };
- virtual void update( void );
-
- virtual AsciiString getLocale( void ) { return m_locale; }
- virtual Int getWins( void ) { return m_wins; }
- virtual Int getLosses( void ) { return m_losses; }
-
- virtual void setLocale( AsciiString locale, Bool setOnServer );
- virtual void setWins( Int wins, Bool setOnServer );
- virtual void setLosses( Int losses, Bool setOnServer );
-
- virtual void readFromServer( void );
- virtual void threadReadFromServer( void );
- virtual void threadSetLocale( AsciiString val );
- virtual void threadSetWins ( AsciiString val );
- virtual void threadSetLosses( AsciiString val );
-
- void queueDisconnect( void ) { MutexClass::LockClass m(TheGameSpyMutex); if (IsStatsConnected()) m_shouldDisconnect = true; else m_shouldDisconnect = false; }
-
-private:
- void setValue( AsciiString key, AsciiString val, Bool setOnServer );
-
- AsciiString m_locale;
- Int m_wins;
- Int m_losses;
- Int m_operationCount;
- Bool m_shouldDisconnect;
-};
-
-void GameSpyPlayerInfo::update( void )
-{
- if (IsStatsConnected())
- {
- if (m_shouldDisconnect)
- {
- DEBUG_LOG(("Persistent Storage close\n"));
- CloseStatsConnection();
- }
- else
- {
- PersistThink();
- }
- }
-}
-
-void GameSpyPlayerInfo::readFromServer( void )
-{
- TheGameSpyThread->queueReadPersistentStatsFromServer();
-}
-
-void GameSpyPlayerInfo::threadReadFromServer( void )
-{
- MutexClass::LockClass m(TheGameSpyMutex);
- if (gameSpyInitPersistentStorageConnection())
- {
- // get persistent info
- m_operationCount++;
- DEBUG_LOG(("GameSpyPlayerInfo::readFromServer() operation count = %d\n", m_operationCount));
- GetPersistDataValues(0, TheGameSpyChat->getProfileID(), pd_public_rw, 0, "\\locale\\wins\\losses", getPersistentDataCallback, &m_operationCount);
- }
- else
- {
- //TheGameSpyThread->setNextShellScreen("Menus/WOLWelcomeMenu.wnd");
- //TheShell->pop();
- //TheShell->push("Menus/WOLWelcomeMenu.wnd");
- }
-}
-
-void GameSpyPlayerInfo::setLocale( AsciiString locale, Bool setOnServer )
-{
- m_locale = locale;
-
- if (!TheGameSpyChat->getProfileID() || !setOnServer)
- return;
-
- setValue("locale", m_locale, setOnServer);
-}
-
-void GameSpyPlayerInfo::setWins( Int wins, Bool setOnServer )
-{
- m_wins = wins;
-
- if (!TheGameSpyChat->getProfileID() || !setOnServer)
- return;
-
- AsciiString winStr;
- winStr.format("%d", wins);
-
- setValue("wins", winStr, setOnServer);
-}
-
-void GameSpyPlayerInfo::setLosses( Int losses, Bool setOnServer )
-{
- m_losses = losses;
-
- if (!TheGameSpyChat->getProfileID() || !setOnServer)
- return;
-
- AsciiString lossesStr;
- lossesStr.format("%d", losses);
-
- setValue("losses", lossesStr, setOnServer);
-}
-
-void GameSpyPlayerInfo::setValue( AsciiString key, AsciiString val, Bool setOnServer )
-{
- if (!setOnServer)
- return;
-
- if (key == "locale")
- TheGameSpyThread->queueUpdateLocale(val);
- else if (key == "wins")
- TheGameSpyThread->queueUpdateWins(val);
- else if (key == "losses")
- TheGameSpyThread->queueUpdateLosses(val);
-}
-
-void GameSpyPlayerInfo::threadSetLocale( AsciiString val )
-{
- MutexClass::LockClass m(TheGameSpyMutex);
- if (!gameSpyInitPersistentStorageConnection())
- return;
-
- // set locale info
- AsciiString key = "locale";
- AsciiString str;
- str.format("\\%s\\%s", key.str(), val.str());
- char *writable = strdup(str.str());
- m_operationCount++;
- DEBUG_LOG(("GameSpyPlayerInfo::set%s() operation count = %d\n", key.str(), m_operationCount));
- SetPersistDataValues(0, TheGameSpyChat->getProfileID(), pd_public_rw, 0, writable, setPersistentDataCallback, &m_operationCount);
- free(writable);
-}
-
-void GameSpyPlayerInfo::threadSetWins( AsciiString val )
-{
- MutexClass::LockClass m(TheGameSpyMutex);
- if (!gameSpyInitPersistentStorageConnection())
- return;
-
- // set win info
- AsciiString key = "wins";
- AsciiString str;
- str.format("\\%s\\%s", key.str(), val.str());
- char *writable = strdup(str.str());
- m_operationCount++;
- DEBUG_LOG(("GameSpyPlayerInfo::set%s() operation count = %d\n", key.str(), m_operationCount));
- SetPersistDataValues(0, TheGameSpyChat->getProfileID(), pd_public_rw, 0, writable, setPersistentDataCallback, &m_operationCount);
- free(writable);
-}
-
-void GameSpyPlayerInfo::threadSetLosses( AsciiString val )
-{
- MutexClass::LockClass m(TheGameSpyMutex);
- if (!gameSpyInitPersistentStorageConnection())
- return;
-
- // set loss info
- AsciiString key = "losses";
- AsciiString str;
- str.format("\\%s\\%s", key.str(), val.str());
- char *writable = strdup(str.str());
- m_operationCount++;
- DEBUG_LOG(("GameSpyPlayerInfo::set%s() operation count = %d\n", key.str(), m_operationCount));
- SetPersistDataValues(0, TheGameSpyChat->getProfileID(), pd_public_rw, 0, writable, setPersistentDataCallback, &m_operationCount);
- free(writable);
-}
-
-GameSpyPlayerInfoInterface *TheGameSpyPlayerInfo = NULL;
-
-GameSpyPlayerInfoInterface *createGameSpyPlayerInfo( void )
-{
- return NEW GameSpyPlayerInfo;
-}
-
-
-
-
-
-
-
-
-
-static void persAuthCallback(int localid, int profileid, int authenticated, char *errmsg, void *instance)
-{
- DEBUG_LOG(("Auth callback: localid: %d profileid: %d auth: %d err: %s\n",localid, profileid, authenticated, errmsg));
- isProfileAuthorized = (authenticated != 0);
-}
-
-static void getPersistentDataCallback(int localid, int profileid, persisttype_t type, int index, int success, char *data, int len, void *instance)
-{
- DEBUG_LOG(("Data get callback: localid: %d profileid: %d success: %d len: %d data: %s\n",localid, profileid, success, len, data));
-
- if (!TheGameSpyPlayerInfo)
- {
- //TheGameSpyThread->setNextShellScreen("Menus/WOLWelcomeMenu.wnd");
- //TheShell->pop();
- //TheShell->push("Menus/WOLWelcomeMenu.wnd");
- return;
- }
-
- AsciiString str = data;
- AsciiString key, val;
- while (!str.isEmpty())
- {
- str.nextToken(&key, "\\");
- str.nextToken(&val, "\\");
- if (!key.isEmpty() && !val.isEmpty())
- {
- if (!key.compareNoCase("locale"))
- {
- TheGameSpyPlayerInfo->setLocale(val, false);
- }
- else if (!key.compareNoCase("wins"))
- {
- TheGameSpyPlayerInfo->setWins(atoi(val.str()), false);
- }
- else if (!key.compareNoCase("losses"))
- {
- TheGameSpyPlayerInfo->setLosses(atoi(val.str()), false);
- }
- }
- }
-
- // decrement count of active operations
- Int *opCount = (Int *)instance;
- (*opCount) --;
- DEBUG_LOG(("getPersistentDataCallback() operation count = %d\n", (*opCount)));
- if (!*opCount)
- {
- DEBUG_LOG(("getPersistentDataCallback() queue disconnect\n"));
- ((GameSpyPlayerInfo *)TheGameSpyPlayerInfo)->queueDisconnect();
- }
-
- const char *keys[3] = { "locale", "wins", "losses" };
- char valueStrings[3][20];
- char *values[3] = { valueStrings[0], valueStrings[1], valueStrings[2] };
- _snprintf(values[0], 20, "%s", TheGameSpyPlayerInfo->getLocale().str());
- _snprintf(values[1], 20, "%d", TheGameSpyPlayerInfo->getWins());
- _snprintf(values[2], 20, "%d", TheGameSpyPlayerInfo->getLosses());
- peerSetGlobalKeys(TheGameSpyChat->getPeer(), 3, (const char **)keys, (const char **)values);
- peerSetGlobalWatchKeys(TheGameSpyChat->getPeer(), GroupRoom, 3, keys, PEERTrue);
- peerSetGlobalWatchKeys(TheGameSpyChat->getPeer(), StagingRoom, 3, keys, PEERTrue);
-
- // choose next screen
- if (TheGameSpyPlayerInfo->getLocale().isEmpty())
- {
- TheGameSpyThread->setShowLocaleSelect(true);
- }
-}
-
-static void setPersistentDataCallback(int localid, int profileid, persisttype_t type, int index, int success, void *instance)
-{
- DEBUG_LOG(("Data save callback: localid: %d profileid: %d success: %d\n", localid, profileid, success));
-
- Int *opCount = (Int *)instance;
- (*opCount) --;
- DEBUG_LOG(("setPersistentDataCallback() operation count = %d\n", (*opCount)));
- if (!*opCount)
- {
- DEBUG_LOG(("setPersistentDataCallback() queue disconnect\n"));
- ((GameSpyPlayerInfo *)TheGameSpyPlayerInfo)->queueDisconnect();
- }
-}
-
-static Bool gameSpyInitPersistentStorageConnection( void )
-{
- if (IsStatsConnected())
- return true;
-
- isProfileAuthorized = false;
- Int result;
-
- /*********
- First step, set our game authentication info
- We could do:
- strcpy(gcd_gamename,"gmtest");
- strcpy(gcd_secret_key,"HA6zkS");
- ...but this is more secure:
- **********/
- gcd_gamename[0]='g';gcd_gamename[1]='m';gcd_gamename[2]='t';gcd_gamename[3]='e';
- gcd_gamename[4]='s';gcd_gamename[5]='t';gcd_gamename[6]='\0';
- gcd_secret_key[0]='H';gcd_secret_key[1]='A';gcd_secret_key[2]='6';gcd_secret_key[3]='z';
- gcd_secret_key[4]='k';gcd_secret_key[5]='S';gcd_secret_key[6]='\0';
-
- /*********
- Next, open the stats connection. This may block for
- a 1-2 seconds, so it should be done before the actual game starts.
- **********/
- result = InitStatsConnection(0);
-
- if (result != GE_NOERROR)
- {
- DEBUG_LOG(("InitStatsConnection returned %d\n",result));
- return isProfileAuthorized;
- }
-
- if (TheGameSpyChat->getProfileID())
- {
- char validate[33];
-
- /***********
- We'll go ahead and start the authentication, using a Presence & Messaging SDK
- profileid / password. To generate the new validation token, we'll need to pass
- in the password for the profile we are authenticating.
- Again, if this is done in a client/server setting, with the Persistent Storage
- access being done on the server, and the P&M SDK is used on the client, the
- server will need to send the challenge (GetChallenge(NULL)) to the client, the
- client will create the validation token using GenerateAuth, and send it
- back to the server for use in PreAuthenticatePlayerPM
- ***********/
- char *munkeeHack = strdup(TheGameSpyChat->getPassword().str()); // GenerateAuth takes a char*, not a const char* :P
- GenerateAuth(GetChallenge(NULL), munkeeHack, validate);
- free (munkeeHack);
-
- /************
- After we get the validation token, we pass it and the profileid of the user
- we are authenticating into PreAuthenticatePlayerPM.
- We pass the same authentication callback as for the first user, but a different
- localid this time.
- ************/
- PreAuthenticatePlayerPM(0, TheGameSpyChat->getProfileID(), validate, persAuthCallback, NULL);
- }
- else
- {
- return isProfileAuthorized;
- }
-
- UnsignedInt timeoutTime = timeGetTime() + 5000;
- while (!isProfileAuthorized && timeGetTime() < timeoutTime && IsStatsConnected())
- {
- PersistThink();
- msleep(10);
- }
-
- DEBUG_LOG(("Persistent Storage connect: %d\n", isProfileAuthorized));
- return isProfileAuthorized;
-}
-
diff --git a/Generals/Code/GameEngine/Source/GameNetwork/NAT.cpp b/Generals/Code/GameEngine/Source/GameNetwork/NAT.cpp
deleted file mode 100644
index 7ed1f134e25..00000000000
--- a/Generals/Code/GameEngine/Source/GameNetwork/NAT.cpp
+++ /dev/null
@@ -1,1325 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: NAT.cpp /////////////////////////////////////////////////////////////////////////////////
-// Author: Bryan Cleveland April 2002
-// Props to Steve Tall for figuring all the NAT and Firewall behavior patterns out, making my job
-// a LOT easier.
-// Desc: Resolves NAT'd IPs and port numbers for the other players in a game.
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "GameNetwork/NAT.h"
-#include "GameNetwork/Transport.h"
-#include "GameNetwork/NetworkDefs.h"
-#include "GameClient/EstablishConnectionsMenu.h"
-#include "GameNetwork/NetworkInterface.h"
-#include "GameNetwork/GameInfo.h"
-#include "GameNetwork/GameSpy/PeerThread.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpy/PersistentStorageThread.h"
-#include "GameNetwork/GameSpy/GSConfig.h"
-
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-
-/*
- * In case you're wondering, we do this weird connection pairing scheme
- * to speed up the negotiation process, especially in cases where there
- * are 4 or more players (nodes). Take for example an 8 player game...
- * In an 8 player game there are 28 connections that need to be negotiated,
- * doing this pairing scheme thing, we can make those 28 connections in the
- * time it would normally take to make 7 connections. Since each connection
- * could potentially take several seconds, this can be a HUGE time savings.
-
- * Right now you're probably wondering who this Bryan Cleveland guy is.
- * He's the network coder that got fired when this didn't work.
-
- * In case you're wondering, this did end up working and Bryan left by
- * his own choice.
- */
-// m_connectionPairs[num nodes] [round] [node index]
-/* static */ Int NAT::m_connectionPairs[MAX_SLOTS-1][MAX_SLOTS-1][MAX_SLOTS] =
-{
- { // 2 nodes
- // node 0 node 1 node 2 node 3 node 4 node 5 node 6 node 7
- { 1, 0, -1, -1, -1, -1, -1, -1}, // round 0
- { -1, -1, -1, -1, -1, -1, -1, -1}, // round 1
- { -1, -1, -1, -1, -1, -1, -1, -1}, // round 2
- { -1, -1, -1, -1, -1, -1, -1, -1}, // round 3
- { -1, -1, -1, -1, -1, -1, -1, -1}, // round 4
- { -1, -1, -1, -1, -1, -1, -1, -1}, // round 5
- { -1, -1, -1, -1, -1, -1, -1, -1} // round 6
- },
- { // 3 nodes
- // node 0 node 1 node 2 node 3 node 4 node 5 node 6 node 7
- { 1, 0, -1, -1, -1, -1, -1, -1}, // round 0
- { 2, -1, 0, -1, -1, -1, -1, -1}, // round 1
- { -1, 2, 1, -1, -1, -1, -1, -1}, // round 2
- { -1, -1, -1, -1, -1, -1, -1, -1}, // round 3
- { -1, -1, -1, -1, -1, -1, -1, -1}, // round 4
- { -1, -1, -1, -1, -1, -1, -1, -1}, // round 5
- { -1, -1, -1, -1, -1, -1, -1, -1} // round 6
- },
- { // 4 nodes
- // node 0 node 1 node 2 node 3 node 4 node 5 node 6 node 7
- { 1, 0, 3, 2, -1, -1, -1, -1}, // round 0
- { 2, 3, 0, 1, -1, -1, -1, -1}, // round 1
- { 3, 2, 1, 0, -1, -1, -1, -1}, // round 2
- { -1, -1, -1, -1, -1, -1, -1, -1}, // round 3
- { -1, -1, -1, -1, -1, -1, -1, -1}, // round 4
- { -1, -1, -1, -1, -1, -1, -1, -1}, // round 5
- { -1, -1, -1, -1, -1, -1, -1, -1} // round 6
- },
- { // 5 nodes
- // node 0 node 1 node 2 node 3 node 4 node 5 node 6 node 7
- { 2, 4, 0, -1, 1, -1, -1, -1}, // round 0
- { -1, 3, 4, 1, 2, -1, -1, -1}, // round 1
- { 3, 2, 1, 0, -1, -1, -1, -1}, // round 2
- { 4, -1, 3, 2, 0, -1, -1, -1}, // round 3
- { 1, 0, -1, 4, 3, -1, -1, -1}, // round 4
- { -1, -1, -1, -1, -1, -1, -1, -1}, // round 5
- { -1, -1, -1, -1, -1, -1, -1, -1} // round 6
- },
- { // 6 nodes
- // node 0 node 1 node 2 node 3 node 4 node 5 node 6 node 7
- { 3, 5, 4, 0, 2, 1, -1, -1}, // round 0
- { 2, 4, 0, 5, 1, 3, -1, -1}, // round 1
- { 4, 3, 5, 1, 0, 2, -1, -1}, // round 2
- { 1, 0, 3, 2, 5, 4, -1, -1}, // round 3
- { 5, 2, 1, 4, 3, 0, -1, -1}, // round 4
- { -1, -1, -1, -1, -1, -1, -1, -1}, // round 5
- { -1, -1, -1, -1, -1, -1, -1, -1} // round 6
- },
- { // 7 nodes
- // node 0 node 1 node 2 node 3 node 4 node 5 node 6 node 7
- { -1, 6, 5, 4, 3, 2, 1, -1}, // round 0
- { 2, -1, 0, 6, 5, 4, 3, -1}, // round 1
- { 4, 3, -1, 1, 0, 6, 5, -1}, // round 2
- { 6, 5, 4, -1, 2, 1, 0, -1}, // round 3
- { 1, 0, 6, 5, -1, 3, 2, -1}, // round 4
- { 3, 2, 1, 0, 6, -1, 4, -1}, // round 5
- { 5, 4, 3, 2, 1, 0, -1, -1} // round 6
- },
- { // 8 nodes
- // node 0 node 1 node 2 node 3 node 4 node 5 node 6 node 7
- { 4, 5, 6, 7, 0, 1, 2, 3}, // round 0
- { 5, 4, 7, 6, 1, 0, 3, 2}, // round 1
- { 3, 6, 5, 0, 7, 2, 1, 4}, // round 2
- { 2, 7, 0, 5, 6, 3, 4, 1}, // round 3
- { 6, 3, 4, 1, 2, 7, 0, 5}, // round 4
- { 1, 0, 3, 2, 5, 4, 7, 6}, // round 5
- { 7, 2, 1, 4, 3, 6, 5, 0} // round 6
- }
-};
-
-/* static */ Int NAT::m_timeBetweenRetries = 500; // .5 seconds between retries sounds good to me.
-/* static */ time_t NAT::m_manglerRetryTimeInterval = 300; // sounds good to me.
-/* static */ Int NAT::m_maxAllowedManglerRetries = 25; // works for me.
-/* static */ time_t NAT::m_keepaliveInterval = 15000; // 15 seconds between keepalive packets seems good.
-/* static */ time_t NAT::m_timeToWaitForPort = 15000; // wait for 15 seconds for the other player's port number.
-/* static */ time_t NAT::m_timeForRoundTimeout = 15000; // wait for at most 15 seconds for each connection round to finish.
-
-NAT *TheNAT = NULL;
-
-NAT::NAT()
-{
- //Added By Sadullah Nader
- //Initializations inserted
- m_beenProbed = FALSE;
- m_connectionPairIndex = 0;
- m_connectionRound = 0;
- m_localIP = 0;
- m_localNodeNumber = 0;
- m_manglerAddress = 0;
- m_manglerRetries = 0;
- m_numNodes = 0;
- m_numRetries = 0;
- m_previousSourcePort = 0;
- for(Int i = 0; i < MAX_SLOTS; i++)
- m_sourcePorts[i] = 0;
- m_spareSocketPort = 0;
- m_startingPortNumber = 0;
- m_targetNodeNumber = 0;
- //
- m_transport = NULL;
- m_slotList = NULL;
- m_roundTimeout = 0;
-
- m_maxNumRetriesAllowed = 10;
- m_packetID = 0x7f00;
-}
-
-NAT::~NAT() {
-}
-
-// if we're already finished, change to being idle
-// if we are negotiating now, check to see if this round is done
-// if it is, check to see if we're completely done with all rounds.
-// if we are, set state to be done.
-// if not go on to the next connection round.
-// if we are negotiating still, call the connection update
-// check to see if this connection is done for us, or if it has failed.
-enum { MS_TO_WAIT_FOR_STATS = 5000 };
-NATStateType NAT::update() {
- static UnsignedInt s_startStatWaitTime = 0;
- if (m_NATState == NATSTATE_DONE) {
- m_NATState = NATSTATE_IDLE;
- } else if (m_NATState == NATSTATE_WAITFORSTATS) {
- // check for all stats
- Bool gotAllStats = TRUE;
- Bool timedOut = FALSE;
- for (Int i=0; igetGameSpySlot(i);
- if (slot && slot->isHuman())
- {
- PSPlayerStats stats = TheGameSpyPSMessageQueue->findPlayerStatsByID(slot->getProfileID());
- if (stats.id == 0)
- {
- gotAllStats = FALSE;
- //DEBUG_LOG(("Failed to find stats for %ls(%d)\n", slot->getName().str(), slot->getProfileID()));
- }
- }
- }
- // check for timeout. Timing out is not a fatal error - it just means we didn't get the other
- // player's stats. We'll see 0/0 as his record, but we can still play him just fine.
- UnsignedInt now = timeGetTime();
- if (now > s_startStatWaitTime + MS_TO_WAIT_FOR_STATS)
- {
- DEBUG_LOG(("Timed out waiting for stats. Let's just start the dang game.\n"));
- timedOut = TRUE;
- }
- if (gotAllStats || timedOut)
- {
- m_NATState = NATSTATE_DONE;
- TheEstablishConnectionsMenu->endMenu();
- if (TheFirewallHelper != NULL) {
- delete TheFirewallHelper;
- TheFirewallHelper = NULL;
- }
- }
- } else if (m_NATState == NATSTATE_DOCONNECTIONPATHS) {
- if (allConnectionsDoneThisRound() == TRUE) {
- // we finished this round, move on to the next one.
- ++m_connectionRound;
-// m_roundTimeout = timeGetTime() + TheGameSpyConfig->getRoundTimeout();
- m_roundTimeout = timeGetTime() + m_timeForRoundTimeout;
- DEBUG_LOG(("NAT::update - done with connection round, moving on to round %d\n", m_connectionRound));
-
- // we finished that round, now check to see if we're done, or if there are more rounds to go.
- if (allConnectionsDone() == TRUE) {
- // we're all done, time to go back home.
- m_NATState = NATSTATE_WAITFORSTATS;
-
- // 2/19/03 BGC - we have successfully negotaited a NAT thingy, so our behavior must be correct
- // so therefore we don't need to refresh our NAT even if we previously thought we had to.
- TheFirewallHelper->flagNeedToRefresh(FALSE);
-
- s_startStatWaitTime = timeGetTime();
- DEBUG_LOG(("NAT::update - done with all connections, woohoo!!\n"));
- /*
- m_NATState = NATSTATE_DONE;
- TheEstablishConnectionsMenu->endMenu();
- if (TheFirewallHelper != NULL) {
- delete TheFirewallHelper;
- TheFirewallHelper = NULL;
- }
- */
- } else {
- doThisConnectionRound();
- }
- }
- NATConnectionState state = connectionUpdate();
-
- if (timeGetTime() > m_roundTimeout) {
- DEBUG_LOG(("NAT::update - round timeout expired\n"));
- setConnectionState(m_localNodeNumber, NATCONNECTIONSTATE_FAILED);
- notifyUsersOfConnectionFailed(m_localNodeNumber);
- }
-
- if (state == NATCONNECTIONSTATE_FAILED) {
- // if we fail
- m_NATState = NATSTATE_FAILED;
- TheEstablishConnectionsMenu->endMenu();
- if (TheFirewallHelper != NULL) {
- // we failed NAT negotiation, perhaps we need to redetect our firewall settings.
- // We don't trust the user to do it for themselves so we force them to do it next time
- // the log in.
- // 2/19/03 - ok, we don't want to do this right away, if the user tries to play in another game
- // before they log out and log back in the game won't have a chance at working.
- // so we need to simply flag it so that when they log out the firewall behavior gets blown away.
- TheFirewallHelper->flagNeedToRefresh(TRUE);
-// TheWritableGlobalData->m_firewallBehavior = FirewallHelperClass::FIREWALL_TYPE_UNKNOWN;
-// TheFirewallHelper->writeFirewallBehavior();
-
- delete TheFirewallHelper;
- TheFirewallHelper = NULL;
- }
- // we failed to connect, so we don't have to pass on the transport to the network.
- if (m_transport != NULL) {
- delete m_transport;
- m_transport = NULL;
- }
- }
- }
- return m_NATState;
-}
-
-
-// update transport, check for PROBE packets from our target.
-// check to see if its time to PROBE our target
-// MANGLER:
-// if we are talking to the mangler, check to see if we got a response
-// if we didn't get a response, check to see if its time to send another packet to it
-NATConnectionState NAT::connectionUpdate() {
-
- GameSlot *targetSlot = NULL;
- if (m_targetNodeNumber >= 0) {
- targetSlot = m_slotList[m_connectionNodes[m_targetNodeNumber].m_slotIndex];
- } else {
- return m_connectionStates[m_localNodeNumber];
- }
-
- if (m_beenProbed == FALSE) {
- if (timeGetTime() >= m_nextPortSendTime) {
-// sendMangledPortNumberToTarget(m_previousSourcePort, targetSlot);
- sendMangledPortNumberToTarget(m_sourcePorts[m_targetNodeNumber], targetSlot);
-// m_nextPortSendTime = timeGetTime() + TheGameSpyConfig->getRetryInterval();
- m_nextPortSendTime = timeGetTime() + m_timeBetweenRetries;
- }
- }
-
- // check to see if its time to send out our keepalives.
- if (timeGetTime() >= m_nextKeepaliveTime) {
- for (Int node = 0; node < m_numNodes; ++node) {
- if (m_myConnections[node] == TRUE) {
- // we've made this connection, send a keepalive.
- Int slotIndex = m_connectionNodes[node].m_slotIndex;
- GameSlot *slot = m_slotList[slotIndex];
- DEBUG_ASSERTCRASH(slot != NULL, ("Trying to send keepalive to a NULL slot"));
- if (slot != NULL) {
- UnsignedInt ip = slot->getIP();
- DEBUG_LOG(("NAT::connectionUpdate - sending keep alive to node %d at %d.%d.%d.%d:%d\n", node,
- ip >> 24, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff, slot->getPort()));
- m_transport->queueSend(ip, slot->getPort(), (const unsigned char *)"KEEPALIVE", strlen("KEEPALIVE") + 1);
- }
- }
- }
-// m_nextKeepaliveTime = timeGetTime() + TheGameSpyConfig->getKeepaliveInterval();
- m_nextKeepaliveTime = timeGetTime() + m_keepaliveInterval;
- }
-
- m_transport->update();
-
- // check to see if we've been probed.
- for (Int i = 0; i < MAX_MESSAGES; ++i) {
- if (m_transport->m_inBuffer[i].length > 0) {
-#ifdef DEBUG_LOGGING
- UnsignedInt ip = m_transport->m_inBuffer[i].addr;
-#endif
- DEBUG_LOG(("NAT::connectionUpdate - got a packet from %d.%d.%d.%d:%d, length = %d\n",
- ip >> 24, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff, m_transport->m_inBuffer[i].port, m_transport->m_inBuffer[i].length));
- UnsignedByte *data = m_transport->m_inBuffer[i].data;
- if (memcmp(data, "PROBE", strlen("PROBE")) == 0) {
- Int fromNode = atoi((char *)data + strlen("PROBE"));
- DEBUG_LOG(("NAT::connectionUpdate - we've been probed by node %d.\n", fromNode));
-
- if (fromNode == m_targetNodeNumber) {
- DEBUG_LOG(("NAT::connectionUpdate - probe was sent by our target, setting connection state %d to done.\n", m_targetNodeNumber));
- setConnectionState(m_targetNodeNumber, NATCONNECTIONSTATE_DONE);
-
- if (m_transport->m_inBuffer[i].addr != targetSlot->getIP()) {
- UnsignedInt fromIP = m_transport->m_inBuffer[i].addr;
-#ifdef DEBUG_LOGGING
- UnsignedInt slotIP = targetSlot->getIP();
-#endif
- DEBUG_LOG(("NAT::connectionUpdate - incomming packet has different from address than we expected, incoming: %d.%d.%d.%d expected: %d.%d.%d.%d\n",
- fromIP >> 24, (fromIP >> 16) & 0xff, (fromIP >> 8) & 0xff, fromIP & 0xff,
- slotIP >> 24, (slotIP >> 16) & 0xff, (slotIP >> 8) & 0xff, slotIP & 0xff));
- targetSlot->setIP(fromIP);
- }
- if (m_transport->m_inBuffer[i].port != targetSlot->getPort()) {
- DEBUG_LOG(("NAT::connectionUpdate - incoming packet came from a different port than we expected, incoming: %d expected: %d\n",
- m_transport->m_inBuffer[i].port, targetSlot->getPort()));
- targetSlot->setPort(m_transport->m_inBuffer[i].port);
- m_sourcePorts[m_targetNodeNumber] = m_transport->m_inBuffer[i].port;
- }
- notifyUsersOfConnectionDone(m_targetNodeNumber);
- }
-
- m_transport->m_inBuffer[i].length = 0;
- }
- if (memcmp(data, "KEEPALIVE", strlen("KEEPALIVE")) == 0) {
- // keep alive packet, just toss it.
- DEBUG_LOG(("NAT::connectionUpdate - got keepalive from %d.%d.%d.%d:%d\n",
- ip >> 24, (ip >> 16) & 0xff, (ip >> 8) && 0xff, ip & 0xff, m_transport->m_inBuffer[i].port));
- m_transport->m_inBuffer[i].length = 0;
- }
- }
- }
-
- // we are waiting for our target to tell us that they have received our probe.
- if (m_connectionStates[m_localNodeNumber] == NATCONNECTIONSTATE_WAITINGFORRESPONSE) {
- // check to see if it's time to probe our target.
- if ((m_timeTillNextSend != -1) && (m_timeTillNextSend <= timeGetTime())) {
- if (m_numRetries > m_maxNumRetriesAllowed) {
- DEBUG_LOG(("NAT::connectionUpdate - too many retries, connection failed.\n"));
- setConnectionState(m_localNodeNumber, NATCONNECTIONSTATE_FAILED);
-
- notifyUsersOfConnectionFailed(m_localNodeNumber);
- } else {
- DEBUG_LOG(("NAT::connectionUpdate - trying to send another probe (#%d) to our target\n", m_numRetries+1));
- // Send a probe.
- sendAProbe(targetSlot->getIP(), targetSlot->getPort(), m_localNodeNumber);
-// m_timeTillNextSend = timeGetTime() + TheGameSpyConfig->getRetryInterval();
- m_timeTillNextSend = timeGetTime() + m_timeBetweenRetries;
-
- // tell the target they've been probed. In other words, our port is open.
- notifyTargetOfProbe(targetSlot);
-
- ++m_numRetries;
- }
- }
- }
-
- // we are waiting for a response from the mangler to tell us what port we're using.
- if (m_connectionStates[m_localNodeNumber] == NATCONNECTIONSTATE_WAITINGFORMANGLERRESPONSE) {
- UnsignedShort mangledPort = 0;
- if (TheFirewallHelper != NULL) {
- mangledPort = TheFirewallHelper->getManglerResponse(m_packetID);
- }
- if (mangledPort != 0) {
- // we got a response. now we need to start probing (unless of course we have a netgear)
- processManglerResponse(mangledPort);
-
- // we know there is a firewall helper if we got here.
- TheFirewallHelper->closeSpareSocket(m_spareSocketPort);
- m_spareSocketPort = 0;
- } else {
- if (timeGetTime() >= m_manglerRetryTime) {
- ++m_manglerRetries;
-// if (m_manglerRetries > TheGameSpyConfig->getMaxManglerRetries()) {
- if (m_manglerRetries > m_maxAllowedManglerRetries) {
- // we couldn't communicate with the mangler, just use our non-mangled
- // port number and hope that works.
- DEBUG_LOG(("NAT::connectionUpdate - couldn't talk with the mangler using default port number\n"));
- sendMangledPortNumberToTarget(getSlotPort(m_connectionNodes[m_localNodeNumber].m_slotIndex), targetSlot);
- m_sourcePorts[m_targetNodeNumber] = getSlotPort(m_connectionNodes[m_localNodeNumber].m_slotIndex);
- setConnectionState(m_localNodeNumber, NATCONNECTIONSTATE_WAITINGFORRESPONSE);
- } else {
- if (TheFirewallHelper != NULL) {
- DEBUG_LOG(("NAT::connectionUpdate - trying to send to the mangler again. mangler address: %d.%d.%d.%d, from port: %d, packet ID:%d\n",
- m_manglerAddress >> 24, (m_manglerAddress >> 16) & 0xff, (m_manglerAddress >> 8) & 0xff, m_manglerAddress & 0xff, m_spareSocketPort, m_packetID));
- TheFirewallHelper->sendToManglerFromPort(m_manglerAddress, m_spareSocketPort, m_packetID);
- }
-// m_manglerRetryTime = TheGameSpyConfig->getRetryInterval() + timeGetTime();
- m_manglerRetryTime = m_manglerRetryTimeInterval + timeGetTime();
- }
- }
- }
- }
-
- if (m_connectionStates[m_localNodeNumber] == NATCONNECTIONSTATE_WAITINGFORMANGLEDPORT) {
- if (timeGetTime() > m_timeoutTime) {
- DEBUG_LOG(("NAT::connectionUpdate - waiting too long to get the other player's port number, failed.\n"));
- setConnectionState(m_localNodeNumber, NATCONNECTIONSTATE_FAILED);
-
- notifyUsersOfConnectionFailed(m_localNodeNumber);
- }
- }
-
- return m_connectionStates[m_localNodeNumber];
-}
-
-// this is the function that starts the NAT/firewall negotiation process.
-// after calling this, you should call the update function untill it returns
-// NATSTATE_DONE.
-void NAT::establishConnectionPaths() {
- DEBUG_LOG(("NAT::establishConnectionPaths - entering\n"));
- m_NATState = NATSTATE_DOCONNECTIONPATHS;
- DEBUG_LOG(("NAT::establishConnectionPaths - using %d as our starting port number\n", m_startingPortNumber));
- if (TheEstablishConnectionsMenu == NULL) {
- TheEstablishConnectionsMenu = NEW EstablishConnectionsMenu;
- }
- TheEstablishConnectionsMenu->initMenu();
-
- if (TheFirewallHelper == NULL) {
- TheFirewallHelper = createFirewallHelper();
- }
-
- DEBUG_ASSERTCRASH(m_slotList != NULL, ("NAT::establishConnectionPaths - don't have a slot list"));
- if (m_slotList == NULL) {
- return;
- }
-
- // determine how many nodes we have.
- m_numNodes = 0;
- for (Int i = 0; i < MAX_SLOTS; ++i) {
- if (m_slotList[i] != NULL) {
- if (m_slotList[i]->isHuman()) {
- DEBUG_LOG(("NAT::establishConnectionPaths - slot %d is %ls\n", i, m_slotList[i]->getName().str()));
- ++m_numNodes;
- }
- }
- }
- DEBUG_LOG(("NAT::establishConnectionPaths - number of nodes: %d\n", m_numNodes));
-
- if (m_numNodes < 2)
- {
- // just start the game - there isn't anybody to which to connect. :P
- m_NATState = NATSTATE_DONE;
- return;
- }
-
- m_connectionRound = 0;
- m_connectionPairIndex = m_numNodes - 2;
- Bool connectionAssigned[MAX_SLOTS];
-
- for (i = 0; i < MAX_SLOTS; ++i) {
- m_connectionNodes[i].m_slotIndex = -1;
- connectionAssigned[i] = FALSE;
- m_sourcePorts[i] = 0;
- }
-
- m_previousSourcePort = 0;
-
-// check for netgear bug behavior.
-// as an aside, if there are more than 2 netgear bug firewall's in the game,
-// it probably isn't going to work so well. stupid netgear.
-
-// nodes with a netgear bug behavior need to be matched up first. This prevents
-// the NAT table from being reset for connections to other nodes. This also happens
-// to be the reason why I call them "nodes" rather than "slots" or "players" as the
-// ordering has to be messed with to get the netgears to make love, not war.
- DEBUG_LOG(("NAT::establishConnectionPaths - about to set up the node list\n"));
- DEBUG_LOG(("NAT::establishConnectionPaths - doing the netgear stuff\n"));
- UnsignedInt otherNetgearNum = -1;
- for (i = 0; i < MAX_SLOTS; ++i) {
- if ((m_slotList != NULL) && (m_slotList[i] != NULL)) {
- if ((m_slotList[i]->getNATBehavior() & FirewallHelperClass::FIREWALL_TYPE_NETGEAR_BUG) != 0) {
- if (otherNetgearNum == -1) {
- // this is the start of a new pair, put it in as the first non -1 node connection pair thing.
- Int nodeindex = 0;
- while ((m_connectionPairs[m_connectionPairIndex][0][nodeindex] == -1) || (m_connectionNodes[nodeindex].m_slotIndex != -1)) {
- ++nodeindex;
- }
- m_connectionNodes[nodeindex].m_slotIndex = i;
- m_connectionNodes[nodeindex].m_behavior = m_slotList[i]->getNATBehavior();
- connectionAssigned[i] = TRUE;
- otherNetgearNum = nodeindex;
- DEBUG_LOG(("NAT::establishConnectionPaths - first netgear in pair. assigning node %d to slot %d (%ls)\n", nodeindex, i, m_slotList[i]->getName().str()));
- } else {
- // this is the second in the pair of netgears, pair this up with the other one
- // for the first round.
- Int nodeindex = 0;
- while (m_connectionPairs[m_connectionPairIndex][0][nodeindex] != otherNetgearNum) {
- ++nodeindex;
- }
- m_connectionNodes[nodeindex].m_slotIndex = i;
- m_connectionNodes[nodeindex].m_behavior = m_slotList[i]->getNATBehavior();
- connectionAssigned[i] = TRUE;
- otherNetgearNum = -1;
- DEBUG_LOG(("NAT::establishConnectionPaths - second netgear in pair. assigning node %d to slot %d (%ls)\n", nodeindex, i, m_slotList[i]->getName().str()));
- }
- }
- }
- }
-
- // fill in the rest of the nodes with the remaining slots.
- DEBUG_LOG(("NAT::establishConnectionPaths - doing the non-Netgear nodes\n"));
- for (i = 0; i < MAX_SLOTS; ++i) {
- if (connectionAssigned[i] == TRUE) {
- continue;
- }
- if (m_slotList[i] == NULL) {
- continue;
- }
- if (!(m_slotList[i]->isHuman())) {
- continue;
- }
- // find the first available connection node for this slot.
- Int nodeindex = 0;
- while (m_connectionNodes[nodeindex].m_slotIndex != -1) {
- ++nodeindex;
- }
- DEBUG_LOG(("NAT::establishConnectionPaths - assigning node %d to slot %d (%ls)\n", nodeindex, i, m_slotList[i]->getName().str()));
- m_connectionNodes[nodeindex].m_slotIndex = i;
- m_connectionNodes[nodeindex].m_behavior = m_slotList[i]->getNATBehavior();
- connectionAssigned[i] = TRUE;
- }
-
-// sanity check
-#if defined(_DEBUG) || defined(_INTERNAL)
- for (i = 0; i < m_numNodes; ++i) {
- DEBUG_ASSERTCRASH(connectionAssigned[i] == TRUE, ("connection number %d not assigned", i));
- }
-#endif
-
- // find the local node number.
- for (i = 0; i < m_numNodes; ++i) {
- if (m_connectionNodes[i].m_slotIndex == TheGameSpyGame->getLocalSlotNum()) {
- m_localNodeNumber = i;
- DEBUG_LOG(("NAT::establishConnectionPaths - local node is %d\n", m_localNodeNumber));
- break;
- }
- }
-
- // set up the names in the connection window.
- Int playerNum = 0;
- for (i = 0; i < MAX_SLOTS; ++i) {
- while ((i < MAX_SLOTS) && (m_slotList[i] != NULL) && !(m_slotList[i]->isHuman())) {
- ++i;
- }
- if (i >= MAX_SLOTS) {
- break;
- }
- if (i != TheGameSpyGame->getLocalSlotNum()) {
- TheEstablishConnectionsMenu->setPlayerName(playerNum, m_slotList[i]->getName());
- TheEstablishConnectionsMenu->setPlayerStatus(playerNum, NATCONNECTIONSTATE_WAITINGTOBEGIN);
- ++playerNum;
- }
- }
-
-// m_roundTimeout = timeGetTime() + TheGameSpyConfig->getRoundTimeout();
- m_roundTimeout = timeGetTime() + m_timeForRoundTimeout;
-
- // make the connections for this round.
- // this song is cool.
- doThisConnectionRound();
-}
-
-void NAT::attachSlotList(GameSlot *slotList[], Int localSlot, UnsignedInt localIP) {
- m_slotList = slotList;
- m_localIP = localIP;
- m_transport = new Transport;
- DEBUG_LOG(("NAT::attachSlotList - initting the transport socket with address %d.%d.%d.%d:%d\n",
- m_localIP >> 24, (m_localIP >> 16) & 0xff, (m_localIP >> 8) & 0xff, m_localIP & 0xff, getSlotPort(localSlot)));
-
- m_startingPortNumber = NETWORK_BASE_PORT_NUMBER + ((timeGetTime() / 1000) % 20000);
- DEBUG_LOG(("NAT::attachSlotList - using %d as the starting port number\n", m_startingPortNumber));
- generatePortNumbers(slotList, localSlot);
- m_transport->init(m_localIP, getSlotPort(localSlot));
-}
-
-Int NAT::getSlotPort(Int slot) {
-// return (slot + m_startingPortNumber);
- if (m_slotList[slot] != NULL) {
- return m_slotList[slot]->getPort();
- }
- return 0;
-}
-
-void NAT::generatePortNumbers(GameSlot *slotList[], Int localSlot) {
- for (Int i = 0; i < MAX_SLOTS; ++i) {
- if (slotList[i] != NULL) {
- if ((i == localSlot) && (TheWritableGlobalData->m_firewallPortOverride != 0)) {
- slotList[i]->setPort(TheWritableGlobalData->m_firewallPortOverride);
- } else {
- slotList[i]->setPort(i + m_startingPortNumber);
- }
- }
- }
-}
-
-Transport * NAT::getTransport() {
- return m_transport;
-}
-
-// figure out which port I'll be using.
-// send the port number to our target for this round.
-// init the m_connectionStates for all players.
-void NAT::doThisConnectionRound() {
- DEBUG_LOG(("NAT::doThisConnectionRound - starting process for connection round %d\n", m_connectionRound));
- // clear out the states from the last round.
- m_targetNodeNumber = -1;
-
- for (Int i = 0; i < MAX_SLOTS; ++i) {
- setConnectionState(i, NATCONNECTIONSTATE_NOSTATE);
- }
-
- m_beenProbed = FALSE;
- m_numRetries = 0;
-
- for (i = 0; i < m_numNodes; ++i) {
- Int targetNodeNumber = m_connectionPairs[m_connectionPairIndex][m_connectionRound][i];
- DEBUG_LOG(("NAT::doThisConnectionRound - node %d needs to connect to node %d\n", i, targetNodeNumber));
- if (targetNodeNumber != -1) {
- if (i == m_localNodeNumber) {
- m_targetNodeNumber = targetNodeNumber;
- DEBUG_LOG(("NAT::doThisConnectionRound - Local node is connecting to node %d\n", m_targetNodeNumber));
- UnsignedInt targetSlotIndex = m_connectionNodes[(m_connectionPairs[m_connectionPairIndex][m_connectionRound][i])].m_slotIndex;
- GameSlot *targetSlot = m_slotList[targetSlotIndex];
- GameSlot *localSlot = m_slotList[m_connectionNodes[m_localNodeNumber].m_slotIndex];
-
- DEBUG_ASSERTCRASH(localSlot != NULL, ("local slot is NULL"));
- DEBUG_ASSERTCRASH(targetSlot != NULL, ("trying to negotiate with a NULL target slot, slot is %d", m_connectionPairs[m_connectionPairIndex][m_connectionRound][i]));
- DEBUG_LOG(("NAT::doThisConnectionRound - Target slot index = %d (%ls)\n", targetSlotIndex, m_slotList[targetSlotIndex]->getName().str()));
- DEBUG_LOG(("NAT::doThisConnectionRound - Target slot has NAT behavior 0x%8X, local slot has NAT behavior 0x%8X\n", targetSlot->getNATBehavior(), localSlot->getNATBehavior()));
-
-#if defined(DEBUG_LOGGING)
- UnsignedInt targetIP = targetSlot->getIP();
- UnsignedInt localIP = localSlot->getIP();
-#endif
-
- DEBUG_LOG(("NAT::doThisConnectionRound - Target slot has IP %d.%d.%d.%d Local slot has IP %d.%d.%d.%d\n",
- targetIP >> 24, (targetIP >> 16) & 0xff, (targetIP >> 8) & 0xff, targetIP & 0xff,
- localIP >> 24, (localIP >> 16) & 0xff, (localIP >> 8) & 0xff, localIP & 0xff));
-
- if (((targetSlot->getNATBehavior() & FirewallHelperClass::FIREWALL_TYPE_NETGEAR_BUG) == 0) &&
- ((localSlot->getNATBehavior() & FirewallHelperClass::FIREWALL_TYPE_NETGEAR_BUG) != 0)) {
-
- // we have a netgear bug type behavior and the target does not, so we need them to send to us
- // first to avoid having our NAT table reset.
-
- DEBUG_LOG(("NAT::doThisConnectionRound - Local node has a netgear and the target node does not, need to delay our probe.\n"));
- m_timeTillNextSend = -1;
- }
-
- // figure out which port number I'm using for this connection
- // this merely starts to talk to the mangler server, we have to keep calling
- // the update function till we get a response.
- DEBUG_LOG(("NAT::doThisConnectionRound - About to attempt to get the next mangled source port\n"));
- sendMangledSourcePort();
-// m_nextPortSendTime = timeGetTime() + TheGameSpyConfig->getRetryInterval();
- m_nextPortSendTime = timeGetTime() + m_timeBetweenRetries;
-// m_timeoutTime = timeGetTime() + TheGameSpyConfig->getPortTimeout();
- m_timeoutTime = timeGetTime() + m_timeToWaitForPort;
- } else {
- // this is someone else that needs to connect to someone, so wait till they tell us
- // that they're done.
- setConnectionState(i, NATCONNECTIONSTATE_WAITINGFORRESPONSE);
- }
- } else {
- // no one to connect to, so this one is done.
- DEBUG_LOG(("NAT::doThisConnectionRound - node %d has no one to connect to, so they're done\n", i));
- setConnectionState(i, NATCONNECTIONSTATE_DONE);
- }
- }
-}
-
-void NAT::sendAProbe(UnsignedInt ip, UnsignedShort port, Int fromNode) {
- DEBUG_LOG(("NAT::sendAProbe - sending a probe from port %d to %d.%d.%d.%d:%d\n", getSlotPort(m_connectionNodes[m_localNodeNumber].m_slotIndex),
- ip >> 24, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff, port));
- AsciiString str;
- str.format("PROBE%d", fromNode);
- m_transport->queueSend(ip, port, (unsigned char *)str.str(), str.getLength() + 1);
- m_transport->doSend();
-}
-
-// find the next mangled source port, and then send it to the other player.
-// if this requires talking to the mangler, we'll have to wait till a later update
-// to send our port out.
-void NAT::sendMangledSourcePort() {
- UnsignedShort sourcePort = getSlotPort(m_connectionNodes[m_localNodeNumber].m_slotIndex);
-
- FirewallHelperClass::tFirewallBehaviorType fwType = m_slotList[m_connectionNodes[m_localNodeNumber].m_slotIndex]->getNATBehavior();
- GameSlot *targetSlot = m_slotList[m_connectionNodes[m_targetNodeNumber].m_slotIndex];
- DEBUG_ASSERTCRASH(targetSlot != NULL, ("NAT::sendMangledSourcePort - targetSlot is NULL"));
- if (targetSlot == NULL) {
- DEBUG_LOG(("NAT::sendMangledSourcePort - targetSlot is NULL, failed this connection\n"));
- setConnectionState(m_localNodeNumber, NATCONNECTIONSTATE_FAILED);
- return;
- }
-
- GameSlot *localSlot = m_slotList[m_connectionNodes[m_localNodeNumber].m_slotIndex];
- DEBUG_ASSERTCRASH(localSlot != NULL, ("NAT::sendMangledSourcePort - localSlot is NULL, WTF?"));
- if (localSlot == NULL) {
- DEBUG_LOG(("NAT::sendMangledSourcePort - localSlot is NULL, failed this connection\n"));
- setConnectionState(m_localNodeNumber, NATCONNECTIONSTATE_FAILED);
- return;
- }
-
- // check to see if the target and I are behind the same NAT
- if (targetSlot->getIP() == localSlot->getIP()) {
-#if defined(DEBUG_LOGGING)
- UnsignedInt localip = localSlot->getIP();
- UnsignedInt targetip = targetSlot->getIP();
-#endif
- DEBUG_LOG(("NAT::sendMangledSourcePort - target and I are behind the same NAT, no mangling\n"));
- DEBUG_LOG(("NAT::sendMangledSourcePort - I am %ls, target is %ls, my IP is %d.%d.%d.%d, target IP is %d.%d.%d.%d\n", localSlot->getName().str(), targetSlot->getName().str(),
- localip >> 24, (localip >> 16) & 0xff, (localip >> 8) & 0xff, localip & 0xff,
- targetip >> 24, (targetip >> 16) & 0xff, (targetip >> 8) & 0xff, targetip & 0xff));
-
- sendMangledPortNumberToTarget(sourcePort, targetSlot);
- m_sourcePorts[m_targetNodeNumber] = sourcePort;
- setConnectionState(m_localNodeNumber, NATCONNECTIONSTATE_WAITINGFORMANGLEDPORT);
- // In case you're wondering, we don't set the m_previousSourcePort here because this will be a different source
- // address than what other nodes will likely see (unless of course there are more than
- // two of us behind the same NAT, but we won't worry about that cause theres no mangling
- // in that case anyways)
- return;
- }
-
- // check to see if we are NAT'd at all.
- if ((fwType == 0) || (fwType == FirewallHelperClass::FIREWALL_TYPE_SIMPLE)) {
- // no mangling, just return the source port
- DEBUG_LOG(("NAT::sendMangledSourcePort - no mangling, just using the source port\n"));
- sendMangledPortNumberToTarget(sourcePort, targetSlot);
- m_previousSourcePort = sourcePort;
- m_sourcePorts[m_targetNodeNumber] = sourcePort;
- setConnectionState(m_localNodeNumber, NATCONNECTIONSTATE_WAITINGFORMANGLEDPORT);
- return;
- }
-
- // check to see if our NAT keeps the same source port for different destinations.
- // if this is the case, and we've already worked out what our mangled port number is
- // then we don't have to figure it out again.
- if (((fwType & FirewallHelperClass::FIREWALL_TYPE_DESTINATION_PORT_DELTA) == 0) &&
- ((fwType & FirewallHelperClass::FIREWALL_TYPE_SMART_MANGLING) == 0)) {
- DEBUG_LOG(("NAT::sendMangledSourcePort - our firewall doesn't NAT based on destination address, checking for old connections from this address\n"));
- if (m_previousSourcePort != 0) {
- DEBUG_LOG(("NAT::sendMangledSourcePort - Previous source port was %d, using that one\n", m_previousSourcePort));
- sendMangledPortNumberToTarget(m_previousSourcePort, targetSlot);
- m_sourcePorts[m_targetNodeNumber] = m_previousSourcePort;
- setConnectionState(m_localNodeNumber, NATCONNECTIONSTATE_WAITINGFORMANGLEDPORT);
- return;
- } else {
- DEBUG_LOG(("NAT::sendMangledSourcePort - Previous source port not found\n"));
- }
- }
-
- // At this point we know that our NAT uses some kind of relative port mapping scheme, so we
- // need to talk to the mangler to find out where we are now so we can find out where we'll be on the
- // next port allocation.
-
- // get the address of the mangler we need to talk to.
- Char manglerName[256];
- FirewallHelperClass::getManglerName(1, manglerName);
- DEBUG_LOG(("NAT::sendMangledSourcePort - about to call gethostbyname for mangler at %s\n", manglerName));
- struct hostent *hostInfo = gethostbyname(manglerName);
-
- if (hostInfo == NULL) {
- DEBUG_LOG(("NAT::sendMangledSourcePort - gethostbyname failed for mangler address %s\n", manglerName));
- // can't find the mangler, we're screwed so just send the source port.
- sendMangledPortNumberToTarget(sourcePort, targetSlot);
- m_sourcePorts[m_targetNodeNumber] = sourcePort;
- setConnectionState(m_localNodeNumber, NATCONNECTIONSTATE_WAITINGFORMANGLEDPORT);
- return;
- }
-
- memcpy(&m_manglerAddress, &(hostInfo->h_addr_list[0][0]), 4);
- m_manglerAddress = ntohl(m_manglerAddress);
- DEBUG_LOG(("NAT::sendMangledSourcePort - mangler %s address is %d.%d.%d.%d\n", manglerName,
- m_manglerAddress >> 24, (m_manglerAddress >> 16) & 0xff, (m_manglerAddress >> 8) & 0xff, m_manglerAddress & 0xff));
-
- DEBUG_LOG(("NAT::sendMangledSourcePort - NAT behavior = 0x%08x\n", fwType));
-
-// m_manglerRetryTime = TheGameSpyConfig->getRetryInterval() + timeGetTime();
- m_manglerRetryTime = m_manglerRetryTimeInterval + timeGetTime();
- m_manglerRetries = 0;
-
- if (TheFirewallHelper != NULL) {
- m_spareSocketPort = TheFirewallHelper->getNextTemporarySourcePort(0);
- TheFirewallHelper->openSpareSocket(m_spareSocketPort);
- TheFirewallHelper->sendToManglerFromPort(m_manglerAddress, m_spareSocketPort, m_packetID);
-// m_manglerRetryTime = TheGameSpyConfig->getRetryInterval() + timeGetTime();
- m_manglerRetryTime = m_manglerRetryTimeInterval + timeGetTime();
- }
-
- setConnectionState(m_localNodeNumber, NATCONNECTIONSTATE_WAITINGFORMANGLERRESPONSE);
-}
-
-void NAT::processManglerResponse(UnsignedShort mangledPort) {
- DEBUG_LOG(("NAT::processManglerResponse - Work out what my NAT'd port will be\n"));
-
- GameSlot *targetSlot = m_slotList[m_connectionNodes[m_targetNodeNumber].m_slotIndex];
- DEBUG_ASSERTCRASH(targetSlot != NULL, ("NAT::processManglerResponse - targetSlot is NULL"));
- if (targetSlot == NULL) {
- DEBUG_LOG(("NAT::processManglerResponse - targetSlot is NULL, failed this connection\n"));
- setConnectionState(m_localNodeNumber, NATCONNECTIONSTATE_FAILED);
- return;
- }
-
- Short delta = TheGlobalData->m_firewallPortAllocationDelta;
- UnsignedShort sourcePort = getSlotPort(m_connectionNodes[m_localNodeNumber].m_slotIndex);
- UnsignedShort returnPort = 0;
-
- FirewallHelperClass::tFirewallBehaviorType fwType = m_slotList[m_connectionNodes[m_localNodeNumber].m_slotIndex]->getNATBehavior();
-
- if ((fwType & FirewallHelperClass::FIREWALL_TYPE_SIMPLE_PORT_ALLOCATION) != 0) {
- returnPort = mangledPort + delta;
- } else {
- // to steal a line from Steve Tall...
- // Rats. It's a relative mangler. This is much harder. Damn NAT32 guy.
- if (delta == 100) {
- // Special NAT32 section.
- // NAT32 mangles source UDP port by ading 1700 + 100*NAT table index.
- returnPort = mangledPort - m_spareSocketPort;
- returnPort -= 1700;
-
- returnPort += delta;
- returnPort += sourcePort;
- returnPort += 1700;
-
- } else if (delta == 0) {
- returnPort = sourcePort;
- } else {
- returnPort = mangledPort / delta;
- returnPort = returnPort * delta;
-
- returnPort += (sourcePort % delta);
- returnPort += delta;
- }
- }
-
- // This bit is probably doomed.
- if (returnPort > 65535) {
- returnPort -= 65535;
- }
- if (returnPort < 1024) {
- returnPort += 1024;
- }
-
- DEBUG_LOG(("NAT::processManglerResponse - mangled port is %d\n", returnPort));
- m_previousSourcePort = returnPort;
-
- sendMangledPortNumberToTarget(returnPort, targetSlot);
- m_sourcePorts[m_targetNodeNumber] = returnPort;
- if (targetSlot->getPort() == 0) {
- // we haven't got the target's mangled port number yet, wait for it.
- setConnectionState(m_localNodeNumber, NATCONNECTIONSTATE_WAITINGFORMANGLEDPORT);
- } else {
- // in this case we should have already sent a PROBE, so we'll just change the state
- // and leave it at that.
- setConnectionState(m_localNodeNumber, NATCONNECTIONSTATE_WAITINGFORRESPONSE);
- }
-}
-
-// check to see if we've completed all the rounds
-// this is kind of a cheesy way to check, but it works.
-Bool NAT::allConnectionsDone() {
- if (m_numNodes == 2) {
- if (m_connectionRound >= 1) {
- return TRUE;
- }
- } else if (m_numNodes == 3) {
- if (m_connectionRound >= 3) {
- return TRUE;
- }
- } else if (m_numNodes == 4) {
- if (m_connectionRound >= 3) {
- return TRUE;
- }
- } else if (m_numNodes == 5) {
- if (m_connectionRound >= 5) {
- return TRUE;
- }
- } else if (m_numNodes == 6) {
- if (m_connectionRound >= 5) {
- return TRUE;
- }
- } else if (m_numNodes == 7) {
- if (m_connectionRound >= 7) {
- return TRUE;
- }
- } else if (m_numNodes == 8) {
- if (m_connectionRound >= 7) {
- return TRUE;
- }
- }
- return FALSE;
-}
-
-Bool NAT::allConnectionsDoneThisRound() {
- Bool retval = TRUE;
- for (Int i = 0; (i < m_numNodes) && (retval == TRUE); ++i) {
- if ((m_connectionStates[i] != NATCONNECTIONSTATE_DONE) && (m_connectionStates[i] != NATCONNECTIONSTATE_FAILED)) {
- retval = FALSE;
- }
- }
- return retval;
-}
-
-// this node's connection for this round has been completed.
-void NAT::connectionComplete(Int slotIndex) {
-}
-
-// this node's connection for this round has failed.
-void NAT::connectionFailed(Int slotIndex) {
-}
-
-// I have been probed by the target.
-void NAT::probed(Int nodeNumber) {
- GameSlot *localSlot = m_slotList[m_connectionNodes[m_localNodeNumber].m_slotIndex];
- DEBUG_ASSERTCRASH(localSlot != NULL, ("NAT::probed - localSlot is NULL, WTF?"));
- if (localSlot == NULL) {
- DEBUG_LOG(("NAT::probed - localSlot is NULL, failed this connection\n"));
- setConnectionState(m_localNodeNumber, NATCONNECTIONSTATE_FAILED);
- return;
- }
-
- if (m_beenProbed == FALSE) {
- m_beenProbed = TRUE;
- DEBUG_LOG(("NAT::probed - just got probed for the first time.\n"));
- if ((localSlot->getNATBehavior() & FirewallHelperClass::FIREWALL_TYPE_NETGEAR_BUG) != 0) {
- DEBUG_LOG(("NAT::probed - we have a NETGEAR and we were just probed for the first time\n"));
- GameSlot *targetSlot = m_slotList[m_connectionNodes[m_targetNodeNumber].m_slotIndex];
- DEBUG_ASSERTCRASH(targetSlot != NULL, ("NAT::probed - targetSlot is NULL"));
- if (targetSlot == NULL) {
- DEBUG_LOG(("NAT::probed - targetSlot is NULL, failed this connection\n"));
- setConnectionState(m_localNodeNumber, NATCONNECTIONSTATE_FAILED);
- return;
- }
-
- if (targetSlot->getPort() == 0) {
- setConnectionState(m_localNodeNumber, NATCONNECTIONSTATE_WAITINGFORMANGLEDPORT);
- DEBUG_LOG(("NAT::probed - still waiting for mangled port\n"));
- } else {
- DEBUG_LOG(("NAT::probed - sending a probe to %ls\n", targetSlot->getName().str()));
- sendAProbe(targetSlot->getIP(), targetSlot->getPort(), m_localNodeNumber);
- notifyTargetOfProbe(targetSlot);
- setConnectionState(m_localNodeNumber, NATCONNECTIONSTATE_WAITINGFORRESPONSE);
- }
- }
- }
-}
-
-// got the mangled port for our target for this round.
-void NAT::gotMangledPort(Int nodeNumber, UnsignedShort mangledPort) {
-
- // if we've already finished the connection, then we don't need to process this.
- if (m_connectionStates[m_localNodeNumber] == NATCONNECTIONSTATE_DONE) {
- DEBUG_LOG(("NAT::gotMangledPort - got a mangled port, but we've already finished this connection, ignoring.\n"));
- return;
- }
-
- GameSlot *targetSlot = m_slotList[m_connectionNodes[m_targetNodeNumber].m_slotIndex];
- DEBUG_ASSERTCRASH(targetSlot != NULL, ("NAT::gotMangledPort - targetSlot is NULL"));
- if (targetSlot == NULL) {
- DEBUG_LOG(("NAT::gotMangledPort - targetSlot is NULL, failed this connection\n"));
- setConnectionState(m_localNodeNumber, NATCONNECTIONSTATE_FAILED);
- return;
- }
-
- GameSlot *localSlot = m_slotList[m_connectionNodes[m_localNodeNumber].m_slotIndex];
- DEBUG_ASSERTCRASH(localSlot != NULL, ("NAT::gotMangledPort - localSlot is NULL, WTF?"));
- if (localSlot == NULL) {
- DEBUG_LOG(("NAT::gotMangledPort - localSlot is NULL, failed this connection\n"));
- setConnectionState(m_localNodeNumber, NATCONNECTIONSTATE_FAILED);
- return;
- }
-
- if (nodeNumber != m_targetNodeNumber) {
- DEBUG_LOG(("NAT::gotMangledPort - got a mangled port number for someone that isn't my target. node = %d, target node = %d\n", nodeNumber, m_targetNodeNumber));
- return;
- }
-
- targetSlot->setPort(mangledPort);
- DEBUG_LOG(("NAT::gotMangledPort - got mangled port number %d from our target node (%ls)\n", mangledPort, targetSlot->getName().str()));
- if (((localSlot->getNATBehavior() & FirewallHelperClass::FIREWALL_TYPE_NETGEAR_BUG) == 0) || (m_beenProbed == TRUE) ||
- (((localSlot->getNATBehavior() & FirewallHelperClass::FIREWALL_TYPE_NETGEAR_BUG) != 0) && ((targetSlot->getNATBehavior() & FirewallHelperClass::FIREWALL_TYPE_NETGEAR_BUG) != 0))) {
-#ifdef DEBUG_LOGGING
- UnsignedInt ip = targetSlot->getIP();
-#endif
- DEBUG_LOG(("NAT::gotMangledPort - don't have a netgear or we have already been probed, or both my target and I have a netgear, send a PROBE. Sending to %d.%d.%d.%d:%d\n",
- ip >> 24, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff, targetSlot->getPort()));
-
- sendAProbe(targetSlot->getIP(), targetSlot->getPort(), m_localNodeNumber);
- notifyTargetOfProbe(targetSlot);
- setConnectionState(m_localNodeNumber, NATCONNECTIONSTATE_WAITINGFORRESPONSE);
- } else {
- DEBUG_LOG(("NAT::gotMangledPort - we are a netgear, not sending a PROBE yet.\n"));
- }
-}
-
-void NAT::gotInternalAddress(Int nodeNumber, UnsignedInt address) {
- GameSlot *targetSlot = m_slotList[m_connectionNodes[nodeNumber].m_slotIndex];
- DEBUG_ASSERTCRASH(targetSlot != NULL, ("NAT::gotInternalAddress - targetSlot is NULL"));
- if (targetSlot == NULL) {
- return;
- }
-
- GameSlot *localSlot = m_slotList[m_connectionNodes[m_localNodeNumber].m_slotIndex];
- DEBUG_ASSERTCRASH(localSlot != NULL, ("NAT::gotInternalAddress - localSlot is NULL, WTF?"));
- if (localSlot == NULL) {
- return;
- }
-
- if (nodeNumber != m_targetNodeNumber) {
- DEBUG_LOG(("NAT::gotInternalAddress - got a internal address for someone that isn't my target. node = %d, target node = %d\n", nodeNumber, m_targetNodeNumber));
- return;
- }
-
- if (localSlot->getIP() == targetSlot->getIP()) {
- // we have the same IP address, i.e. we are behind the same NAT.
- // I need to talk directly to his internal address.
- DEBUG_LOG(("NAT::gotInternalAddress - target and local players have same external address, using internal address.\n"));
- targetSlot->setIP(address); // use the slot's internal address from now on
- }
-}
-
-void NAT::notifyTargetOfProbe(GameSlot *targetSlot) {
- PeerRequest req;
- AsciiString options;
- options.format("PROBED%d", m_localNodeNumber);
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMPLAYER;
- req.UTM.isStagingRoom = TRUE;
- req.id = "NAT/";
- AsciiString hostName;
- hostName.translate(targetSlot->getName());
- req.nick = hostName.str();
- req.options = options.str();
- TheGameSpyPeerMessageQueue->addRequest(req);
- DEBUG_LOG(("NAT::notifyTargetOfProbe - notifying %ls that we have probed them.\n", targetSlot->getName().str()));
-}
-
-void NAT::notifyUsersOfConnectionDone(Int nodeIndex) {
- GameSlot *localSlot = m_slotList[m_connectionNodes[m_localNodeNumber].m_slotIndex];
- DEBUG_ASSERTCRASH(localSlot != NULL, ("NAT::notifyUsersOfConnectionDone - localSlot is NULL, WTF?"));
- if (localSlot == NULL) {
- DEBUG_LOG(("NAT::notifyUsersOfConnectionDone - localSlot is NULL, failed this connection\n"));
- setConnectionState(m_localNodeNumber, NATCONNECTIONSTATE_FAILED);
- return;
- }
-
- PeerRequest req;
- AsciiString options;
- options.format("CONNDONE%d %d", nodeIndex, m_localNodeNumber);
-
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMPLAYER;
- req.UTM.isStagingRoom = TRUE;
- req.id = "NAT";
- AsciiString names;
- for (Int i=0; iisHuman() == FALSE)) {
- continue;
- }
-
- AsciiString name;
- name.translate(m_slotList[i]->getName());
- if (names.isNotEmpty())
- {
- names.concat(',');
- }
- names.concat(name);
- }
- req.nick = names.str();
- req.options = options.str();
-
- DEBUG_LOG(("NAT::notifyUsersOfConnectionDone - sending %s to %s\n", options.str(), names.str()));
- TheGameSpyPeerMessageQueue->addRequest(req);
-}
-
-void NAT::notifyUsersOfConnectionFailed(Int nodeIndex) {
- GameSlot *localSlot = m_slotList[m_connectionNodes[m_localNodeNumber].m_slotIndex];
- DEBUG_ASSERTCRASH(localSlot != NULL, ("NAT::notifyUsersOfConnectionFailed - localSlot is NULL, WTF?"));
- if (localSlot == NULL) {
- DEBUG_LOG(("NAT::notifyUsersOfConnectionFailed - localSlot is NULL, failed this connection\n"));
- setConnectionState(m_localNodeNumber, NATCONNECTIONSTATE_FAILED);
- return;
- }
-
- PeerRequest req;
- AsciiString options;
- options.format("CONNFAILED%d", nodeIndex);
-/*
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMROOM;
- req.UTM.isStagingRoom = TRUE;
- req.id = "NAT/";
- req.options = options.str();
-
- DEBUG_LOG(("NAT::notifyUsersOfConnectionFailed - sending %s to room\n", options.str()));
-*/
-
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMPLAYER;
- req.UTM.isStagingRoom = TRUE;
- req.id = "NAT";
- AsciiString names;
- for (Int i=0; iisHuman() == FALSE)) {
- continue;
- }
-
- AsciiString name;
- name.translate(m_slotList[i]->getName());
- if (names.isNotEmpty())
- {
- names.concat(',');
- }
- names.concat(name);
- }
- req.nick = names.str();
- req.options = options.str();
-
- DEBUG_LOG(("NAT::notifyUsersOfConnectionFailed - sending %s to %s\n", options.str(), names.str()));
-
- TheGameSpyPeerMessageQueue->addRequest(req);
-}
-
-void NAT::sendMangledPortNumberToTarget(UnsignedShort mangledPort, GameSlot *targetSlot) {
- PeerRequest req;
- AsciiString options;
- options.format("PORT%d %d %08X", m_localNodeNumber, mangledPort, m_localIP);
-
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMPLAYER;
- req.UTM.isStagingRoom = TRUE;
- req.id = "NAT/";
- AsciiString hostName;
- hostName.translate(targetSlot->getName());
- req.nick = hostName.str();
- req.options = options.str();
- DEBUG_LOG(("NAT::sendMangledPortNumberToTarget - sending \"%s\" to %s\n", options.str(), hostName.str()));
- TheGameSpyPeerMessageQueue->addRequest(req);
-}
-
-void NAT::processGlobalMessage(Int slotNum, const char *options) {
- const char *ptr = options;
- // skip preceding whitespace.
- while (isspace(*ptr)) {
- ++ptr;
- }
- DEBUG_LOG(("NAT::processGlobalMessage - got message from slot %d, message is \"%s\"\n", slotNum, ptr));
- if (!strncmp(ptr, "PROBED", strlen("PROBED"))) {
- // format: PROBED
- // a probe has been sent at us, if we are waiting because of a netgear or something, we
- // should start sending our own probes.
- Int node = atoi(ptr + strlen("PROBED"));
- if (node == m_targetNodeNumber) {
- // make sure we're being probed by who we're supposed to be probed by.
- probed(node);
- } else {
- DEBUG_LOG(("NAT::processGlobalMessage - probed by node %d, not our target\n", node));
- }
- } else if (!strncmp(ptr, "CONNDONE", strlen("CONNDONE"))) {
- // format: CONNDONE
- // we should get the node number of the player who's connection is done from the options
- // and mark that down as part of the connectionStates.
- const char *c = ptr + strlen("CONNDONE");
-/* while (*c != ' ') {
- ++c;
- }
- while (*c == ' ') {
- ++c;
- }
-*/ Int node;
- Int sendingNode;
- sscanf(c, "%d %d\n", &node, &sendingNode);
-
- if (m_connectionPairs[m_connectionPairIndex][m_connectionRound][node] == sendingNode) {
-// Int node = atoi(ptr + strlen("CONNDONE"));
- DEBUG_LOG(("NAT::processGlobalMessage - got a CONNDONE message for node %d\n", node));
- if ((node >= 0) && (node <= m_numNodes)) {
- DEBUG_LOG(("NAT::processGlobalMessage - node %d's connection is complete, setting connection state to done\n", node));
- setConnectionState(node, NATCONNECTIONSTATE_DONE);
- }
- } else {
- DEBUG_LOG(("NAT::processGlobalMessage - got a connection done message that isn't from this round. node: %d sending node: %d\n", node, sendingNode));
- }
- } else if (!strncmp(ptr, "CONNFAILED", strlen("CONNFAILED"))) {
- // format: CONNFAILED
- // we should get the node number of the player who's connection failed from the options
- // and mark that down as part of the connectionStates.
- Int node = atoi(ptr + strlen("CONNFAILED"));
- if ((node >= 0) && (node < m_numNodes)) {
- DEBUG_LOG(("NAT::processGlobalMessage - node %d's connection failed, setting connection state to failed\n", node));
- setConnectionState(node, NATCONNECTIONSTATE_FAILED);
- }
- } else if (!strncmp(ptr, "PORT", strlen("PORT"))) {
- // format: PORT
- // we should get the node number and the mangled port number of the client we
- // are supposed to be communicating with and start probing them. No, that was not
- // meant to be a phallic reference, you sicko.
- const char *c = ptr + strlen("PORT");
- Int node = atoi(c);
- while (*c != ' ') {
- ++c;
- }
- while (*c == ' ') {
- ++c;
- }
- UnsignedInt intport = 0;
- UnsignedInt addr = 0;
- sscanf(c, "%d %X", &intport, &addr);
- UnsignedShort port = (UnsignedShort)intport;
-
- DEBUG_LOG(("NAT::processGlobalMessage - got port message from node %d, port: %d, internal address: %d.%d.%d.%d\n", node, port,
- addr >> 24, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff));
-
- if ((node >= 0) && (node < m_numNodes)) {
- if (port < 1024) {
- // it has to be less than 65535 cause its a short duh.
- DEBUG_ASSERTCRASH(port >= 1024, ("Was passed an invalid port number"));
- port += 1024;
- }
- gotInternalAddress(node, addr);
- gotMangledPort(node, port);
- }
- }
-}
-
-void NAT::setConnectionState(Int nodeNumber, NATConnectionState state) {
- m_connectionStates[nodeNumber] = state;
-
- if (nodeNumber != m_localNodeNumber) {
- return;
- }
-
- // if this is the case we are starting a new round and we don't know
- // who we're connecting to yet.
- if (m_localNodeNumber == m_targetNodeNumber) {
- return;
- }
-
- // if this is the start of a new connection round we don't have a
- // target yet.
- if (m_targetNodeNumber == -1) {
- return;
- }
-
- // find the menu slot of the target node.
- Int slotIndex = m_connectionNodes[m_targetNodeNumber].m_slotIndex;
- Int slot = 0;
- for (Int i = 0; i < MAX_SLOTS; ++i) {
- if (m_slotList[i] != NULL) {
- if (m_slotList[i]->isHuman()) {
- if (i != m_connectionNodes[m_localNodeNumber].m_slotIndex) {
- if (i == slotIndex) {
- break;
- }
- ++slot;
- }
- }
- }
- }
- if (i == MAX_SLOTS) {
- DEBUG_ASSERTCRASH(i < MAX_SLOTS, ("Didn't find the node number in the slot list"));
- return;
- }
- TheEstablishConnectionsMenu->setPlayerStatus(slot, state);
-}
diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/GUICallbacks/W3DMainMenu.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/GUICallbacks/W3DMainMenu.cpp
index 580f7e75c4c..8da88662fe1 100644
--- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/GUICallbacks/W3DMainMenu.cpp
+++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/GUICallbacks/W3DMainMenu.cpp
@@ -916,17 +916,11 @@ void W3DMainMenuInit( WindowLayout *layout, void *userData )
NameKeyType buttonUSAID = TheNameKeyGenerator->nameToKey( "MainMenu.wnd:ButtonUSA" );
NameKeyType buttonGLAID = TheNameKeyGenerator->nameToKey( "MainMenu.wnd:ButtonGLA" );
NameKeyType buttonChinaID = TheNameKeyGenerator->nameToKey( "MainMenu.wnd:ButtonChina" );
- NameKeyType skirmishID = TheNameKeyGenerator->nameToKey( AsciiString("MainMenu.wnd:ButtonSkirmish") );
- NameKeyType onlineID = TheNameKeyGenerator->nameToKey( AsciiString("MainMenu.wnd:ButtonOnline") );
- NameKeyType networkID = TheNameKeyGenerator->nameToKey( AsciiString("MainMenu.wnd:ButtonNetwork") );
+ NameKeyType skirmishID = TheNameKeyGenerator->nameToKey( AsciiString("MainMenu.wnd:ButtonSkirmish") ); NameKeyType networkID = TheNameKeyGenerator->nameToKey( AsciiString("MainMenu.wnd:ButtonNetwork") );
GameWindow *button = TheWindowManager->winGetWindowFromId( parent, skirmishID );
if (button)
- button->winSetDrawFunc(W3DMainMenuButtonDropShadowDraw);
- button = TheWindowManager->winGetWindowFromId( parent, onlineID );
- if (button)
- button->winSetDrawFunc(W3DMainMenuButtonDropShadowDraw);
- button = TheWindowManager->winGetWindowFromId( parent, networkID );
+ button->winSetDrawFunc(W3DMainMenuButtonDropShadowDraw); button = TheWindowManager->winGetWindowFromId( parent, networkID );
if (button)
button->winSetDrawFunc(W3DMainMenuButtonDropShadowDraw);
diff --git a/Generals/Code/Main/WinMain.cpp b/Generals/Code/Main/WinMain.cpp
index e504e6db2a4..c6b1ab877f3 100644
--- a/Generals/Code/Main/WinMain.cpp
+++ b/Generals/Code/Main/WinMain.cpp
@@ -378,7 +378,6 @@ LRESULT CALLBACK WndProc( HWND hWnd, UINT message,
// ------------------------------------------------------------------------
case WM_CLOSE:
- TheGameEngine->checkAbnormalQuitting();
TheGameEngine->reset();
TheGameEngine->setQuitting(TRUE);
_exit(EXIT_SUCCESS);
diff --git a/GeneralsMD/Code/GameEngine/GameEngine.dsp b/GeneralsMD/Code/GameEngine/GameEngine.dsp
index 803e13bf105..2ddb395651f 100644
--- a/GeneralsMD/Code/GameEngine/GameEngine.dsp
+++ b/GeneralsMD/Code/GameEngine/GameEngine.dsp
@@ -42,7 +42,7 @@ RSC=rc.exe
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /G6 /MD /W3 /WX /GX /O2 /Ob2 /I "Include/Precompiled" /I "../Libraries/Source/WWVegas" /I "../Libraries/Source/WWVegas\WWLib" /I "Include" /I "../Libraries/Include" /I "../Libraries/Source/GameSpy" /I "../Libraries/Source/Compression" /D "IG_DEBUG_STACKTRACE" /D "NDEBUG" /D "_RELEASE" /D WINVER=0x400 /D "_MBCS" /D "_LIB" /D "_WINDOWS" /D "WIN32" /D "Z_PREFIX" /Yu"PreRTS.h" /FD /c
+# ADD CPP /nologo /G6 /MD /W3 /WX /GX /O2 /Ob2 /I "Include/Precompiled" /I "../Libraries/Source/WWVegas" /I "../Libraries/Source/WWVegas\WWLib" /I "Include" /I "../Libraries/Include" /I "../Libraries/Source/Compression" /D "IG_DEBUG_STACKTRACE" /D "NDEBUG" /D "_RELEASE" /D WINVER=0x400 /D "_MBCS" /D "_LIB" /D "_WINDOWS" /D "WIN32" /D "Z_PREFIX" /Yu"PreRTS.h" /FD /c
# SUBTRACT CPP /Fr
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
@@ -66,7 +66,7 @@ LIB32=link.exe -lib
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /G6 /MDd /W3 /WX /Gm /GX /ZI /Od /I "..\Libraries\Source\WWVegas" /I "..\Libraries\Source\WWVegas\WWLib" /I "Include/Precompiled" /I "../Libraries/Source/WWVegas" /I "../Libraries/Source/WWVegas\WWLib" /I "Include" /I "../Libraries/Include" /I "../Libraries/Source/GameSpy" /I "../Libraries/Source/Compression" /D "_DEBUG" /D WINVER=0x400 /D "_MBCS" /D "_LIB" /D "_WINDOWS" /D "WIN32" /D "Z_PREFIX" /Yu"PreRTS.h" /FD /GZ /c
+# ADD CPP /nologo /G6 /MDd /W3 /WX /Gm /GX /ZI /Od /I "..\Libraries\Source\WWVegas" /I "..\Libraries\Source\WWVegas\WWLib" /I "Include/Precompiled" /I "../Libraries/Source/WWVegas" /I "../Libraries/Source/WWVegas\WWLib" /I "Include" /I "../Libraries/Include" /I "../Libraries/Source/Compression" /D "_DEBUG" /D WINVER=0x400 /D "_MBCS" /D "_LIB" /D "_WINDOWS" /D "WIN32" /D "Z_PREFIX" /Yu"PreRTS.h" /FD /GZ /c
# SUBTRACT CPP /Fr
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
@@ -90,7 +90,7 @@ LIB32=link.exe -lib
# PROP Intermediate_Dir "Internal"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GR /GX /O2 /I "../Libraries/Source/WWVegas" /I "../Libraries/Source/WWVegas\WWLib" /I "Include" /I "../Libraries/Include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "_WINDOWS" /YX /FD /c
-# ADD CPP /nologo /G6 /MD /W3 /WX /GX /Zi /Od /I "../Libraries/Source/Compression" /I "Include/Precompiled" /I "../Libraries/Source/WWVegas" /I "../Libraries/Source/WWVegas\WWLib" /I "Include" /I "../Libraries/Include" /I "../Libraries/Source/GameSpy" /D "NDEBUG" /D "_INTERNAL" /D WINVER=0x400 /D "_MBCS" /D "_LIB" /D "_WINDOWS" /D "WIN32" /D "Z_PREFIX" /Yu"PreRTS.h" /FD /c
+# ADD CPP /nologo /G6 /MD /W3 /WX /GX /Zi /Od /I "../Libraries/Source/Compression" /I "Include/Precompiled" /I "../Libraries/Source/WWVegas" /I "../Libraries/Source/WWVegas\WWLib" /I "Include" /I "../Libraries/Include" /D "NDEBUG" /D "_INTERNAL" /D WINVER=0x400 /D "_MBCS" /D "_LIB" /D "_WINDOWS" /D "WIN32" /D "Z_PREFIX" /Yu"PreRTS.h" /FD /c
# SUBTRACT CPP /Fr
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
@@ -2426,102 +2426,26 @@ SOURCE=.\Source\GameClient\Water.cpp
# Begin Group "GameNetwork"
# PROP Default_Filter ""
-# Begin Group "GameSpy"
-
-# PROP Default_Filter ""
-# Begin Group "Thread"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\Source\GameNetwork\GameSpy\Thread\BuddyThread.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\Source\GameNetwork\GameSpy\Thread\GameResultsThread.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\Source\GameNetwork\GameSpy\Thread\PeerThread.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\Source\GameNetwork\GameSpy\Thread\PersistentStorageThread.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\Source\GameNetwork\GameSpy\Thread\PingThread.cpp
-# End Source File
# Begin Source File
-SOURCE=.\Source\GameNetwork\GameSpy\Thread\ThreadUtils.cpp
-# End Source File
-# End Group
-# Begin Source File
-
-SOURCE=.\Source\GameNetwork\GameSpy\Chat.cpp
-# End Source File
# Begin Source File
SOURCE=.\Source\GameNetwork\DownloadManager.cpp
# End Source File
# Begin Source File
-SOURCE=.\Source\GameNetwork\GameSpyOverlay.cpp
-# End Source File
# Begin Source File
-SOURCE=.\Source\GameNetwork\GameSpy\GSConfig.cpp
-# End Source File
# Begin Source File
-SOURCE=.\Source\GameNetwork\GameSpy\LadderDefs.cpp
-# End Source File
# Begin Source File
-SOURCE=.\Source\GameNetwork\GameSpy\LobbyUtils.cpp
-# End Source File
# Begin Source File
-SOURCE=.\Source\GameNetwork\GameSpy\MainMenuUtils.cpp
-# End Source File
# Begin Source File
-SOURCE=.\Source\GameNetwork\GameSpy\PeerDefs.cpp
-# End Source File
# Begin Source File
-SOURCE=.\Source\GameNetwork\GameSpy\StagingRoomGameInfo.cpp
-# End Source File
-# End Group
-# Begin Group "GameSpyEvalImplementation"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\Source\GameNetwork\GameSpy.cpp
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=.\Source\GameNetwork\GameSpyChat.cpp
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=.\Source\GameNetwork\GameSpyGameInfo.cpp
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=.\Source\GameNetwork\GameSpyGP.cpp
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=.\Source\GameNetwork\GameSpyPersistentStorage.cpp
-# PROP Exclude_From_Build 1
-# End Source File
# End Group
# Begin Group "InGameNetwork"
@@ -2858,10 +2782,6 @@ SOURCE=.\Include\Common\GameSpeech.h
# End Source File
# Begin Source File
-SOURCE=.\Include\Common\GameSpyMiscPreferences.h
-# End Source File
-# Begin Source File
-
SOURCE=.\Include\Common\GameState.h
# End Source File
# Begin Source File
@@ -4666,209 +4586,90 @@ SOURCE=.\Include\GameClient\WinInstanceData.h
# PROP Default_Filter ""
# Begin Source File
-SOURCE=..\Libraries\Source\GameSpy\GameSpy\md5.h
-# End Source File
# End Group
# Begin Group "queryreporting"
# PROP Default_Filter ""
# Begin Source File
-SOURCE=..\Libraries\Source\GameSpy\GameSpy\queryreporting\gqueryreporting.h
-# End Source File
# End Group
# Begin Group "pinger"
# PROP Default_Filter ""
# Begin Source File
-SOURCE=..\Libraries\Source\GameSpy\GameSpy\pinger\pinger.h
-# End Source File
# End Group
# Begin Group "CEngine"
# PROP Default_Filter ""
# Begin Source File
-SOURCE=..\Libraries\Source\GameSpy\GameSpy\CEngine\goaceng.h
-# End Source File
# Begin Source File
-SOURCE=..\Libraries\Source\GameSpy\GameSpy\CEngine\gserver.h
-# End Source File
# End Group
# Begin Group "hashtable"
# PROP Default_Filter ""
# Begin Source File
-SOURCE=..\Libraries\Source\GameSpy\GameSpy\hashtable.h
-# End Source File
# End Group
# Begin Group "chat"
# PROP Default_Filter ""
# Begin Source File
-SOURCE=..\Libraries\Source\GameSpy\GameSpy\chat\chat.h
-# End Source File
# Begin Source File
-SOURCE=..\Libraries\Source\GameSpy\GameSpy\chat\chatCallbacks.h
-# End Source File
# Begin Source File
-SOURCE=..\Libraries\Source\GameSpy\GameSpy\chat\chatChannel.h
-# End Source File
# Begin Source File
-SOURCE=..\Libraries\Source\GameSpy\GameSpy\Chat\chatCrypt.h
-# End Source File
# Begin Source File
-SOURCE=..\Libraries\Source\GameSpy\GameSpy\chat\chatHandlers.h
-# End Source File
# Begin Source File
-SOURCE=..\Libraries\Source\GameSpy\GameSpy\chat\chatMain.h
-# End Source File
# Begin Source File
-SOURCE=..\Libraries\Source\GameSpy\GameSpy\chat\chatSocket.h
-# End Source File
# End Group
# Begin Group "nonport"
# PROP Default_Filter ""
# Begin Source File
-SOURCE=..\Libraries\Source\GameSpy\GameSpy\nonport.h
-# End Source File
# End Group
# Begin Group "darray"
# PROP Default_Filter ""
# Begin Source File
-SOURCE=..\Libraries\Source\GameSpy\GameSpy\darray.h
-# End Source File
# End Group
# Begin Group "peer.H"
# PROP Default_Filter ""
# Begin Source File
-SOURCE=..\Libraries\Source\GameSpy\GameSpy\peer\peer.h
-# End Source File
# Begin Source File
-SOURCE=..\Libraries\Source\GameSpy\GameSpy\peer\peerCallbacks.h
-# End Source File
# Begin Source File
-SOURCE=..\Libraries\Source\GameSpy\GameSpy\peer\peerCEngine.h
-# End Source File
# Begin Source File
-SOURCE=..\Libraries\Source\GameSpy\GameSpy\peer\peerGlobalCallbacks.h
-# End Source File
# Begin Source File
-SOURCE=..\Libraries\Source\GameSpy\GameSpy\peer\peerKeys.h
-# End Source File
# Begin Source File
-SOURCE=..\Libraries\Source\GameSpy\GameSpy\peer\peerMain.h
-# End Source File
# Begin Source File
-SOURCE=..\Libraries\Source\GameSpy\GameSpy\peer\peerMangle.h
-# End Source File
# Begin Source File
-SOURCE=..\Libraries\Source\GameSpy\GameSpy\peer\peerOperations.h
-# End Source File
# Begin Source File
-SOURCE=..\Libraries\Source\GameSpy\GameSpy\peer\peerPing.h
-# End Source File
# Begin Source File
-SOURCE=..\Libraries\Source\GameSpy\GameSpy\peer\peerPlayers.h
-# End Source File
# Begin Source File
-SOURCE=..\Libraries\Source\GameSpy\GameSpy\peer\peerRooms.h
-# End Source File
# End Group
# End Group
-# Begin Group "GameSpy.H"
-
-# PROP Default_Filter ""
-# Begin Group "Thread.H"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\Include\GameNetwork\GameSpy\BuddyThread.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Include\GameNetwork\GameSpy\GameResultsThread.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Include\GameNetwork\GameSpy\PeerThread.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Include\GameNetwork\GameSpy\PersistentStorageThread.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Include\GameNetwork\GameSpy\PingThread.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Include\GameNetwork\GameSpy\ThreadUtils.h
-# End Source File
-# End Group
-# Begin Source File
-
-SOURCE=.\Include\GameNetwork\GameSpy\BuddyDefs.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Include\GameNetwork\GameSpy\GSConfig.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Include\GameNetwork\GameSpy\LadderDefs.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Include\GameNetwork\GameSpy\LobbyUtils.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Include\GameNetwork\GameSpy\MainMenuUtils.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Include\GameNetwork\GameSpy\PeerDefs.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Include\GameNetwork\GameSpy\PeerDefsImplementation.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Include\GameNetwork\GameSpy\PersistentStorageDefs.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Include\GameNetwork\GameSpy\StagingRoomGameInfo.h
-# End Source File
# End Group
# Begin Source File
@@ -4916,34 +4717,6 @@ SOURCE=.\Include\GameNetwork\GameMessageParser.h
# End Source File
# Begin Source File
-SOURCE=.\Include\GameNetwork\GameSpy.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Include\GameNetwork\GameSpyChat.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Include\GameNetwork\GameSpyGameInfo.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Include\GameNetwork\GameSpyGP.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Include\GameNetwork\GameSpyOverlay.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Include\GameNetwork\GameSpyPersistentStorage.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Include\GameNetwork\GameSpyThread.h
-# End Source File
-# Begin Source File
-
SOURCE=.\Include\GameNetwork\GUIUtil.h
# End Source File
# Begin Source File
diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/EstablishConnectionsMenu.h b/GeneralsMD/Code/GameEngine/Include/GameClient/EstablishConnectionsMenu.h
index 7a8a8db403d..57eb0859a5a 100644
--- a/GeneralsMD/Code/GameEngine/Include/GameClient/EstablishConnectionsMenu.h
+++ b/GeneralsMD/Code/GameEngine/Include/GameClient/EstablishConnectionsMenu.h
@@ -25,7 +25,16 @@
//// EstablishConnectionsMenu.h /////////////////////////
#include "GameNetwork/NetworkDefs.h"
-#include "GameNetwork/NAT.h"
+
+// NAT traversal support has been removed; provide a minimal stub for compatibility.
+enum NATConnectionState {
+ NATCONNECTIONSTATE_WAITINGFORMANGLERRESPONSE,
+ NATCONNECTIONSTATE_WAITINGFORMANGLEDPORT,
+ NATCONNECTIONSTATE_WAITINGFORRESPONSE,
+ NATCONNECTIONSTATE_DONE,
+ NATCONNECTIONSTATE_FAILED,
+ NATCONNECTIONSTATE_WAITINGTOBEGIN
+};
enum EstablishConnectionsMenuStateType {
ESTABLISHCONNECTIONSMENUSTATETYPE_SCREENON,
diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/GUICallbacks.h b/GeneralsMD/Code/GameEngine/Include/GameClient/GUICallbacks.h
index 8d3bfd23f5d..f32301a5714 100644
--- a/GeneralsMD/Code/GameEngine/Include/GameClient/GUICallbacks.h
+++ b/GeneralsMD/Code/GameEngine/Include/GameClient/GUICallbacks.h
@@ -270,12 +270,6 @@ extern WindowMsgHandledType WOLBuddyOverlayInput( GameWindow *window, UnsignedIn
extern void WOLBuddyOverlayRCMenuInit( WindowLayout *layout, void *userData );
extern WindowMsgHandledType WOLBuddyOverlayRCMenuSystem( GameWindow *window, UnsignedInt msg, WindowMsgData mData1, WindowMsgData mData2 );
-// GameSpy Player Info Overlay ---------------------------------------------------------------------------------
-extern void GameSpyPlayerInfoOverlayInit( WindowLayout *layout, void *userData );
-extern void GameSpyPlayerInfoOverlayUpdate( WindowLayout *layout, void *userData );
-extern void GameSpyPlayerInfoOverlayShutdown( WindowLayout *layout, void *userData );
-extern WindowMsgHandledType GameSpyPlayerInfoOverlaySystem( GameWindow *window, UnsignedInt msg, WindowMsgData mData1, WindowMsgData mData2 );
-extern WindowMsgHandledType GameSpyPlayerInfoOverlayInput( GameWindow *window, UnsignedInt msg, WindowMsgData mData1, WindowMsgData mData2 );
// Popup host Game Internet -----------------------------------------------------------------------------------
extern void PopupHostGameInit( WindowLayout *layout, void *userData );
diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/LoadScreen.h b/GeneralsMD/Code/GameEngine/Include/GameClient/LoadScreen.h
index 4b0bbe457e3..80caab76a0f 100644
--- a/GeneralsMD/Code/GameEngine/Include/GameClient/LoadScreen.h
+++ b/GeneralsMD/Code/GameEngine/Include/GameClient/LoadScreen.h
@@ -258,41 +258,6 @@ class MultiPlayerLoadScreen : public LoadScreen
///////////////////////////////////////////////////////////////////////////////////////////////////
// class MultiPlayerLoadScreen is to be used for multiplayer communication on the loadscreens
//// ///////////////////////////////////////////////////////////////////////////////////////////////
-class GameSpyLoadScreen : public LoadScreen
-{
-public:
- GameSpyLoadScreen( void );
- virtual ~GameSpyLoadScreen( void );
-
- virtual void init( GameInfo *game ); ///< Init the loadscreen
- virtual void reset( void ); ///< Reset the system
- virtual void update( void )
- {
- DEBUG_CRASH(("Call update(Int) instead. This update isn't supported"));
- };
- virtual void update(Int percent); ///< Update the state of the progress bar
- void processProgress(Int playerId, Int percentage);
- virtual void setProgressRange( Int min, Int max ) { }
-private:
- GameWindow *m_progressBars[MAX_SLOTS]; ///< pointer array to all the progress bars on the window
- GameWindow *m_playerNames[MAX_SLOTS]; ///< pointer array to all the static text player names on the window
- GameWindow *m_playerSide[MAX_SLOTS]; ///< pointer array to all the static text player sides
- GameWindow *m_playerFavoriteFactions[MAX_SLOTS]; ///< pointer array to all the static text player sides
- GameWindow *m_playerTotalDisconnects[MAX_SLOTS]; ///< pointer array to all the static text player sides
- GameWindow *m_playerWin[MAX_SLOTS]; ///< pointer array to all the static text player sides
- GameWindow *m_playerWinLosses[MAX_SLOTS]; ///< pointer array to all the static text player sides
- GameWindow *m_playerRank[MAX_SLOTS]; ///< pointer array to all the static text player sides
- GameWindow *m_playerOfficerMedal[MAX_SLOTS]; ///< pointer array to all the static text player munkees
- GameWindow *m_mapPreview;
- GameWindow *m_buttonMapStartPosition[MAX_SLOTS];
-
- Int m_playerLookup[MAX_SLOTS]; ///< lookup table to translate network slot info screen slot (to account for holes in the slot list)
-
- GameWindow *m_portraitLocalGeneral;
- GameWindow *m_featuresLocalGeneral;
- GameWindow *m_nameLocalGeneral;
-};
-
///////////////////////////////////////////////////////////////////////////////////////////////////
// class MapTransferLoadScreen is to be used for map transfers before multiplayer game load screens
//// ///////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/BuddyDefs.h b/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/BuddyDefs.h
deleted file mode 100644
index 2d032020f84..00000000000
--- a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/BuddyDefs.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: BuddyDefs.h //////////////////////////////////////////////////////
-// Generals GameSpy Buddy (GP) definitions
-// Author: Matthew D. Campbell, July 2002
-
-#pragma once
-
-#ifndef __BUDDYDEFS_H__
-#define __BUDDYDEFS_H__
-
-void HandleBuddyResponses(void);
-void PopulateOldBuddyMessages(void);
-
-#endif // __BUDDYDEFS_H__
diff --git a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/BuddyThread.h b/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/BuddyThread.h
deleted file mode 100644
index 770f174053a..00000000000
--- a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/BuddyThread.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: BuddyThread.h //////////////////////////////////////////////////////
-// Generals GameSpy BuddyList thread class interface
-// Author: Matthew D. Campbell, June 2002
-
-#pragma once
-
-#ifndef __BUDDYTHREAD_H__
-#define __BUDDYTHREAD_H__
-
-#include "GameSpy/GP/GP.h"
-
-#define MAX_BUDDY_CHAT_LEN 128
-
-// this class encapsulates a request for the buddy thread
-class BuddyRequest
-{
-public:
- enum
- {
- BUDDYREQUEST_LOGIN, // attempt to login
- BUDDYREQUEST_RELOGIN, // log in after being disconnected
- BUDDYREQUEST_LOGOUT, // log out if connected
- BUDDYREQUEST_MESSAGE,
- BUDDYREQUEST_LOGINNEW, // attempt to create a new nick and login
- //BUDDYREQUEST_DELETELOGIN,
- BUDDYREQUEST_ADDBUDDY, // add someone to your buddy list
- BUDDYREQUEST_DELBUDDY, // delete someone from your buddy list
- BUDDYREQUEST_OKADD, // allow someone to add you to their buddy list
- BUDDYREQUEST_DENYADD, // don't allow someone to add you to their buddy list
- BUDDYREQUEST_SETSTATUS, // Set our status
- BUDDYREQUEST_DELETEACCT, // Delete our account
- BUDDYREQUEST_MAX
- } buddyRequestType;
-
- union
- {
- struct
- {
- GPProfile recipient;
- WideChar text[MAX_BUDDY_CHAT_LEN];
- } message;
-
- struct
- {
- char nick[GP_NICK_LEN];
- char email[GP_EMAIL_LEN];
- char password[GP_PASSWORD_LEN];
- Bool hasFirewall;
- } login;
-
- struct
- {
- GPProfile id;
- WideChar text[MAX_BUDDY_CHAT_LEN];
- } addbuddy;
-
- struct
- {
- GPProfile id;
- } profile;
-
- struct
- {
- GPEnum status;
- char statusString[GP_STATUS_STRING_LEN];
- char locationString[GP_LOCATION_STRING_LEN];
- } status;
-
- } arg;
-};
-
-//-------------------------------------------------------------------------
-
-// this class encapsulates an action the buddy thread wants from the UI
-class BuddyResponse
-{
-public:
- enum
- {
- BUDDYRESPONSE_LOGIN,
- BUDDYRESPONSE_DISCONNECT,
- BUDDYRESPONSE_MESSAGE,
- BUDDYRESPONSE_REQUEST,
- BUDDYRESPONSE_STATUS,
- BUDDYRESPONSE_MAX
- } buddyResponseType;
-
- GPProfile profile;
- GPResult result;
-
- union
- {
- struct
- {
- UnsignedInt date;
- char nick[GP_NICK_LEN];
- WideChar text[MAX_BUDDY_CHAT_LEN];
- } message;
-
- struct
- {
- char nick[GP_NICK_LEN];
- char email[GP_EMAIL_LEN];
- char countrycode[GP_COUNTRYCODE_LEN];
- WideChar text[GP_REASON_LEN];
- } request;
-
- struct
- {
- //GPResult result;
- GPErrorCode errorCode;
- char errorString[MAX_BUDDY_CHAT_LEN];
- GPEnum fatal;
- } error;
-
- struct
- {
- char nick[GP_NICK_LEN];
- char email[GP_EMAIL_LEN];
- char countrycode[GP_COUNTRYCODE_LEN];
- char location[GP_LOCATION_STRING_LEN];
- GPEnum status;
- char statusString[GP_STATUS_STRING_LEN];
- } status;
- } arg;
-};
-
-//-------------------------------------------------------------------------
-
-// this is the actual message queue used to pass messages between threads
-class GameSpyBuddyMessageQueueInterface
-{
-public:
- virtual ~GameSpyBuddyMessageQueueInterface() {}
- virtual void startThread( void ) = 0;
- virtual void endThread( void ) = 0;
- virtual Bool isThreadRunning( void ) = 0;
- virtual Bool isConnected( void ) = 0;
- virtual Bool isConnecting( void ) = 0;
-
- virtual void addRequest( const BuddyRequest& req ) = 0;
- virtual Bool getRequest( BuddyRequest& req ) = 0;
-
- virtual void addResponse( const BuddyResponse& resp ) = 0;
- virtual Bool getResponse( BuddyResponse& resp ) = 0;
-
- virtual GPProfile getLocalProfileID( void ) = 0;
-
- static GameSpyBuddyMessageQueueInterface* createNewMessageQueue( void );
-};
-
-extern GameSpyBuddyMessageQueueInterface *TheGameSpyBuddyMessageQueue;
-
-
-#endif // __BUDDYTHREAD_H__
diff --git a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/GSConfig.h b/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/GSConfig.h
deleted file mode 100644
index fb03080e9e1..00000000000
--- a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/GSConfig.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: GSConfig.h ///////////////////////////////////////////////////////////
-// Author: Matthew D. Campbell, Sept 2002
-// Description: GameSpy online config
-///////////////////////////////////////////////////////////////////////////////
-
-#pragma once
-
-#ifndef __GSCONFIG_H__
-#define __GSCONFIG_H__
-
-#include "Common/AsciiString.h"
-#include "Common/STLTypedefs.h"
-
-class GameSpyConfigInterface
-{
-public:
- virtual ~GameSpyConfigInterface() {}
-
- // Pings
- virtual std::list getPingServers(void) = 0;
- virtual Int getNumPingRepetitions(void) = 0;
- virtual Int getPingTimeoutInMs(void) = 0;
- virtual Int getPingCutoffGood( void ) = 0;
- virtual Int getPingCutoffBad( void ) = 0; //Bryan sez, Maybe
-
- // QM
- virtual std::list getQMMaps(void) = 0;
- virtual Int getQMBotID(void) = 0;
- virtual Int getQMChannel(void) = 0;
- virtual void setQMChannel(Int channel) = 0;
-
- // Player Info
- virtual Int getPointsForRank(Int rank) = 0;
- virtual Bool isPlayerVIP(Int id) = 0;
-
- // mangler Info
- virtual Bool getManglerLocation(Int index, AsciiString& host, UnsignedShort& port) = 0;
-
- // Ladder / Any other external parsing
- virtual AsciiString getLeftoverConfig(void) = 0;
-
- // Custom match
- virtual Bool restrictGamesToLobby() = 0;
- static GameSpyConfigInterface* create(AsciiString config);
-};
-
-extern GameSpyConfigInterface *TheGameSpyConfig;
-
-#endif // __GSCONFIG_H__
diff --git a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/GameResultsThread.h b/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/GameResultsThread.h
deleted file mode 100644
index 76c91675855..00000000000
--- a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/GameResultsThread.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: GameResultsThread.h //////////////////////////////////////////////////////
-// Generals game results thread class interface
-// Author: Matthew D. Campbell, August 2002
-
-#pragma once
-
-#ifndef __GAMERESULTSTHREAD_H__
-#define __GAMERESULTSTHREAD_H__
-
-#include "Common/SubsystemInterface.h"
-
-// this class encapsulates a request for the thread
-class GameResultsRequest
-{
-public:
- std::string hostname;
- UnsignedShort port;
- std::string results;
-};
-
-//-------------------------------------------------------------------------
-
-// this class encapsulates a response from the thread
-class GameResultsResponse
-{
-public:
- std::string hostname;
- UnsignedShort port;
- Bool sentOk;
-};
-
-//-------------------------------------------------------------------------
-
-// this is the actual message queue used to pass messages between threads
-class GameResultsInterface : public SubsystemInterface
-{
-public:
- virtual ~GameResultsInterface() {}
- virtual void startThreads( void ) = 0;
- virtual void endThreads( void ) = 0;
- virtual Bool areThreadsRunning( void ) = 0;
-
- virtual void addRequest( const GameResultsRequest& req ) = 0;
- virtual Bool getRequest( GameResultsRequest& resp ) = 0;
-
- virtual void addResponse( const GameResultsResponse& resp ) = 0;
- virtual Bool getResponse( GameResultsResponse& resp ) = 0;
-
- static GameResultsInterface* createNewGameResultsInterface( void );
-
- virtual Bool areGameResultsBeingSent( void ) = 0;
-};
-
-extern GameResultsInterface *TheGameResultsQueue;
-
-
-#endif // __GAMERESULTSTHREAD_H__
diff --git a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/LadderDefs.h b/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/LadderDefs.h
deleted file mode 100644
index 25d8098c2ed..00000000000
--- a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/LadderDefs.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: LadderDefs.h //////////////////////////////////////////////////////
-// Generals ladder definitions
-// Author: Matthew D. Campbell, August 2002
-
-#pragma once
-
-#ifndef __LADDERDEFS_H__
-#define __LADDERDEFS_H__
-
-#include "Common/UnicodeString.h"
-#include "Common/AsciiString.h"
-#include "Common/STLTypedefs.h"
-
-class GameWindow;
-
-class LadderInfo
-{
-public:
- LadderInfo();
- UnicodeString name;
- UnicodeString description;
- UnicodeString location;
- Int playersPerTeam;
- Int minWins;
- Int maxWins;
- Bool randomMaps;
- Bool randomFactions;
- Bool validQM;
- Bool validCustom;
- std::list validMaps;
- std::list validFactions;
- AsciiString cryptedPassword;
- AsciiString address;
- UnsignedShort port;
- AsciiString homepageURL;
- Bool submitReplay; // with game results
- Int index;
-};
-
-typedef std::list LadderInfoList;
-
-class LadderList
-{
-public:
- LadderList();
- ~LadderList();
-
- const LadderInfo* findLadder( const AsciiString& addr, UnsignedShort port );
- const LadderInfo* findLadderByIndex( Int index ); // doesn't look in local ladders
- const LadderInfoList* getLocalLadders( void );
- const LadderInfoList* getSpecialLadders( void );
- const LadderInfoList* getStandardLadders( void );
-
-private:
- void loadLocalLadders( void );
- void checkLadder( AsciiString fname, Int index );
- LadderInfoList m_localLadders;
- LadderInfoList m_specialLadders;
- LadderInfoList m_standardLadders;
-};
-
-extern LadderList *TheLadderList;
-
-#endif // __LADDERDEFS_H__
diff --git a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/LobbyUtils.h b/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/LobbyUtils.h
deleted file mode 100644
index 3cdd85cc628..00000000000
--- a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/LobbyUtils.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: LobbyUtils.h //////////////////////////////////////////////////////
-// Generals lobby utils
-// Author: Matthew D. Campbell, Sept 2002
-
-#pragma once
-
-#ifndef __LOBBYUTILS_H__
-#define __LOBBYUTILS_H__
-
-class GameWindow;
-
-GameWindow *GetGameListBox( void );
-GameWindow *GetGameInfoListBox( void );
-NameKeyType GetGameListBoxID( void );
-NameKeyType GetGameInfoListBoxID( void );
-void GrabWindowInfo( void );
-void ReleaseWindowInfo( void );
-void RefreshGameInfoListBox( GameWindow *mainWin, GameWindow *win );
-void RefreshGameListBoxes( void );
-void ToggleGameListType( void );
-
-void playerTemplateComboBoxTooltip(GameWindow *wndComboBox, WinInstanceData *instData, UnsignedInt mouse);
-void playerTemplateListBoxTooltip(GameWindow *wndListBox, WinInstanceData *instData, UnsignedInt mouse);
-
-enum GameSortType
-{
- GAMESORT_ALPHA_ASCENDING = 0,
- GAMESORT_ALPHA_DESCENDING,
- GAMESORT_PING_ASCENDING,
- GAMESORT_PING_DESCENDING,
- GAMESORT_MAX,
-};
-
-Bool HandleSortButton( NameKeyType sortButton );
-void PopulateLobbyPlayerListbox(void);
-
-#endif // __LOBBYUTILS_H__
diff --git a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/MainMenuUtils.h b/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/MainMenuUtils.h
deleted file mode 100644
index a0a8aff3dab..00000000000
--- a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/MainMenuUtils.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: MainMenuUtils.h //////////////////////////////////////////////////////
-// Author: Matthew D. Campbell, Sept 2002
-// Description: GameSpy version check, patch download, etc utils
-///////////////////////////////////////////////////////////////////////////////
-
-#pragma once
-
-#ifndef __MAINMENUUTILS_H__
-#define __MAINMENUUTILS_H__
-
-void HTTPThinkWrapper( void );
-void StopAsyncDNSCheck( void );
-void StartPatchCheck( void );
-void CancelPatchCheckCallback( void );
-void StartDownloadingPatches( void );
-void HandleCanceledDownload( Bool resetDropDown = TRUE );
-
-void CheckOverallStats( void );
-void HandleOverallStats( const char* szHTTPStats, unsigned len );
-
-void CheckNumPlayersOnline( void );
-void HandleNumPlayersOnline( Int numPlayersOnline );
-
-#endif // __MAINMENUUTILS_H__
diff --git a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/PeerDefs.h b/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/PeerDefs.h
deleted file mode 100644
index a8a5151293d..00000000000
--- a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/PeerDefs.h
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: PeerDefs.h //////////////////////////////////////////////////////
-// Generals GameSpy Peer (chat) definitions
-// Author: Matthew D. Campbell, June 2002
-
-#pragma once
-
-#ifndef __PEERDEFS_H__
-#define __PEERDEFS_H__
-
-#include "GameSpy/Peer/Peer.h"
-#include "GameSpy/GP/GP.h"
-
-#include "GameClient/Color.h"
-#include "Common/STLTypedefs.h"
-#include "GameNetwork/GameSpy/StagingRoomGameInfo.h"
-
-class GameWindow;
-class PSPlayerStats;
-
-typedef std::set IgnoreList;
-typedef std::map SavedIgnoreMap;
-
-enum RCItemType
-{
- ITEM_BUDDY,
- ITEM_REQUEST,
- ITEM_NONBUDDY,
- ITEM_NONE,
-};
-
-class GameSpyRCMenuData
-{
-public:
- AsciiString m_nick;
- GPProfile m_id;
- RCItemType m_itemType;
-};
-
-class BuddyInfo
-{
-public:
- GPProfile m_id;
- AsciiString m_name;
- AsciiString m_email;
- AsciiString m_countryCode;
- GPEnum m_status;
- UnicodeString m_statusString;
- UnicodeString m_locationString;
-};
-typedef std::map BuddyInfoMap;
-
-class BuddyMessage
-{
-public:
- UnsignedInt m_timestamp;
- GPProfile m_senderID;
- AsciiString m_senderNick;
- GPProfile m_recipientID;
- AsciiString m_recipientNick;
- UnicodeString m_message;
-};
-typedef std::list BuddyMessageList;
-
-class GameSpyGroupRoom
-{
-public:
- GameSpyGroupRoom() { m_name = AsciiString::TheEmptyString; m_translatedName = UnicodeString::TheEmptyString; m_groupID = m_numWaiting = m_maxWaiting = m_numGames = m_numPlaying = 0; }
- AsciiString m_name;
- UnicodeString m_translatedName;
- Int m_groupID;
- Int m_numWaiting;
- Int m_maxWaiting;
- Int m_numGames;
- Int m_numPlaying;
-};
-typedef std::map GroupRoomMap;
-
-class Transport;
-class NAT;
-
-typedef std::map StagingRoomMap;
-
-class PlayerInfo
-{
-public:
- PlayerInfo() { m_name = m_locale = AsciiString::TheEmptyString; m_wins = m_losses = m_rankPoints = m_side = m_preorder = m_profileID = m_flags = 0; }
- AsciiString m_name;
- AsciiString m_locale;
- Int m_wins;
- Int m_losses;
- Int m_profileID;
- Int m_flags;
- Int m_rankPoints;
- Int m_side;
- Int m_preorder;
- Bool isIgnored( void );
-};
-struct AsciiComparator
-{
- bool operator()(AsciiString s1, AsciiString s2) const;
-};
-
-
-typedef std::map PlayerInfoMap;
-
-enum GameSpyColors {
- GSCOLOR_DEFAULT = 0,
- GSCOLOR_CURRENTROOM,
- GSCOLOR_ROOM,
- GSCOLOR_GAME,
- GSCOLOR_GAME_FULL,
- GSCOLOR_GAME_CRCMISMATCH,
- GSCOLOR_PLAYER_NORMAL,
- GSCOLOR_PLAYER_OWNER,
- GSCOLOR_PLAYER_BUDDY,
- GSCOLOR_PLAYER_SELF,
- GSCOLOR_PLAYER_IGNORED,
- GSCOLOR_CHAT_NORMAL,
- GSCOLOR_CHAT_EMOTE,
- GSCOLOR_CHAT_OWNER,
- GSCOLOR_CHAT_OWNER_EMOTE,
- GSCOLOR_CHAT_PRIVATE,
- GSCOLOR_CHAT_PRIVATE_EMOTE,
- GSCOLOR_CHAT_PRIVATE_OWNER,
- GSCOLOR_CHAT_PRIVATE_OWNER_EMOTE,
- GSCOLOR_CHAT_BUDDY,
- GSCOLOR_CHAT_SELF,
- GSCOLOR_ACCEPT_TRUE,
- GSCOLOR_ACCEPT_FALSE,
- GSCOLOR_MAP_SELECTED,
- GSCOLOR_MAP_UNSELECTED,
- GSCOLOR_MOTD,
- GSCOLOR_MOTD_HEADING,
- GSCOLOR_MAX
-};
-
-extern Color GameSpyColor[GSCOLOR_MAX];
-
-enum GameSpyBuddyStatus {
- BUDDY_OFFLINE,
- BUDDY_ONLINE,
- BUDDY_LOBBY,
- BUDDY_STAGING,
- BUDDY_LOADING,
- BUDDY_PLAYING,
- BUDDY_MATCHING,
- BUDDY_MAX
-};
-
-// ---------------------------------------------------
-// this class holds info used in the main thread
-class GameSpyInfoInterface
-{
-public:
- virtual ~GameSpyInfoInterface() {};
- virtual void reset( void ) {};
- virtual void clearGroupRoomList( void ) = 0;
- virtual GroupRoomMap* getGroupRoomList( void ) = 0;
- virtual void addGroupRoom( GameSpyGroupRoom room ) = 0;
- virtual Bool gotGroupRoomList( void ) = 0;
- virtual void joinGroupRoom( Int groupID ) = 0;
- virtual void leaveGroupRoom( void ) = 0;
- virtual void joinBestGroupRoom( void ) = 0;
- virtual void setCurrentGroupRoom( Int groupID ) = 0;
- virtual Int getCurrentGroupRoom( void ) = 0;
- virtual void updatePlayerInfo( PlayerInfo pi, AsciiString oldNick = AsciiString::TheEmptyString ) = 0;
- virtual void playerLeftGroupRoom( AsciiString nick ) = 0;
- virtual PlayerInfoMap* getPlayerInfoMap( void ) = 0;
-
- virtual BuddyInfoMap* getBuddyMap( void ) = 0;
- virtual BuddyInfoMap* getBuddyRequestMap( void ) = 0;
- virtual BuddyMessageList* getBuddyMessages( void ) = 0;
- virtual Bool isBuddy( Int id ) = 0;
-
- virtual void setLocalName( AsciiString name ) = 0;
- virtual AsciiString getLocalName( void ) = 0;
- virtual void setLocalProfileID( Int profileID ) = 0;
- virtual Int getLocalProfileID( void ) = 0;
- virtual AsciiString getLocalEmail( void ) = 0;
- virtual void setLocalEmail( AsciiString email ) = 0;
- virtual AsciiString getLocalPassword( void ) = 0;
- virtual void setLocalPassword( AsciiString passwd ) = 0;
- virtual void setLocalBaseName( AsciiString name ) = 0;
- virtual AsciiString getLocalBaseName( void ) = 0;
-
- virtual void setCachedLocalPlayerStats( PSPlayerStats stats ) = 0;
- virtual PSPlayerStats getCachedLocalPlayerStats( void ) = 0;
-
- virtual void clearStagingRoomList( void ) = 0;
- virtual StagingRoomMap* getStagingRoomList( void ) = 0;
- virtual GameSpyStagingRoom* findStagingRoomByID( Int id ) = 0;
- virtual void addStagingRoom( GameSpyStagingRoom room ) = 0;
- virtual void updateStagingRoom( GameSpyStagingRoom room ) = 0;
- virtual void removeStagingRoom( GameSpyStagingRoom room ) = 0;
- virtual Bool hasStagingRoomListChanged( void ) = 0;
- virtual void leaveStagingRoom( void ) = 0;
- virtual void markAsStagingRoomHost( void ) = 0;
- virtual void markAsStagingRoomJoiner( Int game ) = 0;
- virtual void sawFullGameList( void ) = 0;
-
- virtual Bool amIHost( void ) = 0;
- virtual GameSpyStagingRoom* getCurrentStagingRoom( void ) = 0;
- virtual void setGameOptions( void ) = 0;
- virtual Int getCurrentStagingRoomID( void ) = 0;
-
- virtual void setDisallowAsianText( Bool val ) = 0;
- virtual void setDisallowNonAsianText( Bool val ) = 0;
- virtual Bool getDisallowAsianText( void ) = 0;
- virtual Bool getDisallowNonAsianText(void ) = 0;
-
- // chat
- virtual void registerTextWindow( GameWindow *win ) = 0;
- virtual void unregisterTextWindow( GameWindow *win ) = 0;
- virtual Int addText( UnicodeString message, Color c, GameWindow *win ) = 0;
- virtual void addChat( PlayerInfo p, UnicodeString msg, Bool isPublic, Bool isAction, GameWindow *win ) = 0;
- virtual void addChat( AsciiString nick, Int profileID, UnicodeString msg, Bool isPublic, Bool isAction, GameWindow *win ) = 0;
- virtual Bool sendChat( UnicodeString message, Bool isAction, GameWindow *playerListbox ) = 0;
-
- virtual void setMOTD( const AsciiString& motd ) = 0;
- virtual const AsciiString& getMOTD( void ) = 0;
-
- virtual void setConfig( const AsciiString& config ) = 0;
- virtual const AsciiString& getConfig( void ) = 0;
-
- virtual void setPingString( const AsciiString& ping ) = 0;
- virtual const AsciiString& getPingString( void ) = 0;
- virtual Int getPingValue( const AsciiString& otherPing ) = 0;
-
- static GameSpyInfoInterface* createNewGameSpyInfoInterface( void );
-
- virtual void addToSavedIgnoreList( Int profileID, AsciiString nick ) = 0;
- virtual void removeFromSavedIgnoreList( Int profileID ) = 0;
- virtual Bool isSavedIgnored( Int profileID ) = 0;
- virtual SavedIgnoreMap returnSavedIgnoreList( void ) = 0;
- virtual void loadSavedIgnoreList( void ) = 0;
-
- virtual IgnoreList returnIgnoreList( void ) = 0;
- virtual void addToIgnoreList( AsciiString nick ) = 0;
- virtual void removeFromIgnoreList( AsciiString nick ) = 0;
- virtual Bool isIgnored( AsciiString nick ) = 0;
-
- virtual void setLocalIPs(UnsignedInt internalIP, UnsignedInt externalIP) = 0;
- virtual UnsignedInt getInternalIP(void) = 0;
- virtual UnsignedInt getExternalIP(void) = 0;
-
- virtual Bool isDisconnectedAfterGameStart(Int *reason) const = 0;
- virtual void markAsDisconnectedAfterGameStart(Int reason) = 0;
-
- virtual Bool didPlayerPreorder( Int profileID ) const = 0;
- virtual void markPlayerAsPreorder( Int profileID ) = 0;
-
- virtual void setMaxMessagesPerUpdate( Int num ) = 0;
- virtual Int getMaxMessagesPerUpdate( void ) = 0;
-
- virtual Int getAdditionalDisconnects( void ) = 0;
- virtual void clearAdditionalDisconnects( void ) = 0;
- virtual void readAdditionalDisconnects( void ) = 0;
- virtual void updateAdditionalGameSpyDisconnections(Int count) = 0;
-};
-
-extern GameSpyInfoInterface *TheGameSpyInfo;
-
-void WOLDisplayGameOptions( void );
-void WOLDisplaySlotList( void );
-Bool GetLocalChatConnectionAddress(AsciiString serverName, UnsignedShort serverPort, UnsignedInt& localIP);
-void SetLobbyAttemptHostJoin(Bool start);
-void SendStatsToOtherPlayers(const GameInfo *game);
-
-class PSPlayerStats;
-void GetAdditionalDisconnectsFromUserFile(PSPlayerStats *stats);
-extern Int GetAdditionalDisconnectsFromUserFile(Int playerID);
-
-//-------------------------------------------------------------------------
-// These functions set up the globals and threads neccessary for our GameSpy impl.
-
-void SetUpGameSpy( const char *motdBuffer, const char *configBuffer );
-void TearDownGameSpy( void );
-
-#endif // __PEERDEFS_H__
diff --git a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/PeerDefsImplementation.h b/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/PeerDefsImplementation.h
deleted file mode 100644
index 30c7fcb3b06..00000000000
--- a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/PeerDefsImplementation.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: PeerDefsImplementation.h //////////////////////////////////////////////////////
-// Generals GameSpy Peer (chat) implementation definitions
-// Author: Matthew D. Campbell, Sept 2002
-
-#pragma once
-
-#ifndef __PEERDEFSIMPLEMENTATION_H__
-#define __PEERDEFSIMPLEMENTATION_H__
-
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpy/PersistentStorageThread.h"
-
-
-class GameSpyInfo : public GameSpyInfoInterface
-{
-public:
- GameSpyInfo();
- virtual ~GameSpyInfo();
- virtual void reset( void );
- virtual void clearGroupRoomList( void ) { m_groupRooms.clear(); m_gotGroupRoomList = false; }
- virtual GroupRoomMap* getGroupRoomList( void ) { return &m_groupRooms; }
- virtual void addGroupRoom( GameSpyGroupRoom room );
- virtual Bool gotGroupRoomList( void ) { return m_gotGroupRoomList; }
- virtual void joinGroupRoom( Int groupID );
- virtual void leaveGroupRoom( void );
- virtual void joinBestGroupRoom( void );
- virtual void setCurrentGroupRoom( Int groupID ) { m_currentGroupRoomID = groupID; m_playerInfoMap.clear(); }
- virtual Int getCurrentGroupRoom( void ) { return m_currentGroupRoomID; }
- virtual void updatePlayerInfo( PlayerInfo pi, AsciiString oldNick = AsciiString::TheEmptyString );
- virtual void playerLeftGroupRoom( AsciiString nick );
- virtual PlayerInfoMap* getPlayerInfoMap( void ) { return &m_playerInfoMap; }
-
- virtual void setLocalName( AsciiString name ) { m_localName = name; }
- virtual AsciiString getLocalName( void ) { return m_localName; }
- virtual void setLocalProfileID( Int profileID ) { m_localProfileID = profileID; }
- virtual Int getLocalProfileID( void ) { return m_localProfileID; }
- virtual AsciiString getLocalEmail( void ) { return m_localEmail; }
- virtual void setLocalEmail( AsciiString email ) { m_localEmail = email; }
- virtual AsciiString getLocalPassword( void ){ return m_localPasswd; }
- virtual void setLocalPassword( AsciiString passwd ) { m_localPasswd = passwd; }
- virtual void setLocalBaseName( AsciiString name ) { m_localBaseName = name; }
- virtual AsciiString getLocalBaseName( void ){ return m_localBaseName; }
- virtual void setCachedLocalPlayerStats( PSPlayerStats stats ) {m_cachedLocalPlayerStats = stats; }
- virtual PSPlayerStats getCachedLocalPlayerStats( void ){ return m_cachedLocalPlayerStats; }
-
- virtual BuddyInfoMap* getBuddyMap( void ) { return &m_buddyMap; }
- virtual BuddyInfoMap* getBuddyRequestMap( void ) { return &m_buddyRequestMap; }
- virtual BuddyMessageList* getBuddyMessages( void ) { return &m_buddyMessages; }
- virtual Bool isBuddy( Int id );
-
- virtual void clearStagingRoomList( void );
- virtual StagingRoomMap* getStagingRoomList( void ) { return &m_stagingRooms; }
- virtual GameSpyStagingRoom* findStagingRoomByID( Int id );
- virtual void addStagingRoom( GameSpyStagingRoom room );
- virtual void updateStagingRoom( GameSpyStagingRoom room );
- virtual void removeStagingRoom( GameSpyStagingRoom room );
- virtual Bool hasStagingRoomListChanged( void );
- virtual void leaveStagingRoom( void );
- virtual void markAsStagingRoomHost( void );
- virtual void markAsStagingRoomJoiner( Int game );
- virtual Int getCurrentStagingRoomID( void ) { return m_localStagingRoomID; }
-
- virtual void sawFullGameList( void ) { m_sawFullGameList = TRUE; }
-
- virtual void setDisallowAsianText( Bool val );
- virtual void setDisallowNonAsianText( Bool val );
- virtual Bool getDisallowAsianText( void );
- virtual Bool getDisallowNonAsianText(void );
- // chat
- virtual void registerTextWindow( GameWindow *win );
- virtual void unregisterTextWindow( GameWindow *win );
- virtual Int addText( UnicodeString message, Color c, GameWindow *win );
- virtual void addChat( PlayerInfo p, UnicodeString msg, Bool isPublic, Bool isAction, GameWindow *win );
- virtual void addChat( AsciiString nick, Int profileID, UnicodeString msg, Bool isPublic, Bool isAction, GameWindow *win );
- virtual Bool sendChat( UnicodeString message, Bool isAction, GameWindow *playerListbox );
-
- virtual void setMOTD( const AsciiString& motd );
- virtual const AsciiString& getMOTD( void );
- virtual void setConfig( const AsciiString& config );
- virtual const AsciiString& getConfig( void );
-
- virtual void setPingString( const AsciiString& ping ) { m_pingString = ping; }
- virtual const AsciiString& getPingString( void ) { return m_pingString; }
- virtual Int getPingValue( const AsciiString& otherPing );
-
- virtual Bool amIHost( void );
- virtual GameSpyStagingRoom* getCurrentStagingRoom( void );
- virtual void setGameOptions( void );
-
- virtual void addToIgnoreList( AsciiString nick );
- virtual void removeFromIgnoreList( AsciiString nick );
- virtual Bool isIgnored( AsciiString nick );
- virtual IgnoreList returnIgnoreList( void );
-
- virtual void loadSavedIgnoreList( void );
- virtual SavedIgnoreMap returnSavedIgnoreList( void );
- virtual void addToSavedIgnoreList( Int profileID, AsciiString nick);
- virtual void removeFromSavedIgnoreList( Int profileID );
- virtual Bool isSavedIgnored( Int profileID );
- virtual void setLocalIPs(UnsignedInt internalIP, UnsignedInt externalIP);
- virtual UnsignedInt getInternalIP(void) { return m_internalIP; }
- virtual UnsignedInt getExternalIP(void) { return m_externalIP; }
-
- virtual Bool isDisconnectedAfterGameStart(Int *reason) const { if (reason) *reason = m_disconReason; return m_isDisconAfterGameStart; }
- virtual void markAsDisconnectedAfterGameStart(Int reason) { m_isDisconAfterGameStart = TRUE; m_disconReason = reason; }
-
- virtual Bool didPlayerPreorder( Int profileID ) const;
- virtual void markPlayerAsPreorder( Int profileID );
-
- virtual void setMaxMessagesPerUpdate( Int num );
- virtual Int getMaxMessagesPerUpdate( void );
-
- virtual Int getAdditionalDisconnects( void );
- virtual void clearAdditionalDisconnects( void );
- virtual void readAdditionalDisconnects( void );
- virtual void updateAdditionalGameSpyDisconnections(Int count);
-private:
- Bool m_sawFullGameList;
- Bool m_isDisconAfterGameStart;
- Int m_disconReason;
- AsciiString m_rawMotd;
- AsciiString m_rawConfig;
- AsciiString m_pingString;
- GroupRoomMap m_groupRooms;
- StagingRoomMap m_stagingRooms;
- Bool m_stagingRoomsDirty;
- BuddyInfoMap m_buddyMap;
- BuddyInfoMap m_buddyRequestMap;
- PlayerInfoMap m_playerInfoMap;
- BuddyMessageList m_buddyMessages;
- Int m_currentGroupRoomID;
- Bool m_gotGroupRoomList;
- AsciiString m_localName;
- Int m_localProfileID;
- AsciiString m_localPasswd;
- AsciiString m_localEmail;
- AsciiString m_localBaseName;
- PSPlayerStats m_cachedLocalPlayerStats;
- Bool m_disallowAsainText;
- Bool m_disallowNonAsianText;
- UnsignedInt m_internalIP, m_externalIP;
- Int m_maxMessagesPerUpdate;
-
- Int m_joinedStagingRoom; // if we join a staging room, this holds its ID (0 otherwise)
- Bool m_isHosting; // if we host, this is true, and
- GameSpyStagingRoom m_localStagingRoom; // this holds the GameInfo for it.
- Int m_localStagingRoomID;
-
- IgnoreList m_ignoreList;
- SavedIgnoreMap m_savedIgnoreMap;
-
- std::set m_textWindows;
-
- std::set m_preorderPlayers;
- Int m_additionalDisconnects;
-};
-
-#endif // __PEERDEFS_H__
diff --git a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/PeerThread.h b/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/PeerThread.h
deleted file mode 100644
index 0b00d8375fd..00000000000
--- a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/PeerThread.h
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: PeerThread.h //////////////////////////////////////////////////////
-// Generals GameSpy Peer-to-peer chat thread class interface
-// Author: Matthew D. Campbell, June 2002
-
-#pragma once
-
-#ifndef __PEERTHREAD_H__
-#define __PEERTHREAD_H__
-
-#include "GameSpy/Peer/Peer.h"
-#include "GameNetwork/NetworkDefs.h"
-
-enum SerialAuthResult
-{
- SERIAL_NONEXISTENT,
- SERIAL_AUTHFAILED,
- SERIAL_BANNED,
- SERIAL_OK
-};
-
-// this class encapsulates a request for the peer thread
-class PeerRequest
-{
-public:
- enum
- {
- PEERREQUEST_LOGIN, // attempt to login
- PEERREQUEST_LOGOUT, // log out if connected
- PEERREQUEST_MESSAGEPLAYER,
- PEERREQUEST_MESSAGEROOM,
- PEERREQUEST_JOINGROUPROOM,
- PEERREQUEST_LEAVEGROUPROOM,
- PEERREQUEST_STARTGAMELIST,
- PEERREQUEST_STOPGAMELIST,
- PEERREQUEST_CREATESTAGINGROOM,
- PEERREQUEST_SETGAMEOPTIONS,
- PEERREQUEST_JOINSTAGINGROOM,
- PEERREQUEST_LEAVESTAGINGROOM,
- PEERREQUEST_UTMPLAYER,
- PEERREQUEST_UTMROOM,
- PEERREQUEST_STARTGAME,
- PEERREQUEST_STARTQUICKMATCH,
- PEERREQUEST_WIDENQUICKMATCHSEARCH,
- PEERREQUEST_STOPQUICKMATCH,
- PEERREQUEST_PUSHSTATS,
- PEERREQUEST_GETEXTENDEDSTAGINGROOMINFO,
- PEERREQUEST_MAX
- } peerRequestType;
-
- std::string nick; // only used by login, but must be outside the union b/c of copy constructor
- std::wstring text; // can't be in a union
- std::string password;
- std::string email;
- std::string id;
-
- // gameopts
- std::string options; // full string for UTMs
- std::string ladderIP;
- std::string hostPingStr;
- std::string gameOptsMapName;
- std::string gameOptsPlayerNames[MAX_SLOTS];
-
- std::vector qmMaps;
-
- union
- {
- struct
- {
- Int profileID;
- } login;
-
- struct
- {
- Int id;
- } groupRoom;
-
- struct
- {
- Bool restrictGameList;
- } gameList;
-
- struct
- {
- Bool isAction;
- } message;
-
- struct
- {
- Int id;
- } stagingRoom;
-
- struct
- {
- UnsignedInt exeCRC;
- UnsignedInt iniCRC;
- UnsignedInt gameVersion;
- Bool allowObservers;
- Bool useStats;
- UnsignedShort ladPort;
- UnsignedInt ladPassCRC;
- Bool restrictGameList;
- } stagingRoomCreation;
-
- struct
- {
- Int wins[MAX_SLOTS];
- Int losses[MAX_SLOTS];
- Int profileID[MAX_SLOTS];
- Int faction[MAX_SLOTS];
- Int color[MAX_SLOTS];
- Int numPlayers;
- Int maxPlayers;
- Int numObservers;
- } gameOptions;
-
- struct
- {
- Bool isStagingRoom;
- } UTM;
-
- struct
- {
- Int minPointPercentage, maxPointPercentage, points;
- Int widenTime;
- Int ladderID;
- UnsignedInt ladderPassCRC;
- Int maxPing;
- Int maxDiscons, discons;
- char pings[17]; // 8 servers (0-ff), 1 NULL
- Int numPlayers;
- Int botID;
- Int roomID;
- Int side;
- Int color;
- Int NAT;
- UnsignedInt exeCRC;
- UnsignedInt iniCRC;
- } QM;
-
- struct
- {
- Int locale;
- Int wins;
- Int losses;
- Int rankPoints;
- Int side;
- Bool preorder;
- } statsToPush;
-
- };
-};
-
-//-------------------------------------------------------------------------
-
-enum DisconnectReason
-{
- DISCONNECT_NICKTAKEN = 1,
- DISCONNECT_BADNICK,
- DISCONNECT_LOSTCON,
- DISCONNECT_COULDNOTCONNECT,
- DISCONNECT_GP_LOGIN_TIMEOUT,
- DISCONNECT_GP_LOGIN_BAD_NICK,
- DISCONNECT_GP_LOGIN_BAD_EMAIL,
- DISCONNECT_GP_LOGIN_BAD_PASSWORD,
- DISCONNECT_GP_LOGIN_BAD_PROFILE,
- DISCONNECT_GP_LOGIN_PROFILE_DELETED,
- DISCONNECT_GP_LOGIN_CONNECTION_FAILED,
- DISCONNECT_GP_LOGIN_SERVER_AUTH_FAILED,
- DISCONNECT_SERIAL_INVALID,
- DISCONNECT_SERIAL_NOT_PRESENT,
- DISCONNECT_SERIAL_BANNED,
- DISCONNECT_GP_NEWUSER_BAD_NICK,
- DISCONNECT_GP_NEWUSER_BAD_PASSWORD,
- DISCONNECT_GP_NEWPROFILE_BAD_NICK,
- DISCONNECT_GP_NEWPROFILE_BAD_OLD_NICK,
- DISCONNECT_MAX,
-};
-
-enum QMStatus
-{
- QM_IDLE,
- QM_JOININGQMCHANNEL,
- QM_LOOKINGFORBOT,
- QM_SENTINFO,
- QM_WORKING,
- QM_POOLSIZE,
- QM_WIDENINGSEARCH,
- QM_MATCHED,
- QM_INCHANNEL,
- QM_NEGOTIATINGFIREWALLS,
- QM_STARTINGGAME,
- QM_COULDNOTFINDBOT,
- QM_COULDNOTFINDCHANNEL,
- QM_COULDNOTNEGOTIATEFIREWALLS,
- QM_STOPPED,
-};
-
-// this class encapsulates an action the peer thread wants from the UI
-class PeerResponse
-{
-public:
- enum
- {
- PEERRESPONSE_LOGIN,
- PEERRESPONSE_DISCONNECT,
- PEERRESPONSE_MESSAGE,
- PEERRESPONSE_GROUPROOM,
- PEERRESPONSE_STAGINGROOM,
- PEERRESPONSE_STAGINGROOMLISTCOMPLETE,
- PEERRESPONSE_STAGINGROOMPLAYERINFO,
- PEERRESPONSE_JOINGROUPROOM,
- PEERRESPONSE_CREATESTAGINGROOM,
- PEERRESPONSE_JOINSTAGINGROOM,
- PEERRESPONSE_PLAYERJOIN,
- PEERRESPONSE_PLAYERLEFT,
- PEERRESPONSE_PLAYERCHANGEDNICK,
- PEERRESPONSE_PLAYERINFO,
- PEERRESPONSE_PLAYERCHANGEDFLAGS,
- PEERRESPONSE_ROOMUTM,
- PEERRESPONSE_PLAYERUTM,
- PEERRESPONSE_QUICKMATCHSTATUS,
- PEERRESPONSE_GAMESTART,
- PEERRESPONSE_FAILEDTOHOST,
- PEERRESPONSE_MAX
- } peerResponseType;
-
- std::string groupRoomName; // can't be in union
-
- std::string nick; // can't be in a union
- std::string oldNick; // can't be in a union
- std::wstring text; // can't be in a union
- std::string locale; // can't be in a union
-
- std::string stagingServerGameOptions; // full string from UTMs
-
- // game opts sent with PEERRESPONSE_STAGINGROOM
- std::wstring stagingServerName;
- std::string stagingServerPingString;
- std::string stagingServerLadderIP;
- std::string stagingRoomMapName;
-
- // game opts sent with PEERRESPONSE_STAGINGROOMPLAYERINFO
- std::string stagingRoomPlayerNames[MAX_SLOTS];
-
- std::string command;
- std::string commandOptions;
-
- union
- {
- struct
- {
- DisconnectReason reason;
- } discon;
-
- struct
- {
- Int id;
- Int numWaiting;
- Int maxWaiting;
- Int numGames;
- Int numPlaying;
- } groupRoom;
-
- struct
- {
- Int id;
- Bool ok;
- } joinGroupRoom;
-
- struct
- {
- Int result;
- } createStagingRoom;
-
- struct
- {
- Int id;
- Bool ok;
- Bool isHostPresent;
- Int result; // for failures
- } joinStagingRoom;
-
- struct
- {
- Bool isPrivate;
- Bool isAction;
- Int profileID;
- } message;
-
- struct
- {
- Int profileID;
- Int wins;
- Int losses;
- RoomType roomType;
- Int flags;
- UnsignedInt IP;
- Int rankPoints;
- Int side;
- Int preorder;
- UnsignedInt internalIP; // for us, on connection
- UnsignedInt externalIP; // for us, on connection
- } player;
-
- struct
- {
- Int id;
- Int action;
- Bool isStaging;
- Bool requiresPassword;
- Bool allowObservers;
- Bool useStats;
- UnsignedInt version;
- UnsignedInt exeCRC;
- UnsignedInt iniCRC;
- UnsignedShort ladderPort;
- Int wins[MAX_SLOTS];
- Int losses[MAX_SLOTS];
- Int profileID[MAX_SLOTS];
- Int faction[MAX_SLOTS];
- Int color[MAX_SLOTS];
- Int numPlayers;
- Int numObservers;
- Int maxPlayers;
- Int percentComplete;
- } stagingRoom;
-
- struct
- {
- QMStatus status;
- Int poolSize;
- Int mapIdx; // when matched
- Int seed; // when matched
- UnsignedInt IP[MAX_SLOTS]; // when matched
- Int side[MAX_SLOTS]; // when matched
- Int color[MAX_SLOTS]; // when matched
- Int nat[MAX_SLOTS];
- } qmStatus;
- };
-};
-
-//-------------------------------------------------------------------------
-
-// this is the actual message queue used to pass messages between threads
-class GameSpyPeerMessageQueueInterface
-{
-public:
- virtual ~GameSpyPeerMessageQueueInterface() {}
- virtual void startThread( void ) = 0;
- virtual void endThread( void ) = 0;
- virtual Bool isThreadRunning( void ) = 0;
- virtual Bool isConnected( void ) = 0;
- virtual Bool isConnecting( void ) = 0;
-
- virtual void addRequest( const PeerRequest& req ) = 0;
- virtual Bool getRequest( PeerRequest& req ) = 0;
-
- virtual void addResponse( const PeerResponse& resp ) = 0;
- virtual Bool getResponse( PeerResponse& resp ) = 0;
-
- virtual SerialAuthResult getSerialAuthResult( void ) = 0;
-
- static GameSpyPeerMessageQueueInterface* createNewMessageQueue( void );
-};
-
-extern GameSpyPeerMessageQueueInterface *TheGameSpyPeerMessageQueue;
-
-#endif // __PEERTHREAD_H__
diff --git a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/PersistentStorageDefs.h b/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/PersistentStorageDefs.h
deleted file mode 100644
index a480f8a9750..00000000000
--- a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/PersistentStorageDefs.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: PersistentStorageDefs.h //////////////////////////////////////////////////////
-// Generals GameSpy Persistent Storage definitions
-// Author: Matthew D. Campbell, July 2002
-
-#pragma once
-
-#ifndef __PERSISTENTSTORAGEDEFS_H__
-#define __PERSISTENTSTORAGEDEFS_H__
-
-enum LocaleType
-{
- LOC_UNKNOWN = 0,
- LOC_MIN = 1,
- LOC_MAX = 37
-};
-
-void HandlePersistentStorageResponses(void);
-void UpdateLocalPlayerStats(void);
-
-void SetLookAtPlayer( Int id, AsciiString nick );
-void PopulatePlayerInfoWindows( AsciiString parentWindowName );
-
-#endif // __PERSISTENTSTORAGEDEFS_H__
diff --git a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/PersistentStorageThread.h b/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/PersistentStorageThread.h
deleted file mode 100644
index 91c04dc0278..00000000000
--- a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/PersistentStorageThread.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: PersistentStorageThread.h //////////////////////////////////////////////////////
-// Generals GameSpy Persistent Storage thread class interface
-// Author: Matthew D. Campbell, July 2002
-
-#pragma once
-
-#ifndef __PERSISTENTSTORAGETHREAD_H__
-#define __PERSISTENTSTORAGETHREAD_H__
-
-#include "GameSpy/gstats/gpersist.h"
-
-#define MAX_BUDDY_CHAT_LEN 128
-
-typedef std::map PerGeneralMap;
-// this structure holds all info on a player that is stored online
-class PSPlayerStats
-{
-public:
- PSPlayerStats( void );
- PSPlayerStats( const PSPlayerStats& other );
- void reset(void);
-
- Int id;
- PerGeneralMap wins;
- PerGeneralMap losses;
- PerGeneralMap games; //first: playerTemplate #, second: #games played (see also gamesAsRandom)
- PerGeneralMap duration;
- PerGeneralMap unitsKilled;
- PerGeneralMap unitsLost;
- PerGeneralMap unitsBuilt;
- PerGeneralMap buildingsKilled;
- PerGeneralMap buildingsLost;
- PerGeneralMap buildingsBuilt;
- PerGeneralMap earnings;
- PerGeneralMap techCaptured;
- PerGeneralMap discons;
- PerGeneralMap desyncs;
- PerGeneralMap surrenders;
- PerGeneralMap gamesOf2p;
- PerGeneralMap gamesOf3p;
- PerGeneralMap gamesOf4p;
- PerGeneralMap gamesOf5p;
- PerGeneralMap gamesOf6p;
- PerGeneralMap gamesOf7p;
- PerGeneralMap gamesOf8p;
- PerGeneralMap customGames;
- PerGeneralMap QMGames;
- Int locale;
- Int gamesAsRandom;
- std::string options;
- std::string systemSpec;
- Real lastFPS;
- Int lastGeneral;
- Int gamesInRowWithLastGeneral;
- Int challengeMedals;
- Int battleHonors;
- Int QMwinsInARow;
- Int maxQMwinsInARow;
-
- Int winsInARow;
- Int maxWinsInARow;
- Int lossesInARow;
- Int maxLossesInARow;
- Int disconsInARow;
- Int maxDisconsInARow;
- Int desyncsInARow;
- Int maxDesyncsInARow;
-
- Int builtParticleCannon;
- Int builtNuke;
- Int builtSCUD;
-
- Int lastLadderPort;
- std::string lastLadderHost;
-
- void incorporate( const PSPlayerStats& other );
-};
-
-// this class encapsulates a request for the thread
-class PSRequest
-{
-public:
- PSRequest();
- enum
- {
- PSREQUEST_READPLAYERSTATS, // read stats for a player
- PSREQUEST_UPDATEPLAYERSTATS, // update stats on the server
- PSREQUEST_UPDATEPLAYERLOCALE, // update locale on the server
- PSREQUEST_READCDKEYSTATS, // read stats for a cdkey
- PSREQUEST_SENDGAMERESTOGAMESPY, // report game results to GameSpy
- PSREQUEST_MAX
- } requestType;
-
- // player stats for the *PLAYERSTATS
- PSPlayerStats player;
-
- // cdkey for READCDKEYSTATS;
- std::string cdkey;
-
- // our info for UPDATEPLAYERSTATS
- std::string nick;
- std::string password;
- std::string email;
- Bool addDiscon;
- Bool addDesync;
- Int lastHouse;
-
- // for GameRes
- std::string results;
-};
-
-//-------------------------------------------------------------------------
-
-// this class encapsulates a response from the thread
-class PSResponse
-{
-public:
- enum
- {
- PSRESPONSE_PLAYERSTATS,
- PSRESPONSE_COULDNOTCONNECT,
- PSRESPONSE_PREORDER,
- PSRESPONSE_MAX
- } responseType;
-
- // player stats for the *PLAYERSTATS
- PSPlayerStats player;
-
- // preorder flag
- Bool preorder;
-};
-
-//-------------------------------------------------------------------------
-
-// this is the actual message queue used to pass messages between threads
-class GameSpyPSMessageQueueInterface
-{
-public:
- virtual ~GameSpyPSMessageQueueInterface() {}
- virtual void startThread( void ) = 0;
- virtual void endThread( void ) = 0;
- virtual Bool isThreadRunning( void ) = 0;
-
- virtual void addRequest( const PSRequest& req ) = 0;
- virtual Bool getRequest( PSRequest& req ) = 0;
-
- virtual void addResponse( const PSResponse& resp ) = 0;
- virtual Bool getResponse( PSResponse& resp ) = 0;
-
- // called from the main thread
- virtual void trackPlayerStats( PSPlayerStats stats ) = 0;
- virtual PSPlayerStats findPlayerStatsByID( Int id ) = 0;
-
- static GameSpyPSMessageQueueInterface* createNewMessageQueue( void );
-
- static std::string formatPlayerKVPairs( PSPlayerStats stats );
- static PSPlayerStats parsePlayerKVPairs( std::string kvPairs );
-};
-
-extern GameSpyPSMessageQueueInterface *TheGameSpyPSMessageQueue;
-
-
-#endif // __PERSISTENTSTORAGETHREAD_H__
diff --git a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/PingThread.h b/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/PingThread.h
deleted file mode 100644
index 4661de891bb..00000000000
--- a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/PingThread.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: PingThread.h //////////////////////////////////////////////////////
-// Generals ping thread class interface
-// Author: Matthew D. Campbell, August 2002
-// Note: adapted from WOLAPI
-
-#pragma once
-
-#ifndef __PINGTHREAD_H__
-#define __PINGTHREAD_H__
-
-// this class encapsulates a request for the thread
-class PingRequest
-{
-public:
- std::string hostname;
- Int repetitions;
- Int timeout;
-};
-
-//-------------------------------------------------------------------------
-
-// this class encapsulates a response from the thread
-class PingResponse
-{
-public:
- std::string hostname;
- Int avgPing;
- Int repetitions;
-};
-
-//-------------------------------------------------------------------------
-
-// this is the actual message queue used to pass messages between threads
-class PingerInterface
-{
-public:
- virtual ~PingerInterface() {}
- virtual void startThreads( void ) = 0;
- virtual void endThreads( void ) = 0;
- virtual Bool areThreadsRunning( void ) = 0;
-
- virtual void addRequest( const PingRequest& req ) = 0;
- virtual Bool getRequest( PingRequest& resp ) = 0;
-
- virtual void addResponse( const PingResponse& resp ) = 0;
- virtual Bool getResponse( PingResponse& resp ) = 0;
-
- static PingerInterface* createNewPingerInterface( void );
-
- virtual Bool arePingsInProgress( void ) = 0;
- virtual Int getPing( AsciiString hostname ) = 0;
- virtual void clearPingMap( void ) = 0;
- virtual AsciiString getPingString( Int timeout ) = 0;
-};
-
-extern PingerInterface *ThePinger;
-
-
-#endif // __PINGTHREAD_H__
diff --git a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/StagingRoomGameInfo.h b/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/StagingRoomGameInfo.h
deleted file mode 100644
index e7cd2bd4e4b..00000000000
--- a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/StagingRoomGameInfo.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: StagingRoomGameInfo.h //////////////////////////////////////////////////////
-// Generals GameSpy GameInfo
-// Author: Matthew D. Campbell, Sept 2002
-
-#pragma once
-
-#ifndef __STAGINGROOMGAMEINFO_H__
-#define __STAGINGROOMGAMEINFO_H__
-
-#include "GameNetwork/GameInfo.h"
-#include "GameNetwork/Transport.h"
-
-class GameSpyGameSlot : public GameSlot
-{
-public:
- GameSpyGameSlot();
- Int getProfileID( void ) const { return m_profileID; }
- void setProfileID( Int id ) { m_profileID = id; }
- AsciiString getLoginName( void ) const { return m_gameSpyLogin; }
- void setLoginName( AsciiString name ) { m_gameSpyLogin = name; }
- AsciiString getLocale( void ) const { return m_gameSpyLocale; }
- void setLocale( AsciiString name ) { m_gameSpyLocale = name; }
- Int getWins( void ) const { return m_wins; }
- Int getLosses( void ) const { return m_losses; }
- void setWins( Int wins ) { m_wins = wins; }
- void setLosses( Int losses ) { m_losses = losses; }
-
- Int getSlotRankPoints( void ) const { return m_rankPoints; }
- Int getFavoriteSide( void ) const { return m_favoriteSide; }
- void setSlotRankPoints( Int val ) { m_rankPoints = val; }
- void setFavoriteSide( Int val ) { m_favoriteSide = val; }
-
- void setPingString( AsciiString pingStr );
- inline AsciiString getPingString( void ) const { return m_pingStr; }
- inline Int getPingAsInt( void ) const { return m_pingInt; }
-
-protected:
- Int m_profileID;
- AsciiString m_gameSpyLogin;
- AsciiString m_gameSpyLocale;
-
- AsciiString m_pingStr;
- Int m_pingInt;
- Int m_wins, m_losses;
- Int m_rankPoints, m_favoriteSide;
-};
-
-/**
- * GameSpyStagingRoom class - maintains information about the GameSpy game and
- * the contents of its slot list throughout the game.
- */
-class GameSpyStagingRoom : public GameInfo
-{
-private:
- GameSpyGameSlot m_GameSpySlot[MAX_SLOTS]; ///< The GameSpy Games Slot List
- UnicodeString m_gameName;
- Int m_id;
- Transport *m_transport;
- AsciiString m_localName;
- Bool m_requiresPassword;
- Bool m_allowObservers;
- UnsignedInt m_version;
- UnsignedInt m_exeCRC;
- UnsignedInt m_iniCRC;
- Bool m_isQM;
-
- AsciiString m_ladderIP;
- AsciiString m_pingStr;
- Int m_pingInt;
- UnsignedShort m_ladderPort;
-
- Int m_reportedNumPlayers;
- Int m_reportedMaxPlayers;
- Int m_reportedNumObservers;
-
-public:
- GameSpyStagingRoom();
- virtual void reset( void );
-
- void cleanUpSlotPointers(void);
- inline void setID(Int id) { m_id = id; }
- inline Int getID( void ) const { return m_id; }
-
- inline void setHasPassword(Bool val) { m_requiresPassword = val; }
- inline Bool getHasPassword(void) const { return m_requiresPassword; }
- inline void setAllowObservers(Bool val) { m_allowObservers = val; }
- inline Bool getAllowObservers(void) const { return m_allowObservers; }
-
- inline void setVersion(UnsignedInt val) { m_version = val; }
- inline UnsignedInt getVersion(void) const { return m_version; }
- inline void setExeCRC(UnsignedInt val) { m_exeCRC = val; }
- inline UnsignedInt getExeCRC(void) const { return m_exeCRC; }
- inline void setIniCRC(UnsignedInt val) { m_iniCRC = val; }
- inline UnsignedInt getIniCRC(void) const { return m_iniCRC; }
-
- inline void setReportedNumPlayers(Int val) { m_reportedNumPlayers = val; }
- inline Int getReportedNumPlayers(void) const { return m_reportedNumPlayers; }
-
- inline void setReportedMaxPlayers(Int val) { m_reportedMaxPlayers = val; }
- inline Int getReportedMaxPlayers(void) const { return m_reportedMaxPlayers; }
-
- inline void setReportedNumObservers(Int val) { m_reportedNumObservers = val; }
- inline Int getReportedNumObservers(void) const { return m_reportedNumObservers; }
-
- inline void setLadderIP( AsciiString ladderIP ) { m_ladderIP = ladderIP; }
- inline AsciiString getLadderIP( void ) const { return m_ladderIP; }
- inline void setLadderPort( UnsignedShort ladderPort ) { m_ladderPort = ladderPort; }
- inline UnsignedShort getLadderPort( void ) const { return m_ladderPort; }
- void setPingString( AsciiString pingStr );
- inline AsciiString getPingString( void ) const { return m_pingStr; }
- inline Int getPingAsInt( void ) const { return m_pingInt; }
-
- virtual Bool amIHost( void ) const; ///< Convenience function - is the local player the game host?
-
- GameSpyGameSlot *getGameSpySlot( Int index );
-
- AsciiString generateGameSpyGameResultsPacket( void );
- AsciiString generateLadderGameResultsPacket( void );
- void markGameAsQM( void ) { m_isQM = TRUE; }
- Bool isQMGame( void ) { return m_isQM; }
-
- virtual void init(void);
- virtual void resetAccepted(void); ///< Reset the accepted flag on all players
-
- virtual void startGame(Int gameID); ///< Mark our game as started and record the game ID.
- void launchGame( void ); ///< NAT negotiation has finished - really start
- virtual Int getLocalSlotNum( void ) const; ///< Get the local slot number, or -1 if we're not present
-
- inline void setGameName( UnicodeString name ) { m_gameName = name; }
- inline UnicodeString getGameName( void ) const { return m_gameName; }
-
- inline void setLocalName( AsciiString name ) { m_localName = name; }
-};
-
-extern GameSpyStagingRoom *TheGameSpyGame;
-
-#endif // __STAGINGROOMGAMEINFO_H__
diff --git a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/ThreadUtils.h b/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/ThreadUtils.h
deleted file mode 100644
index 7dd7c6fa3fc..00000000000
--- a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpy/ThreadUtils.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: ThreadUtils.h //////////////////////////////////////////////////////
-// Generals GameSpy thread utils
-// Author: Matthew D. Campbell, July 2002
-
-#pragma once
-
-#ifndef __GAMESPY_THREADUTILS_H__
-#define __GAMESPY_THREADUTILS_H__
-
-std::wstring MultiByteToWideCharSingleLine( const char *orig );
-std::string WideCharStringToMultiByte( const WideChar *orig );
-
-#endif // __GAMESPY_THREADUTILS_H__
diff --git a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpyChat.h b/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpyChat.h
deleted file mode 100644
index 1d3bca8f550..00000000000
--- a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpyChat.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: GameSpyChat.h //////////////////////////////////////////////////////
-// Generals GameSpy Chat
-// Author: Matthew D. Campbell, February 2002
-
-#pragma once
-
-#ifndef __GAMESPYCHAT_H__
-#define __GAMESPYCHAT_H__
-
-#include "GameSpy/Peer/Peer.h"
-
-class GameWindow;
-class WindowLayout;
-
-Bool GameSpySendChat(UnicodeString message, Bool isEmote, GameWindow *playerListbox = NULL);
-void GameSpyAddText( UnicodeString message, GameSpyColors color = GSCOLOR_DEFAULT );
-
-extern GameWindow *progressTextWindow; ///< Text box on the progress screen
-extern GameWindow *quickmatchTextWindow; ///< Text box on the quickmatch screen
-extern GameWindow *quickmatchTextWindow; ///< Text box on the quickmatch screen
-extern GameWindow *listboxLobbyChat; ///< Chat box on the custom lobby screen
-extern GameWindow *listboxLobbyPlayers; ///< Player box on the custom lobby screen
-extern GameWindow *listboxLobbyGames; ///< Game box on the custom lobby screen
-extern GameWindow *listboxLobbyChatChannels; ///< Chat channel box on the custom lobby screen
-extern GameWindow *listboxGameSetupChat; ///< Chat box on the custom game setup screen
-extern WindowLayout *WOLMapSelectLayout; ///< Map selection overlay
-
-void RoomMessageCallback(PEER peer, RoomType roomType,
- const char * nick, const char * message,
- MessageType messageType, void * param); ///< Called when a message arrives in a room.
-
-void PlayerMessageCallback(PEER peer, const char * nick,
- const char * message, MessageType messageType,
- void * param); ///< Called when a private message is received from another player.
-
-#endif // __GAMESPYCHAT_H__
diff --git a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpyGP.h b/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpyGP.h
deleted file mode 100644
index 79c4d825fd2..00000000000
--- a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpyGP.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: GameSpyGP.h //////////////////////////////////////////////////////
-// Generals GameSpy GP (Buddy)
-// Author: Matthew D. Campbell, March 2002
-
-#pragma once
-
-#ifndef __GAMESPYGP_H__
-#define __GAMESPYGP_H__
-
-#include "GameSpy/GP/GP.h"
-
-void GPRecvBuddyRequestCallback(GPConnection * connection, GPRecvBuddyRequestArg * arg, void * param);
-void GPRecvBuddyMessageCallback(GPConnection * pconnection, GPRecvBuddyMessageArg * arg, void * param);
-void GPRecvBuddyStatusCallback(GPConnection * connection, GPRecvBuddyStatusArg * arg, void * param);
-void GPErrorCallback(GPConnection * pconnection, GPErrorArg * arg, void * param);
-void GPConnectCallback(GPConnection * pconnection, GPConnectResponseArg * arg, void * param);
-void GameSpyUpdateBuddyOverlay(void);
-
-extern GPConnection *TheGPConnection;
-
-Bool IsGameSpyBuddy(GPProfile id);
-
-#endif // __GAMESPYGP_H__
diff --git a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpyGameInfo.h b/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpyGameInfo.h
deleted file mode 100644
index 0652c08be0d..00000000000
--- a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpyGameInfo.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: GameSpyGameInfo.h //////////////////////////////////////////////////////
-// Generals GameSpy game setup information
-// Author: Matthew D. Campbell, February 2002
-
-#pragma once
-
-#error this file is obsolete
-
-#ifndef __GAMESPYGAMEINFO_H__
-#define __GAMESPYGAMEINFO_H__
-
-#include "GameSpy/Peer/Peer.h"
-
-#include "GameNetwork/GameInfo.h"
-
-class Transport;
-class NAT;
-
-class GameSpyGameSlot : public GameSlot
-{
-public:
- GameSpyGameSlot();
- Int getProfileID( void ) { return m_profileID; }
- void setProfileID( Int id ) { m_profileID = id; }
- AsciiString getLoginName( void ) { return m_gameSpyLogin; }
- void setLoginName( AsciiString name ) { m_gameSpyLogin = name; }
- AsciiString getLocale( void ) { return m_gameSpyLocale; }
- void setLocale( AsciiString name ) { m_gameSpyLocale = name; }
-protected:
- Int m_profileID;
- AsciiString m_gameSpyLogin;
- AsciiString m_gameSpyLocale;
-};
-
-/**
- * GameSpyGameInfo class - maintains information about the GameSpy game and
- * the contents of its slot list throughout the game.
- */
-class GameSpyGameInfo : public GameInfo
-{
-private:
- GameSpyGameSlot m_GameSpySlot[MAX_SLOTS]; ///< The GameSpy Games Slot List
- SBServer m_server;
- Bool m_hasBeenQueried;
- Transport *m_transport;
- Bool m_isQM;
-
-public:
- GameSpyGameInfo();
-
- inline void setServer(SBServer server) { m_server = server; }
- inline SBServer getServer( void ) { return m_server; }
-
- AsciiString generateGameResultsPacket( void );
-
- virtual void init(void);
- virtual void resetAccepted(void); ///< Reset the accepted flag on all players
-
- void markGameAsQM( void ) { m_isQM = TRUE; }
- virtual void startGame(Int gameID); ///< Mark our game as started and record the game ID.
- virtual Int getLocalSlotNum( void ) const; ///< Get the local slot number, or -1 if we're not present
-
- void gotGOACall( void ); ///< Mark the game info as having been queried
-};
-
-extern GameSpyGameInfo *TheGameSpyGame;
-
-void WOLDisplayGameOptions( void );
-void WOLDisplaySlotList( void );
-void GameSpyStartGame( void );
-void GameSpyLaunchGame( void );
-Bool GetLocalChatConnectionAddress(AsciiString serverName, UnsignedShort serverPort, UnsignedInt& localIP);
-
-#endif // __LANGAMEINFO_H__
diff --git a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpyOverlay.h b/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpyOverlay.h
deleted file mode 100644
index d41f96a57a8..00000000000
--- a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpyOverlay.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: GamespyOverlay.h //////////////////////////////////////////////////////
-// Generals GameSpy overlay screens
-// Author: Matthew D. Campbell, March 2002
-
-#pragma once
-
-#ifndef __GAMESPYOVERLAY_H__
-#define __GAMESPYOVERLAY_H__
-
-#include "Common/NameKeyGenerator.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/Shell.h"
-#include "GameClient/KeyDefs.h"
-#include "GameClient/GameWindowManager.h"
-
-void ClearGSMessageBoxes( void ); ///< Tear down any GS message boxes (e.g. in case we have a new one to put up)
-void GSMessageBoxOk(UnicodeString titleString,UnicodeString bodyString, GameWinMsgBoxFunc okFunc = NULL); ///< Display a Message box with Ok button and track it
-void GSMessageBoxOkCancel(UnicodeString title, UnicodeString message, GameWinMsgBoxFunc okFunc, GameWinMsgBoxFunc cancelFunc); ///< Display a Message box with Ok/Cancel buttons and track it
-void GSMessageBoxYesNo(UnicodeString title, UnicodeString message, GameWinMsgBoxFunc yesFunc, GameWinMsgBoxFunc noFunc); ///< Display a Message box with Yes/No buttons and track it
-void RaiseGSMessageBox( void ); ///< Bring GS message box to the foreground (if we transition screens while a message box is up)
-
-enum GSOverlayType
-{
- GSOVERLAY_PLAYERINFO,
- GSOVERLAY_MAPSELECT,
- GSOVERLAY_BUDDY,
- GSOVERLAY_PAGE,
- GSOVERLAY_GAMEOPTIONS,
- GSOVERLAY_GAMEPASSWORD,
- GSOVERLAY_LADDERSELECT,
- GSOVERLAY_LOCALESELECT,
- GSOVERLAY_OPTIONS,
- GSOVERLAY_MAX
-};
-
-void GameSpyOpenOverlay( GSOverlayType );
-void GameSpyCloseOverlay( GSOverlayType );
-void GameSpyCloseAllOverlays( void );
-Bool GameSpyIsOverlayOpen( GSOverlayType );
-void GameSpyToggleOverlay( GSOverlayType );
-void GameSpyUpdateOverlays( void );
-void ReOpenPlayerInfo( void );
-void CheckReOpenPlayerInfo(void );
-#endif // __GAMESPYOVERLAY_H__
diff --git a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpyThread.h b/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpyThread.h
deleted file mode 100644
index 11e8040027c..00000000000
--- a/GeneralsMD/Code/GameEngine/Include/GameNetwork/GameSpyThread.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: GameSpyThread.h //////////////////////////////////////////////////////
-// Generals GameSpy thread class
-// Author: Matthew D. Campbell, March 2002
-
-#pragma once
-
-#ifndef __GAMESPYTHREAD_H__
-#define __GAMESPYTHREAD_H__
-
-#include "mutex.h"
-#include "thread.h"
-
-class GameSpyThreadClass : public ThreadClass
-{
-
-public:
- GameSpyThreadClass::GameSpyThreadClass() : ThreadClass() { m_doLogin = false; m_readStats = false; m_updateWins = false; m_updateLosses = false; m_updateLocale = false; m_showLocaleSelect = false; m_nextShellScreen.clear(); }
- void queueLogin(AsciiString nick, AsciiString pass, AsciiString email) { m_nick = nick; m_pass = pass; m_email = email; m_doLogin = true; }
- void queueReadPersistentStatsFromServer( void ) { m_readStats = true; }
- void queueUpdateLocale( AsciiString locale ) { m_locale = locale; m_updateLocale = true; }
- void queueUpdateWins ( AsciiString wins ) { m_wins = wins; m_updateWins = true; }
- void queueUpdateLosses( AsciiString losses ) { m_losses = losses; m_updateLosses = true; }
-
- void Thread_Function();
-
- AsciiString getNextShellScreen( void );
- Bool showLocaleSelect( void );
-
- void setNextShellScreen( AsciiString nextShellScreen );
- void setShowLocaleSelect( Bool val );
-
-private:
- AsciiString m_nick, m_pass, m_email;
- Bool m_doLogin, m_readStats, m_updateWins, m_updateLosses, m_updateLocale;
- AsciiString m_locale, m_wins, m_losses;
- AsciiString m_nextShellScreen;
- Bool m_showLocaleSelect;
-};
-
-extern GameSpyThreadClass *TheGameSpyThread;
-extern MutexClass TheGameSpyMutex;
-
-#endif // __GAMESPYTHREAD_H__
diff --git a/GeneralsMD/Code/GameEngine/Include/GameNetwork/NAT.h b/GeneralsMD/Code/GameEngine/Include/GameNetwork/NAT.h
deleted file mode 100644
index 3f8e2cac3a3..00000000000
--- a/GeneralsMD/Code/GameEngine/Include/GameNetwork/NAT.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: NAT.h /////////////////////////////////////////////////////////////////////////////////
-// Author: Bryan Cleveland April 2002
-// Desc: Resolves NAT'd IPs and port numbers for the other players in a game.
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-#pragma once
-
-#ifndef __NAT_H
-#define __NAT_H
-
-#include "Lib\BaseType.h"
-#include "GameNetwork/NetworkInterface.h"
-#include "GameNetwork/FirewallHelper.h"
-
-class Transport;
-class GameSlot;
-
-enum NATStateType {
- NATSTATE_IDLE,
- NATSTATE_DOCONNECTIONPATHS,
- NATSTATE_WAITFORSTATS,
- NATSTATE_DONE,
- NATSTATE_FAILED
-};
-
-enum NATConnectionState {
- NATCONNECTIONSTATE_NOSTATE,
- NATCONNECTIONSTATE_WAITINGTOBEGIN,
-// NATCONNECTIONSTATE_NETGEARDELAY,
- NATCONNECTIONSTATE_WAITINGFORMANGLERRESPONSE,
- NATCONNECTIONSTATE_WAITINGFORMANGLEDPORT,
- NATCONNECTIONSTATE_WAITINGFORRESPONSE,
- NATCONNECTIONSTATE_DONE,
- NATCONNECTIONSTATE_FAILED
-};
-
-struct ConnectionNodeType {
- FirewallHelperClass::tFirewallBehaviorType m_behavior; ///< the NAT/Firewall behavior of this node.
- UnsignedInt m_slotIndex; ///< the player list index of this node.
-};
-
-class NAT {
-public:
- NAT();
- virtual ~NAT();
-
- NATStateType update();
-
- void attachSlotList(GameSlot **slotList, Int localSlot, UnsignedInt localIP);
- void establishConnectionPaths();
-
- Int getSlotPort(Int slot);
- Transport * getTransport(); ///< return the newly created Transport layer that has all the connections and whatnot.
-
- // Notification messages from GameSpy
- void processGlobalMessage(Int slotNum, const char *options);
-
-protected:
- NATConnectionState connectionUpdate(); ///< the update function for the connections.
- void sendMangledSourcePort(); ///< starts the process to get the next mangled source port.
- void processManglerResponse(UnsignedShort mangledPort);
-
- Bool allConnectionsDoneThisRound();
- Bool allConnectionsDone();
-
- void generatePortNumbers(GameSlot **slotList, Int localSlot); ///< generate all of the slots' port numbers to be used.
-
- void doThisConnectionRound(); ///< compute who will connect with who for this round.
- void setConnectionState(Int nodeNumber, NATConnectionState state); ///< central point for changing a connection's state.
- void sendAProbe(UnsignedInt ip, UnsignedShort port, Int fromNode); ///< send a "PROBE" packet to this IP and port.
- void notifyTargetOfProbe(GameSlot *targetSlot);
- void notifyUsersOfConnectionDone(Int nodeIndex);
- void notifyUsersOfConnectionFailed(Int nodeIndex);
- void sendMangledPortNumberToTarget(UnsignedShort mangledPort, GameSlot *targetSlot);
-
- void probed(Int nodeNumber);
- void gotMangledPort(Int nodeNumber, UnsignedShort mangledPort);
- void gotInternalAddress(Int nodeNumber, UnsignedInt address);
- void connectionComplete(Int slotIndex);
- void connectionFailed(Int slotIndex);
-
- Transport *m_transport;
- GameSlot **m_slotList;
- NATStateType m_NATState;
- Int m_localNodeNumber; ///< The node number of the local player.
- Int m_targetNodeNumber; ///< The node number of the player we are connecting to this round.
- UnsignedInt m_localIP; ///< The IP of the local computer.
- UnsignedInt m_numNodes; ///< The number of players we have to connect together.
- UnsignedInt m_connectionRound; ///< The "round" of connections we are currently on.
-
- Int m_numRetries;
- Int m_maxNumRetriesAllowed;
-
- UnsignedShort m_packetID;
- UnsignedShort m_spareSocketPort;
- time_t m_manglerRetryTime;
- Int m_manglerRetries;
- UnsignedShort m_previousSourcePort;
-
- Bool m_beenProbed; ///< have I been notified that I've been probed this round?
-
- UnsignedInt m_manglerAddress;
-
- time_t m_timeTillNextSend; ///< The number of milliseconds till we send to the other guy's port again.
- NATConnectionState m_connectionStates[MAX_SLOTS]; ///< connection states for this round for all the nodes.
-
- ConnectionNodeType m_connectionNodes[MAX_SLOTS]; ///< info regarding the nodes that are being connected.
-
- UnsignedShort m_sourcePorts[MAX_SLOTS]; ///< the source ports that the other players communicate to us on.
-
- Bool m_myConnections[MAX_SLOTS]; ///< keeps track of all the nodes I've connected to. For keepalive.
- time_t m_nextKeepaliveTime; ///< the next time we will send out our keepalive packets.
-
- static Int m_connectionPairs[MAX_SLOTS-1][MAX_SLOTS-1][MAX_SLOTS];
- Int m_connectionPairIndex;
-
- UnsignedShort m_startingPortNumber; ///< the starting port number for this game. The slots all get port numbers with their port numbers based on this number.
- ///< this is done so that games that are played right after each other with the same players in the same
- ///< slot order will not use the old source port allocation scheme in case their NAT
- ///< hasn't timed out that connection.
-
- time_t m_nextPortSendTime; ///< Last time we sent our mangled port number to our target this round.
-
- time_t m_timeoutTime; ///< the time at which we will time out waiting for the other player's port number.
- time_t m_roundTimeout; ///< the time at which we will time out this connection round.
-
- static Int m_timeBetweenRetries; // 1 second between retries sounds good to me.
- static time_t m_manglerRetryTimeInterval; // sounds good to me.
- static Int m_maxAllowedManglerRetries; // works for me.
- static time_t m_keepaliveInterval; // 15 seconds between keepalive packets seems good.
- static time_t m_timeToWaitForPort; // wait for ten seconds for the other player's port number.
- static time_t m_timeForRoundTimeout; // wait for at most ten seconds for each connection round to finish.
-
-};
-
-extern NAT *TheNAT;
-
-#endif // #ifndef __NAT_H
\ No newline at end of file
diff --git a/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp b/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp
index ba20321e594..9807c695e97 100644
--- a/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp
+++ b/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp
@@ -103,7 +103,6 @@
#include "GameNetwork/NetworkInterface.h"
#include "GameNetwork/LANAPI.h"
-#include "GameNetwork/GameSpy/GameResultsThread.h"
#include "Common/Version.h"
diff --git a/GeneralsMD/Code/GameEngine/Source/Common/System/FunctionLexicon.cpp b/GeneralsMD/Code/GameEngine/Source/Common/System/FunctionLexicon.cpp
index 2f6a9569dc3..74db38eddf5 100644
--- a/GeneralsMD/Code/GameEngine/Source/Common/System/FunctionLexicon.cpp
+++ b/GeneralsMD/Code/GameEngine/Source/Common/System/FunctionLexicon.cpp
@@ -121,7 +121,6 @@ static FunctionLexicon::TableEntry gameWinSystemTable[] =
{ NAMEKEY_INVALID, "WOLBuddyOverlaySystem", WOLBuddyOverlaySystem },
{ NAMEKEY_INVALID, "WOLBuddyOverlayRCMenuSystem", WOLBuddyOverlayRCMenuSystem },
{ NAMEKEY_INVALID, "RCGameDetailsMenuSystem", RCGameDetailsMenuSystem },
- { NAMEKEY_INVALID, "GameSpyPlayerInfoOverlaySystem",GameSpyPlayerInfoOverlaySystem },
{ NAMEKEY_INVALID, "WOLMessageWindowSystem", WOLMessageWindowSystem },
{ NAMEKEY_INVALID, "WOLQuickMatchMenuSystem", WOLQuickMatchMenuSystem },
{ NAMEKEY_INVALID, "WOLWelcomeMenuSystem", WOLWelcomeMenuSystem },
@@ -192,7 +191,6 @@ static FunctionLexicon::TableEntry gameWinInputTable[] =
{ NAMEKEY_INVALID, "WOLGameSetupMenuInput", WOLGameSetupMenuInput },
{ NAMEKEY_INVALID, "WOLMapSelectMenuInput", WOLMapSelectMenuInput },
{ NAMEKEY_INVALID, "WOLBuddyOverlayInput", WOLBuddyOverlayInput },
- { NAMEKEY_INVALID, "GameSpyPlayerInfoOverlayInput", GameSpyPlayerInfoOverlayInput },
{ NAMEKEY_INVALID, "WOLMessageWindowInput", WOLMessageWindowInput },
{ NAMEKEY_INVALID, "WOLQuickMatchMenuInput", WOLQuickMatchMenuInput },
{ NAMEKEY_INVALID, "WOLWelcomeMenuInput", WOLWelcomeMenuInput },
@@ -266,7 +264,6 @@ static FunctionLexicon::TableEntry winLayoutInitTable[] =
{ NAMEKEY_INVALID, "WOLBuddyOverlayInit", WOLBuddyOverlayInit },
{ NAMEKEY_INVALID, "WOLBuddyOverlayRCMenuInit", WOLBuddyOverlayRCMenuInit },
{ NAMEKEY_INVALID, "RCGameDetailsMenuInit", RCGameDetailsMenuInit },
- { NAMEKEY_INVALID, "GameSpyPlayerInfoOverlayInit", GameSpyPlayerInfoOverlayInit },
{ NAMEKEY_INVALID, "WOLMessageWindowInit", WOLMessageWindowInit },
{ NAMEKEY_INVALID, "WOLQuickMatchMenuInit", WOLQuickMatchMenuInit },
{ NAMEKEY_INVALID, "WOLWelcomeMenuInit", WOLWelcomeMenuInit },
@@ -314,7 +311,6 @@ static FunctionLexicon::TableEntry winLayoutUpdateTable[] =
{ NAMEKEY_INVALID, "PopupHostGameUpdate", PopupHostGameUpdate },
{ NAMEKEY_INVALID, "WOLMapSelectMenuUpdate", WOLMapSelectMenuUpdate },
{ NAMEKEY_INVALID, "WOLBuddyOverlayUpdate", WOLBuddyOverlayUpdate },
- { NAMEKEY_INVALID, "GameSpyPlayerInfoOverlayUpdate",GameSpyPlayerInfoOverlayUpdate },
{ NAMEKEY_INVALID, "WOLMessageWindowUpdate", WOLMessageWindowUpdate },
{ NAMEKEY_INVALID, "WOLQuickMatchMenuUpdate", WOLQuickMatchMenuUpdate },
{ NAMEKEY_INVALID, "WOLWelcomeMenuUpdate", WOLWelcomeMenuUpdate },
@@ -355,7 +351,6 @@ static FunctionLexicon::TableEntry winLayoutShutdownTable[] =
{ NAMEKEY_INVALID, "WOLGameSetupMenuShutdown", WOLGameSetupMenuShutdown },
{ NAMEKEY_INVALID, "WOLMapSelectMenuShutdown", WOLMapSelectMenuShutdown },
{ NAMEKEY_INVALID, "WOLBuddyOverlayShutdown", WOLBuddyOverlayShutdown },
- { NAMEKEY_INVALID, "GameSpyPlayerInfoOverlayShutdown",GameSpyPlayerInfoOverlayShutdown },
{ NAMEKEY_INVALID, "WOLMessageWindowShutdown", WOLMessageWindowShutdown },
{ NAMEKEY_INVALID, "WOLQuickMatchMenuShutdown", WOLQuickMatchMenuShutdown },
{ NAMEKEY_INVALID, "WOLWelcomeMenuShutdown", WOLWelcomeMenuShutdown },
diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Diplomacy.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Diplomacy.cpp
index 5118a563afe..5088549b456 100644
--- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Diplomacy.cpp
+++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Diplomacy.cpp
@@ -54,8 +54,6 @@
#include "GameLogic/VictoryConditions.h"
#include "GameNetwork/GameInfo.h"
#include "GameNetwork/NetworkInterface.h"
-#include "GameNetwork/GameSpy/BuddyDefs.h"
-#include "GameNetwork/GameSpy/peerDefs.h"
#ifdef _INTERNAL
// for occasional debugging...
diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/DownloadMenu.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/DownloadMenu.cpp
deleted file mode 100644
index 701030bc064..00000000000
--- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/DownloadMenu.cpp
+++ /dev/null
@@ -1,436 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: DownloadMenu.cpp /////////////////////////////////////////////////////////
-//-----------------------------------------------------------------------------
-//
-// Electronic Arts Pacific.
-//
-// Confidential Information
-// Copyright (C) 2002 - All Rights Reserved
-//
-//-----------------------------------------------------------------------------
-//
-// Project: RTS3
-//
-// File name: DownloadMenu.cpp
-//
-// Created: Matthew D. Campbell, July 2002
-//
-// Desc: the Patch Download window control
-//
-//-----------------------------------------------------------------------------
-///////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/GameEngine.h"
-#include "Common/NameKeyGenerator.h"
-#include "GameClient/GUICallbacks.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/GadgetStaticText.h"
-#include "GameClient/GadgetProgressBar.h"
-#include "GameClient/GameText.h"
-#include "GameClient/MessageBox.h"
-
-#include "GameLogic/GameLogic.h"
-
-#include "GameNetwork/DownloadManager.h"
-#include "GameNetwork/GameSpy/MainMenuUtils.h"
-
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-static NameKeyType buttonCancelID = NAMEKEY_INVALID;
-static NameKeyType staticTextSizeID = NAMEKEY_INVALID;
-static NameKeyType staticTextTimeID = NAMEKEY_INVALID;
-static NameKeyType staticTextFileID = NAMEKEY_INVALID;
-static NameKeyType staticTextStatusID = NAMEKEY_INVALID;
-static NameKeyType progressBarMunkeeID = NAMEKEY_INVALID;
-
-static GameWindow * staticTextSize = NULL;
-static GameWindow * staticTextTime = NULL;
-static GameWindow * staticTextFile = NULL;
-static GameWindow * staticTextStatus = NULL;
-static GameWindow * progressBarMunkee = NULL;
-
-static GameWindow *parent = NULL;
-
-static void closeDownloadWindow( void )
-{
- DEBUG_ASSERTCRASH(parent, ("No Parent"));
- if (!parent)
- return;
-
- WindowLayout *menuLayout = parent->winGetLayout();
- menuLayout->runShutdown();
- menuLayout->destroyWindows();
- menuLayout->deleteInstance();
- menuLayout = NULL;
-
- GameWindow *mainWin = TheWindowManager->winGetWindowFromId( NULL, NAMEKEY("MainMenu.wnd:MainMenuParent") );
- if (mainWin)
- TheWindowManager->winSetFocus( mainWin );
-}
-
-static void errorCallback( void )
-{
- HandleCanceledDownload();
- closeDownloadWindow();
-}
-
-static void successQuitCallback( void )
-{
- TheGameEngine->setQuitting( TRUE );
- closeDownloadWindow();
-
- // Clean up game data. No crashy-crash for you!
- if (TheGameLogic->isInGame())
- TheMessageStream->appendMessage( GameMessage::MSG_CLEAR_GAME_DATA );
-}
-
-static void successNoQuitCallback( void )
-{
- HandleCanceledDownload();
- closeDownloadWindow();
-}
-
-class DownloadManagerMunkee : public DownloadManager
-{
-public:
- DownloadManagerMunkee() {m_shouldQuitOnSuccess = true; m_shouldQuitOnSuccess = false;}
- virtual HRESULT OnError( Int error );
- virtual HRESULT OnEnd();
- virtual HRESULT OnProgressUpdate( Int bytesread, Int totalsize, Int timetaken, Int timeleft );
- virtual HRESULT OnStatusUpdate( Int status );
- virtual HRESULT downloadFile( AsciiString server, AsciiString username, AsciiString password, AsciiString file, AsciiString localfile, AsciiString regkey, Bool tryResume );
-
-private:
- Bool m_shouldQuitOnSuccess;
-};
-
-HRESULT DownloadManagerMunkee::downloadFile( AsciiString server, AsciiString username, AsciiString password, AsciiString file, AsciiString localfile, AsciiString regkey, Bool tryResume )
-{
- // see if we'll need to restart
- if (strstr(localfile.str(), "patches\\") != NULL)
- {
- m_shouldQuitOnSuccess = true;
- }
-
- if (staticTextFile)
- {
- AsciiString bob = file;
-
- // just get the filename, not the pathname
- const char *tmp = bob.reverseFind('/');
- if (tmp)
- bob = tmp+1;
- tmp = bob.reverseFind('\\');
- if (tmp)
- bob = tmp+1;
-
- UnicodeString fileString;
- fileString.translate(bob);
- GadgetStaticTextSetText(staticTextFile, fileString);
- }
-
- password.format("-%s", password.str());
- return DownloadManager::downloadFile( server, username, password, file, localfile, regkey, tryResume );
-}
-HRESULT DownloadManagerMunkee::OnError( Int error )
-{
- HRESULT ret = DownloadManager::OnError( error );
-
- MessageBoxOk(TheGameText->fetch("GUI:DownloadErrorTitle"), getErrorString(), errorCallback);
- return ret;
-}
-HRESULT DownloadManagerMunkee::OnEnd()
-{
- HRESULT ret = DownloadManager::OnEnd();
-
- if (isFileQueuedForDownload())
- {
- return downloadNextQueuedFile();
- }
- if (m_shouldQuitOnSuccess)
- MessageBoxOk(TheGameText->fetch("GUI:DownloadSuccessTitle"), TheGameText->fetch("GUI:DownloadSuccessMustQuit"), successQuitCallback);
- else
- MessageBoxOk(TheGameText->fetch("GUI:DownloadSuccessTitle"), TheGameText->fetch("GUI:DownloadSuccess"), successNoQuitCallback);
- return ret;
-}
-
-static time_t lastUpdate = 0;
-static Int timeLeft = 0;
-HRESULT DownloadManagerMunkee::OnProgressUpdate( Int bytesread, Int totalsize, Int timetaken, Int timeleft )
-{
- HRESULT ret = DownloadManager::OnProgressUpdate( bytesread, totalsize, timetaken, timeleft );
-
- if (progressBarMunkee)
- {
- Int percent = bytesread * 100 / totalsize;
- GadgetProgressBarSetProgress( progressBarMunkee, percent );
- }
-
- if (staticTextSize)
- {
- UnicodeString sizeString;
- sizeString.format(TheGameText->fetch("GUI:DownloadBytesRatio"), bytesread, totalsize);
- GadgetStaticTextSetText(staticTextSize, sizeString);
- }
- timeLeft = timeleft;
- if (staticTextTime && GadgetStaticTextGetText(staticTextTime).isEmpty()) // only update immediately the first time
- {
- lastUpdate = time(NULL);
- UnicodeString timeString;
- if (timeleft)
- {
- DEBUG_ASSERTCRASH(timeleft > 0, ("Time left is negative!"));
- timeleft = max(1, timeleft);
- Int takenHour, takenMin, takenSec;
- takenHour = timeleft / 60 / 60;
- takenMin = timeleft / 60;
- takenSec = timeleft % 60;
- timeString.format(TheGameText->fetch("GUI:DownloadTimeLeft"), takenHour, takenMin, takenSec);
- }
- else
- {
- timeString = TheGameText->fetch("GUI:DownloadUnknownTime");
- }
- GadgetStaticTextSetText(staticTextTime, timeString);
- }
- return ret;
-}
-
-HRESULT DownloadManagerMunkee::OnStatusUpdate( Int status )
-{
- HRESULT ret = DownloadManager::OnStatusUpdate( status );
-
- if (staticTextStatus)
- {
- GadgetStaticTextSetText(staticTextStatus, getStatusString());
- }
- return ret;
-}
-
-// PUBLIC FUNCTIONS ///////////////////////////////////////////////////////////////////////////////
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the menu */
-//-------------------------------------------------------------------------------------------------
-void DownloadMenuInit( WindowLayout *layout, void *userData )
-{
-
- //set keyboard focus to main parent and set modal
- NameKeyType parentID = TheNameKeyGenerator->nameToKey("DownloadMenu.wnd:ParentDownload");
- parent = TheWindowManager->winGetWindowFromId( NULL, parentID );
-
- // get ids for our children controls
- buttonCancelID = TheNameKeyGenerator->nameToKey( "DownloadMenu.wnd:ButtonCancel" );
- staticTextSizeID = TheNameKeyGenerator->nameToKey( "DownloadMenu.wnd:StaticTextSize" );
- staticTextTimeID = TheNameKeyGenerator->nameToKey( "DownloadMenu.wnd:StaticTextTime" );
- staticTextFileID = TheNameKeyGenerator->nameToKey( "DownloadMenu.wnd:StaticTextFile" );
- staticTextStatusID = TheNameKeyGenerator->nameToKey( "DownloadMenu.wnd:StaticTextStatus" );
- progressBarMunkeeID = TheNameKeyGenerator->nameToKey( "DownloadMenu.wnd:ProgressBarMunkee" );
-
- staticTextSize = TheWindowManager->winGetWindowFromId( parent, staticTextSizeID );
- staticTextTime = TheWindowManager->winGetWindowFromId( parent, staticTextTimeID );
- staticTextFile = TheWindowManager->winGetWindowFromId( parent, staticTextFileID );
- staticTextStatus = TheWindowManager->winGetWindowFromId( parent, staticTextStatusID );
- progressBarMunkee = TheWindowManager->winGetWindowFromId( parent, progressBarMunkeeID );
-
- DEBUG_ASSERTCRASH(!TheDownloadManager, ("Download manager already exists"));
- if (TheDownloadManager)
- {
- delete TheDownloadManager;
- }
- TheDownloadManager = NEW DownloadManagerMunkee;
-
-} // end DownloadMenuInit
-
-//-------------------------------------------------------------------------------------------------
-/** menu shutdown method */
-//-------------------------------------------------------------------------------------------------
-void DownloadMenuShutdown( WindowLayout *layout, void *userData )
-{
- DEBUG_ASSERTCRASH(TheDownloadManager, ("No download manager"));
- if (TheDownloadManager)
- {
- delete TheDownloadManager;
- TheDownloadManager = NULL;
- }
-
- staticTextSize = NULL;
- staticTextTime = NULL;
- staticTextFile = NULL;
- staticTextStatus = NULL;
- progressBarMunkee = NULL;
- parent = NULL;
-
-} // end DownloadMenuShutdown
-
-//-------------------------------------------------------------------------------------------------
-/** menu update method */
-//-------------------------------------------------------------------------------------------------
-void DownloadMenuUpdate( WindowLayout *layout, void *userData )
-{
- if (staticTextTime && !GadgetStaticTextGetText(staticTextTime).isEmpty())
- {
- time_t now = time(NULL);
- if (now <= lastUpdate)
- return;
-
- lastUpdate = now;
-
- UnicodeString timeString;
- if (timeLeft)
- {
- DEBUG_ASSERTCRASH(timeLeft > 0, ("Time left is negative!"));
- timeLeft = max(1, timeLeft);
- Int takenHour, takenMin, takenSec;
- takenHour = timeLeft / 60 / 60;
- takenMin = timeLeft / 60;
- takenSec = timeLeft % 60;
- timeString.format(TheGameText->fetch("GUI:DownloadTimeLeft"), takenHour, takenMin, takenSec);
- }
- else
- {
- timeString = TheGameText->fetch("GUI:DownloadUnknownTime");
- }
- GadgetStaticTextSetText(staticTextTime, timeString);
- }
-
-} // end DownloadMenuUpdate
-
-//-------------------------------------------------------------------------------------------------
-/** menu input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType DownloadMenuInput( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
-
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
- UnsignedByte key = mData1;
- UnsignedByte state = mData2;
-
- switch( key )
- {
-
- // ----------------------------------------------------------------------------------------
- case KEY_ESC:
- {
-
- //
- // send a simulated selected event to the parent window of the
- // back/exit button
- //
- if( BitTest( state, KEY_STATE_UP ) )
- {
- AsciiString buttonName( "DownloadMenu.wnd:ButtonCancel" );
- NameKeyType buttonID = TheNameKeyGenerator->nameToKey( buttonName );
- GameWindow *button = TheWindowManager->winGetWindowFromId( window, buttonID );
-
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)button, buttonID );
-
- } // end if
-
- // don't let key fall through anywhere else
- return MSG_HANDLED;
-
- } // end escape
-
- } // end switch( key )
-
- } // end char
-
- } // end switch( msg )
-
- return MSG_IGNORED;
-
-} // end DownloadMenuInput
-
-//-------------------------------------------------------------------------------------------------
-/** menu window system callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType DownloadMenuSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
-
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CREATE:
- {
-
- break;
-
- } // end create
- //---------------------------------------------------------------------------------------------
- case GWM_DESTROY:
- {
-
- break;
-
- } // end case
-
- //----------------------------------------------------------------------------------------------
- case GWM_INPUT_FOCUS:
- {
-
- // if we're givin the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
-
- break;
-
- } // end input
- //---------------------------------------------------------------------------------------------
- case GBM_SELECTED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if( controlID == buttonCancelID )
- {
- HandleCanceledDownload();
- closeDownloadWindow();
- } // end if
-
- break;
-
- } // end selected
-
- default:
- return MSG_IGNORED;
-
- } // end switch
-
- return MSG_HANDLED;
-
-} // end DownloadMenuSystem
\ No newline at end of file
diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/MainMenu.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/MainMenu.cpp
index e9517dd6593..f10bd6dcc38 100644
--- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/MainMenu.cpp
+++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/MainMenu.cpp
@@ -30,8 +30,6 @@
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-#include "GameSpy/ghttp/ghttp.h"
-
#include "Lib/BaseType.h"
#include "Common/GameEngine.h"
#include "Common/GameState.h"
@@ -62,16 +60,11 @@
#include "GameClient/GameClient.h"
#include "GameLogic/GameLogic.h"
#include "GameLogic/ScriptEngine.h"
-#include "GameNetwork/GameSpyOverlay.h"
#include "GameClient/GameWindowTransitions.h"
#include "GameClient/ChallengeGenerals.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpy/PeerThread.h"
-#include "GameNetwork/GameSpy/BuddyThread.h"
#include "GameNetwork/DownloadManager.h"
-#include "GameNetwork/GameSpy/MainMenuUtils.h"
//Added By Saad
//for accessing the InGameUI
@@ -481,7 +474,9 @@ void MainMenuInit( WindowLayout *layout, void *userData )
buttonSinglePlayer = TheWindowManager->winGetWindowFromId( parentMainMenu, buttonSinglePlayerID );
buttonMultiPlayer = TheWindowManager->winGetWindowFromId( parentMainMenu, buttonMultiPlayerID );
buttonSkirmish = TheWindowManager->winGetWindowFromId( parentMainMenu, skirmishID );
- buttonOnline = TheWindowManager->winGetWindowFromId( parentMainMenu, onlineID );
+ buttonOnline = TheWindowManager->winGetWindowFromId( parentMainMenu, onlineID );
+ if (buttonOnline)
+ buttonOnline->winHide(TRUE);
buttonNetwork = TheWindowManager->winGetWindowFromId( parentMainMenu, networkID );
buttonOptions = TheWindowManager->winGetWindowFromId( parentMainMenu, optionsID );
buttonExit = TheWindowManager->winGetWindowFromId( parentMainMenu, exitID );
@@ -595,12 +590,6 @@ void MainMenuInit( WindowLayout *layout, void *userData )
//getUpdate->winEnable( FALSE );
}
/**/
-
- if (TheGameSpyPeerMessageQueue && !TheGameSpyPeerMessageQueue->isConnected())
- {
- DEBUG_LOG(("Tearing down GameSpy from MainMenuInit()\n"));
- TearDownGameSpy();
- }
if (TheMapCache)
TheMapCache->updateCache();
@@ -901,7 +890,6 @@ void MainMenuUpdate( WindowLayout *layout, void *userData )
}
HTTPThinkWrapper();
- GameSpyUpdateOverlays();
// if(localAnimateWindowManager)
// localAnimateWindowManager->update();
// if(localAnimateWindowManager && pendingDropDown != DROPDOWN_NONE && localAnimateWindowManager->isFinished())
@@ -1031,15 +1019,12 @@ WindowMsgHandledType MainMenuSystem( GameWindow *window, UnsignedInt msg,
} // end case
//---------------------------------------------------------------------------------------------
- case GWM_DESTROY:
- {
- ghttpCleanup();
- DEBUG_LOG(("Tearing down GameSpy from MainMenuSystem(GWM_DESTROY)\n"));
- TearDownGameSpy();
- StopAsyncDNSCheck(); // kill off the async DNS check thread in case it is still running
- break;
+ case GWM_DESTROY:
+ {
+ StopAsyncDNSCheck(); // kill off the async DNS check thread in case it is still running
+ break;
- } // end case
+ } // end case
// --------------------------------------------------------------------------------------------
case GWM_INPUT_FOCUS:
@@ -1055,13 +1040,9 @@ WindowMsgHandledType MainMenuSystem( GameWindow *window, UnsignedInt msg,
//---------------------------------------------------------------------------------------------
case GBM_MOUSE_ENTERING:
{
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- if(controlID == onlineID)
- {
- TheScriptEngine->signalUIInteract(TheShellHookNames[SHELL_SCRIPT_HOOK_MAIN_MENU_ONLINE_HIGHLIGHTED]);
- }
- else if(controlID == networkID)
+GameWindow *control = (GameWindow *)mData1;
+Int controlID = control->winGetWindowId();
+if(controlID == networkID)
{
TheScriptEngine->signalUIInteract(TheShellHookNames[SHELL_SCRIPT_HOOK_MAIN_MENU_NETWORK_HIGHLIGHTED]);
}
@@ -1173,14 +1154,10 @@ WindowMsgHandledType MainMenuSystem( GameWindow *window, UnsignedInt msg,
//---------------------------------------------------------------------------------------------
case GBM_MOUSE_LEAVING:
{
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
+GameWindow *control = (GameWindow *)mData1;
+Int controlID = control->winGetWindowId();
- if(controlID == onlineID)
- {
- TheScriptEngine->signalUIInteract(TheShellHookNames[SHELL_SCRIPT_HOOK_MAIN_MENU_ONLINE_UNHIGHLIGHTED]);
- }
- else if(controlID == networkID)
+if(controlID == networkID)
{
TheScriptEngine->signalUIInteract(TheShellHookNames[SHELL_SCRIPT_HOOK_MAIN_MENU_NETWORK_UNHIGHLIGHTED]);
}
@@ -1437,20 +1414,6 @@ WindowMsgHandledType MainMenuSystem( GameWindow *window, UnsignedInt msg,
TheShell->push( AsciiString("Menus/SkirmishGameOptionsMenu.wnd") );
TheScriptEngine->signalUIInteract(TheShellHookNames[SHELL_SCRIPT_HOOK_MAIN_MENU_SKIRMISH_SELECTED]);
}
- else if( controlID == onlineID )
- {
- if(dontAllowTransitions)
- break;
- dontAllowTransitions = TRUE;
- buttonPushed = TRUE;
- dropDownWindows[DROPDOWN_MULTIPLAYER]->winHide(FALSE);
- TheTransitionHandler->reverse("MainMenuMultiPlayerMenuTransitionToNext");
-
- StartPatchCheck();
-// localAnimateWindowManager->reverseAnimateWindow();
- dropDown = DROPDOWN_NONE;
-
- } // end else if
else if( controlID == networkID )
{
if(dontAllowTransitions)
diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/NetworkDirectConnect.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/NetworkDirectConnect.cpp
deleted file mode 100644
index 48492f0740f..00000000000
--- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/NetworkDirectConnect.cpp
+++ /dev/null
@@ -1,537 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////////////
-// FILE: NetworkDirectConnect.cpp
-// Author: Bryan Cleveland, November 2001
-// Description: Lan Lobby Menu
-///////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "GameSpy/peer/peer.h"
-
-#include "Common/QuotedPrintable.h"
-#include "Common/UserPreferences.h"
-#include "GameClient/AnimateWindowManager.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/GameText.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/GadgetComboBox.h"
-#include "GameClient/GadgetTextEntry.h"
-#include "GameClient/GadgetStaticText.h"
-#include "GameClient/Shell.h"
-#include "GameClient/GameWindowTransitions.h"
-
-#include "GameNetwork/IPEnumeration.h"
-#include "GameNetwork/LANAPI.h"
-#include "GameNetwork/LANAPICallbacks.h"
-
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-
-// window ids ------------------------------------------------------------------------------
-
-// Window Pointers ------------------------------------------------------------------------
-
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-
-extern Bool LANbuttonPushed;
-extern Bool LANisShuttingDown;
-
-static Bool isShuttingDown = false;
-static Bool buttonPushed = false;
-
-static NameKeyType buttonBackID = NAMEKEY_INVALID;
-static NameKeyType buttonHostID = NAMEKEY_INVALID;
-static NameKeyType buttonJoinID = NAMEKEY_INVALID;
-static NameKeyType editPlayerNameID = NAMEKEY_INVALID;
-static NameKeyType comboboxRemoteIPID = NAMEKEY_INVALID;
-static NameKeyType staticLocalIPID = NAMEKEY_INVALID;
-
-static GameWindow *buttonBack = NULL;
-static GameWindow *buttonHost = NULL;
-static GameWindow *buttonJoin = NULL;
-static GameWindow *editPlayerName = NULL;
-static GameWindow *comboboxRemoteIP = NULL;
-static GameWindow *staticLocalIP = NULL;
-
-void PopulateRemoteIPComboBox()
-{
- LANPreferences userprefs;
- GadgetComboBoxReset(comboboxRemoteIP);
-
- Int numRemoteIPs = userprefs.getNumRemoteIPs();
- Color white = GameMakeColor(255,255,255,255);
-
- for (Int i = 0; i < numRemoteIPs; ++i)
- {
- UnicodeString entry;
- entry = userprefs.getRemoteIPEntry(i);
- GadgetComboBoxAddEntry(comboboxRemoteIP, entry, white);
- }
-
- if (numRemoteIPs > 0)
- {
- GadgetComboBoxSetSelectedPos(comboboxRemoteIP, 0, TRUE);
- }
- userprefs.write();
-}
-
-void UpdateRemoteIPList()
-{
- Int n1[4], n2[4];
- LANPreferences prefs;
- Int numEntries = GadgetComboBoxGetLength(comboboxRemoteIP);
- Int currentSelection = -1;
- GadgetComboBoxGetSelectedPos(comboboxRemoteIP, ¤tSelection);
- UnicodeString unisel = GadgetComboBoxGetText(comboboxRemoteIP);
- AsciiString sel;
- sel.translate(unisel);
-
-// UnicodeString newEntry = prefs.getRemoteIPEntry(0);
- UnicodeString newEntry = unisel;
- UnicodeString newIP;
- newEntry.nextToken(&newIP, UnicodeString(L":"));
- Int numFields = swscanf(newIP.str(), L"%d.%d.%d.%d", &(n1[0]), &(n1[1]), &(n1[2]), &(n1[3]));
-
- if (numFields != 4) {
- // this is not a properly formatted IP, don't change a thing.
- return;
- }
-
- prefs["RemoteIP0"] = sel;
-
- Int currentINIEntry = 1;
-
- for (Int i = 0; i < numEntries; ++i)
- {
- if (i != currentSelection)
- {
- GadgetComboBoxSetSelectedPos(comboboxRemoteIP, i, FALSE);
- UnicodeString uni;
- uni = GadgetComboBoxGetText(comboboxRemoteIP);
- AsciiString ascii;
- ascii.translate(uni);
-
- // prevent more than one copy of an IP address from being put in the list.
- if (currentSelection == -1)
- {
- UnicodeString oldEntry = uni;
- UnicodeString oldIP;
- oldEntry.nextToken(&oldIP, UnicodeString(L":"));
-
- swscanf(oldIP.str(), L"%d.%d.%d.%d", &(n2[0]), &(n2[1]), &(n2[2]), &(n2[3]));
-
- Bool isEqual = TRUE;
- for (Int i = 0; (i < 4) && (isEqual == TRUE); ++i) {
- if (n1[i] != n2[i]) {
- isEqual = FALSE;
- }
- }
- // check to see if this is a duplicate or if this is not a properly formatted IP address.
- if (isEqual == TRUE)
- {
- --numEntries;
- continue;
- }
- }
- AsciiString temp;
- temp.format("RemoteIP%d", currentINIEntry);
- ++currentINIEntry;
- prefs[temp.str()] = ascii;
- }
- }
-
- if (currentSelection == -1)
- {
- ++numEntries;
- }
-
- AsciiString numRemoteIPs;
- numRemoteIPs.format("%d", numEntries);
-
- prefs["NumRemoteIPs"] = numRemoteIPs;
-
- prefs.write();
-}
-
-void HostDirectConnectGame()
-{
- // Init LAN API Singleton
- DEBUG_ASSERTCRASH(TheLAN != NULL, ("TheLAN is NULL!"));
- if (!TheLAN)
- {
- TheLAN = NEW LANAPI();
- }
-
- UnsignedInt localIP = TheLAN->GetLocalIP();
- UnicodeString localIPString;
- localIPString.format(L"%d.%d.%d.%d", localIP >> 24, (localIP & 0xff0000) >> 16, (localIP & 0xff00) >> 8, localIP & 0xff);
-
- UnicodeString name;
- name = GadgetTextEntryGetText(editPlayerName);
-
- LANPreferences prefs;
- prefs["UserName"] = UnicodeStringToQuotedPrintable(name);
- prefs.write();
-
- while (name.getLength() > g_lanPlayerNameLength)
- name.removeLastChar();
- TheLAN->RequestSetName(name);
- TheLAN->RequestGameCreate(localIPString, TRUE);
-}
-
-void JoinDirectConnectGame()
-{
- // Init LAN API Singleton
-
- if (!TheLAN)
- {
- TheLAN = NEW LANAPI();
- }
-
- UnsignedInt ipaddress = 0;
- UnicodeString ipunistring = GadgetComboBoxGetText(comboboxRemoteIP);
- AsciiString asciientry;
- asciientry.translate(ipunistring);
-
- AsciiString ipstring;
- asciientry.nextToken(&ipstring, "(");
-
- char ipstr[16];
- strcpy(ipstr, ipstring.str());
-
- Int ip1, ip2, ip3, ip4;
- sscanf(ipstr, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
-
- DEBUG_LOG(("JoinDirectConnectGame - joining at %d.%d.%d.%d\n", ip1, ip2, ip3, ip4));
-
- ipaddress = (ip1 << 24) + (ip2 << 16) + (ip3 << 8) + ip4;
-// ipaddress = htonl(ipaddress);
-
- UnicodeString name;
- name = GadgetTextEntryGetText(editPlayerName);
-
- LANPreferences prefs;
- prefs["UserName"] = UnicodeStringToQuotedPrintable(name);
- prefs.write();
-
- UpdateRemoteIPList();
- PopulateRemoteIPComboBox();
-
- while (name.getLength() > g_lanPlayerNameLength)
- name.removeLastChar();
- TheLAN->RequestSetName(name);
-
- TheLAN->RequestGameJoinDirectConnect(ipaddress);
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the WOL Welcome Menu */
-//-------------------------------------------------------------------------------------------------
-void NetworkDirectConnectInit( WindowLayout *layout, void *userData )
-{
- LANbuttonPushed = false;
- LANisShuttingDown = false;
-
- if (TheLAN == NULL)
- {
- TheLAN = NEW LANAPI();
- TheLAN->init();
- }
- TheLAN->reset();
-
- buttonPushed = false;
- isShuttingDown = false;
- TheShell->showShellMap(TRUE);
- buttonBackID = TheNameKeyGenerator->nameToKey( AsciiString( "NetworkDirectConnect.wnd:ButtonBack" ) );
- buttonHostID = TheNameKeyGenerator->nameToKey( AsciiString( "NetworkDirectConnect.wnd:ButtonHost" ) );
- buttonJoinID = TheNameKeyGenerator->nameToKey( AsciiString( "NetworkDirectConnect.wnd:ButtonJoin" ) );
- editPlayerNameID = TheNameKeyGenerator->nameToKey( AsciiString( "NetworkDirectConnect.wnd:EditPlayerName" ) );
- comboboxRemoteIPID = TheNameKeyGenerator->nameToKey( AsciiString( "NetworkDirectConnect.wnd:ComboboxRemoteIP" ) );
- staticLocalIPID = TheNameKeyGenerator->nameToKey( AsciiString( "NetworkDirectConnect.wnd:StaticLocalIP" ) );
-
- buttonBack = TheWindowManager->winGetWindowFromId( NULL, buttonBackID);
- buttonHost = TheWindowManager->winGetWindowFromId( NULL, buttonHostID);
- buttonJoin = TheWindowManager->winGetWindowFromId( NULL, buttonJoinID);
- editPlayerName = TheWindowManager->winGetWindowFromId( NULL, editPlayerNameID);
- comboboxRemoteIP = TheWindowManager->winGetWindowFromId( NULL, comboboxRemoteIPID);
- staticLocalIP = TheWindowManager->winGetWindowFromId( NULL, staticLocalIPID);
-
-// // animate controls
-// TheShell->registerWithAnimateManager(buttonBack, WIN_ANIMATION_SLIDE_LEFT, TRUE, 800);
-// TheShell->registerWithAnimateManager(buttonHost, WIN_ANIMATION_SLIDE_LEFT, TRUE, 600);
-// TheShell->registerWithAnimateManager(buttonJoin, WIN_ANIMATION_SLIDE_LEFT, TRUE, 200);
-//
- LANPreferences userprefs;
- UnicodeString name;
- name = userprefs.getUserName();
-
- if (name.getLength() == 0)
- {
- name = TheGameText->fetch("GUI:Player");
- }
-
- GadgetTextEntrySetText(editPlayerName, name);
-
- PopulateRemoteIPComboBox();
-
- UnicodeString ipstr;
-
- delete TheLAN;
- TheLAN = NULL;
-
- if (TheLAN == NULL) {
-// DEBUG_ASSERTCRASH(TheLAN != NULL, ("TheLAN is null initializing the direct connect screen."));
- TheLAN = NEW LANAPI();
-
- OptionPreferences prefs;
- UnsignedInt IP = prefs.getOnlineIPAddress();
-
- IPEnumeration IPs;
-
-// if (!IP)
-// {
- EnumeratedIP *IPlist = IPs.getAddresses();
- DEBUG_ASSERTCRASH(IPlist, ("No IP addresses found!"));
- if (!IPlist)
- {
- /// @todo: display error and exit lan lobby if no IPs are found
- }
-
- Bool foundIP = FALSE;
- EnumeratedIP *tempIP = IPlist;
- while ((tempIP != NULL) && (foundIP == FALSE)) {
- if (IP == tempIP->getIP()) {
- foundIP = TRUE;
- }
- tempIP = tempIP->getNext();
- }
-
- if (foundIP == FALSE) {
- // The IP that we had no longer exists, we need to pick a new one.
- IP = IPlist->getIP();
- }
-
-// IP = IPlist->getIP();
-// }
- TheLAN->init();
- TheLAN->SetLocalIP(IP);
- }
-
- UnsignedInt ip = TheLAN->GetLocalIP();
- ipstr.format(L"%d.%d.%d.%d", ip >> 24, (ip & 0xff0000) >> 16, (ip & 0xff00) >> 8, ip & 0xff);
- GadgetStaticTextSetText(staticLocalIP, ipstr);
-
- TheLAN->RequestLobbyLeave(true);
- layout->hide(FALSE);
- layout->bringForward();
- TheTransitionHandler->setGroup("NetworkDirectConnectFade");
-
-
-} // NetworkDirectConnectInit
-
-//-------------------------------------------------------------------------------------------------
-/** This is called when a shutdown is complete for this menu */
-//-------------------------------------------------------------------------------------------------
-static void shutdownComplete( WindowLayout *layout )
-{
-
- isShuttingDown = false;
-
- // hide the layout
- layout->hide( TRUE );
-
- // our shutdown is complete
- TheShell->shutdownComplete( layout );
-
-} // end if
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Welcome Menu shutdown method */
-//-------------------------------------------------------------------------------------------------
-void NetworkDirectConnectShutdown( WindowLayout *layout, void *userData )
-{
- isShuttingDown = true;
-
- // if we are shutting down for an immediate pop, skip the animations
- Bool popImmediate = *(Bool *)userData;
- if( popImmediate )
- {
-
- shutdownComplete( layout );
- return;
-
- } //end if
-
- TheShell->reverseAnimatewindow();
-
- TheTransitionHandler->reverse("NetworkDirectConnectFade");
-} // NetworkDirectConnectShutdown
-
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Welcome Menu update method */
-//-------------------------------------------------------------------------------------------------
-void NetworkDirectConnectUpdate( WindowLayout * layout, void *userData)
-{
- // We'll only be successful if we've requested to
- if(isShuttingDown && TheShell->isAnimFinished() && TheTransitionHandler->isFinished())
- shutdownComplete(layout);
-}// NetworkDirectConnectUpdate
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Welcome Menu input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType NetworkDirectConnectInput( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
- UnsignedByte key = mData1;
- UnsignedByte state = mData2;
- if (buttonPushed)
- break;
-
- switch( key )
- {
-
- // ----------------------------------------------------------------------------------------
- case KEY_ESC:
- {
-
- //
- // send a simulated selected event to the parent window of the
- // back/exit button
- //
- if( BitTest( state, KEY_STATE_UP ) )
- {
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)buttonBack, buttonBackID );
-
- } // end if
-
- // don't let key fall through anywhere else
- return MSG_HANDLED;
-
- } // end escape
-
- } // end switch( key )
-
- } // end char
-
- } // end switch( msg )
-
- return MSG_IGNORED;
-}// NetworkDirectConnectInput
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Welcome Menu window system callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType NetworkDirectConnectSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- UnicodeString txtInput;
-
- switch( msg )
- {
-
-
- case GWM_CREATE:
- {
-
- break;
- } // case GWM_DESTROY:
-
- case GWM_DESTROY:
- {
- break;
- } // case GWM_DESTROY:
-
- case GWM_INPUT_FOCUS:
- {
- // if we're givin the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
-
- return MSG_HANDLED;
- }//case GWM_INPUT_FOCUS:
-
- case GBM_SELECTED:
- {
- if (buttonPushed)
- break;
-
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if ( controlID == buttonBackID )
- {
- UnicodeString name;
- name = GadgetTextEntryGetText(editPlayerName);
-
- LANPreferences prefs;
- prefs["UserName"] = UnicodeStringToQuotedPrintable(name);
- prefs.write();
-
- while (name.getLength() > g_lanPlayerNameLength)
- name.removeLastChar();
- TheLAN->RequestSetName(name);
-
- buttonPushed = true;
- LANbuttonPushed = true;
- TheShell->pop();
- } //if ( controlID == buttonBack )
- else if (controlID == buttonHostID)
- {
- HostDirectConnectGame();
- }
- else if (controlID == buttonJoinID)
- {
- JoinDirectConnectGame();
- }
- break;
- }// case GBM_SELECTED:
-
- case GEM_EDIT_DONE:
- {
- break;
- }
- default:
- return MSG_IGNORED;
-
- }//Switch
-
- return MSG_HANDLED;
-}// NetworkDirectConnectSystem
diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp
index a5bfec7e6a4..b34e045aad9 100644
--- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp
+++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp
@@ -30,8 +30,6 @@
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-#include "GameSpy/ghttp/ghttp.h"
-
#include "Common/AudioAffect.h"
#include "Common/AudioSettings.h"
#include "Common/GameAudio.h"
@@ -63,8 +61,6 @@
#include "GameClient/GUICallbacks.h"
#include "GameNetwork/FirewallHelper.h"
#include "GameNetwork/IPEnumeration.h"
-#include "GameNetwork/GameSpyOverlay.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
#include "GameLogic/GameLogic.h"
#include "GameLogic/ScriptEngine.h"
#include "WWDownload/Registry.h"
@@ -82,8 +78,6 @@
#endif
-static NameKeyType comboBoxOnlineIPID = NAMEKEY_INVALID;
-static GameWindow * comboBoxOnlineIP = NULL;
static NameKeyType comboBoxLANIPID = NAMEKEY_INVALID;
static GameWindow * comboBoxLANIP = NULL;
@@ -807,7 +801,7 @@ static void setDefaults( void )
//-------------------------------------------------------------------------------------------------
// Resolution
//Find index of 800x600 mode.
- if ((TheGameLogic->isInGame() == FALSE) || (TheGameLogic->isInShellGame() == TRUE) && !TheGameSpyInfo) {
+ if ((TheGameLogic->isInGame() == FALSE) || (TheGameLogic->isInShellGame() == TRUE)) {
Int numResolutions = TheDisplay->getDisplayModeCount();
Int defaultResIndex=0;
for( Int i = 0; i < numResolutions; ++i )
@@ -1128,13 +1122,6 @@ static void saveOptions( void )
TheWritableGlobalData->m_defaultIP = ip;
pref->setLANIPAddress(ip);
}
- GadgetComboBoxGetSelectedPos(comboBoxOnlineIP, &index);
- if (index>=0)
- {
- ip = (UnsignedInt)GadgetComboBoxGetItemData(comboBoxOnlineIP, index);
- pref->setOnlineIPAddress(ip);
- }
-
//-------------------------------------------------------------------------------------------------
// HTTP Proxy
GameWindow *textEntryHTTPProxy = TheWindowManager->winGetWindowFromId(NULL, NAMEKEY("OptionsMenu.wnd:TextEntryHTTPProxy"));
@@ -1144,7 +1131,6 @@ static void saveOptions( void )
AsciiString aStr;
aStr.translate(uStr);
SetStringInRegistry("", "Proxy", aStr.str());
- ghttpSetProxy(aStr.str());
}
//-------------------------------------------------------------------------------------------------
@@ -1348,8 +1334,9 @@ void OptionsMenuInit( WindowLayout *layout, void *userData )
comboBoxLANIPID = TheNameKeyGenerator->nameToKey( AsciiString( "OptionsMenu.wnd:ComboBoxIP" ) );
comboBoxLANIP = TheWindowManager->winGetWindowFromId( NULL, comboBoxLANIPID);
- comboBoxOnlineIPID = TheNameKeyGenerator->nameToKey( AsciiString( "OptionsMenu.wnd:ComboBoxOnlineIP" ) );
- comboBoxOnlineIP = TheWindowManager->winGetWindowFromId( NULL, comboBoxOnlineIPID);
+ NameKeyType comboBoxOnlineIPID = TheNameKeyGenerator->nameToKey( AsciiString( "OptionsMenu.wnd:ComboBoxOnlineIP" ) );
+ if ( GameWindow *comboBoxOnlineIP = TheWindowManager->winGetWindowFromId( NULL, comboBoxOnlineIPID ) )
+ comboBoxOnlineIP->winHide( TRUE );
checkAlternateMouseID = TheNameKeyGenerator->nameToKey( AsciiString( "OptionsMenu.wnd:CheckAlternateMouse" ) );
checkAlternateMouse = TheWindowManager->winGetWindowFromId( NULL, checkAlternateMouseID);
checkRetaliationID = TheNameKeyGenerator->nameToKey( AsciiString( "OptionsMenu.wnd:Retaliation" ) );
@@ -1520,8 +1507,6 @@ void OptionsMenuInit( WindowLayout *layout, void *userData )
}
}
- // And now the GameSpy one
- if (comboBoxOnlineIP)
{
UnsignedInt selectedIP = pref->getOnlineIPAddress();
UnicodeString str;
@@ -1530,13 +1515,10 @@ void OptionsMenuInit( WindowLayout *layout, void *userData )
Int index;
Int selectedIndex = -1;
Int count = 0;
- GadgetComboBoxReset(comboBoxOnlineIP);
while (IPlist)
{
count++;
str.translate(IPlist->getIPstring());
- index = GadgetComboBoxAddEntry(comboBoxOnlineIP, str, color);
- GadgetComboBoxSetItemData(comboBoxOnlineIP, index, (void *)(IPlist->getIP()));
if (selectedIP == IPlist->getIP())
{
selectedIndex = index;
@@ -1545,14 +1527,11 @@ void OptionsMenuInit( WindowLayout *layout, void *userData )
}
if (selectedIndex >= 0)
{
- GadgetComboBoxSetSelectedPos(comboBoxOnlineIP, selectedIndex);
}
else
{
- GadgetComboBoxSetSelectedPos(comboBoxOnlineIP, 0);
if (IPs.getAddresses())
{
- pref->setOnlineIPAddress(IPs.getAddresses()->getIPstring());
}
}
}
@@ -1796,12 +1775,10 @@ void OptionsMenuInit( WindowLayout *layout, void *userData )
GameWindow *parent = TheWindowManager->winGetWindowFromId( NULL, parentID );
TheWindowManager->winSetFocus( parent );
- if( (TheGameLogic->isInGame() && TheGameLogic->getGameMode() != GAME_SHELL) || TheGameSpyInfo )
+ if( (TheGameLogic->isInGame() && TheGameLogic->getGameMode() != GAME_SHELL) )
{
// disable controls that you can't change the options for in game
comboBoxLANIP->winEnable(FALSE);
- if (comboBoxOnlineIP)
- comboBoxOnlineIP->winEnable(FALSE);
checkSendDelay->winEnable(FALSE);
buttonFirewallRefresh->winEnable(FALSE);
@@ -1996,15 +1973,8 @@ WindowMsgHandledType OptionsMenuSystem( GameWindow *window, UnsignedInt msg,
pref = NULL;
}
- comboBoxLANIP = NULL;
- comboBoxOnlineIP = NULL;
-
- if(GameSpyIsOverlayOpen(GSOVERLAY_OPTIONS))
- GameSpyCloseOverlay(GSOVERLAY_OPTIONS);
- else
- {
- DestroyOptionsLayout();
- }
+comboBoxLANIP = NULL;
+DestroyOptionsLayout();
} // end if
else if (controlID == buttonAccept )
@@ -2018,23 +1988,16 @@ WindowMsgHandledType OptionsMenuSystem( GameWindow *window, UnsignedInt msg,
pref = NULL;
}
- comboBoxLANIP = NULL;
- comboBoxOnlineIP = NULL;
-
- if(!TheGameLogic->isInGame() || TheGameLogic->isInShellGame())
- destroyQuitMenu(); // if we're in a game, the change res then enter the same kind of game, we nee the quit menu to be gone.
+comboBoxLANIP = NULL;
+if(!TheGameLogic->isInGame() || TheGameLogic->isInShellGame())
+destroyQuitMenu(); // if we're in a game, the change res then enter the same kind of game, we nee the quit menu to be gone.
- if(GameSpyIsOverlayOpen(GSOVERLAY_OPTIONS))
- GameSpyCloseOverlay(GSOVERLAY_OPTIONS);
- else
- {
- DestroyOptionsLayout();
- if (dispChanged)
- {
- DoResolutionDialog();
- }
- }
+DestroyOptionsLayout();
+if (dispChanged)
+{
+DoResolutionDialog();
+}
}
else if (controlID == buttonDefaults )
diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/PopupLadderSelect.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/PopupLadderSelect.cpp
deleted file mode 100644
index 1c57a852b3e..00000000000
--- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/PopupLadderSelect.cpp
+++ /dev/null
@@ -1,682 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: PopupLadderSelect.cpp ////////////////////////////////////////////////
-//-----------------------------------------------------------------------------
-//
-// Electronic Arts Pacific.
-//
-// Confidential Information
-// Copyright (C) 2002 - All Rights Reserved
-//
-//-----------------------------------------------------------------------------
-//
-// created: August 2002
-//
-// Filename: PopupLadderSelect.cpp
-//
-// author: Matthew D. Campbell
-//
-// purpose: Contains the Callbacks for the Ladder Select Popup
-//
-//-----------------------------------------------------------------------------
-///////////////////////////////////////////////////////////////////////////////
-
-//-----------------------------------------------------------------------------
-// SYSTEM INCLUDES ////////////////////////////////////////////////////////////
-//-----------------------------------------------------------------------------
-
-//-----------------------------------------------------------------------------
-// USER INCLUDES //////////////////////////////////////////////////////////////
-//-----------------------------------------------------------------------------
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/GlobalData.h"
-#include "Common/Encrypt.h"
-#include "Common/NameKeyGenerator.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/GameText.h"
-#include "GameClient/KeyDefs.h"
-#include "GameClient/MapUtil.h"
-#include "GameClient/GadgetListBox.h"
-#include "GameClient/GadgetStaticText.h"
-#include "GameClient/GadgetTextEntry.h"
-#include "GameNetwork/GameSpy/LadderDefs.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-//#include "GameNetwork/GameSpy/PeerThread.h"
-#include "GameNetwork/GameSpyOverlay.h"
-
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-
-//-----------------------------------------------------------------------------
-// DEFINES ////////////////////////////////////////////////////////////////////
-//-----------------------------------------------------------------------------
-
-static NameKeyType parentID = NAMEKEY_INVALID;
-static NameKeyType listboxLadderSelectID = NAMEKEY_INVALID;
-static NameKeyType listboxLadderDetailsID = NAMEKEY_INVALID;
-static NameKeyType staticTextLadderNameID = NAMEKEY_INVALID;
-static NameKeyType buttonOkID = NAMEKEY_INVALID;
-static NameKeyType buttonCancelID = NAMEKEY_INVALID;
-
-static GameWindow *parent = NULL;
-static GameWindow *listboxLadderSelect = NULL;
-static GameWindow *listboxLadderDetails = NULL;
-static GameWindow *staticTextLadderName = NULL;
-static GameWindow *buttonOk = NULL;
-static GameWindow *buttonCancel = NULL;
-
-// password entry popup
-static NameKeyType passwordParentID = NAMEKEY_INVALID;
-static NameKeyType buttonPasswordOkID = NAMEKEY_INVALID;
-static NameKeyType buttonPasswordCancelID = NAMEKEY_INVALID;
-static NameKeyType textEntryPasswordID = NAMEKEY_INVALID;
-static GameWindow *passwordParent = NULL;
-static GameWindow *textEntryPassword = NULL;
-
-// incorrect password popup
-static NameKeyType badPasswordParentID = NAMEKEY_INVALID;
-static NameKeyType buttonBadPasswordOkID = NAMEKEY_INVALID;
-static GameWindow *badPasswordParent = NULL;
-
-static void updateLadderDetails( Int ladderID, GameWindow *staticTextLadderName, GameWindow *listboxLadderDetails );
-
-void PopulateQMLadderComboBox( void );
-void PopulateCustomLadderComboBox( void );
-
-void PopulateQMLadderListBox( GameWindow *win );
-void PopulateCustomLadderListBox( GameWindow *win );
-
-void HandleQMLadderSelection(Int ladderID);
-void HandleCustomLadderSelection(Int ladderID);
-
-void CustomMatchHideHostPopup(Bool hide);
-
-static void populateLadderComboBox( void )
-{
- // only one of these will do any work...
- PopulateQMLadderComboBox();
- PopulateCustomLadderComboBox();
-}
-
-static void populateLadderListBox( void )
-{
- // only one of these will do any work...
- PopulateQMLadderListBox(listboxLadderSelect);
- PopulateCustomLadderListBox(listboxLadderSelect);
-
- Int selIndex, selID;
- GadgetListBoxGetSelected(listboxLadderSelect, &selIndex);
- if (selIndex < 0)
- return;
- selID = (Int)GadgetListBoxGetItemData(listboxLadderSelect, selIndex);
- if (!selID)
- return;
- updateLadderDetails(selID, staticTextLadderName, listboxLadderDetails);
-}
-
-static void handleLadderSelection( Int ladderID )
-{
- // only one of these will do any work...
- HandleQMLadderSelection(ladderID);
- HandleCustomLadderSelection(ladderID);
-}
-
-
-enum PasswordMode
-{
- PASS_NONE,
- PASS_ENTRY,
- PASS_ERROR
-};
-
-static PasswordMode s_currentMode = PASS_NONE;
-static void setPasswordMode(PasswordMode mode)
-{
- s_currentMode = mode;
- switch(mode)
- {
- case PASS_NONE:
- if (passwordParent)
- passwordParent->winHide(TRUE);
- if (badPasswordParent)
- badPasswordParent->winHide(TRUE);
- if (buttonOk)
- buttonOk->winEnable(TRUE);
- if (buttonCancel)
- buttonCancel->winEnable(TRUE);
- if (textEntryPassword)
- textEntryPassword->winEnable(FALSE);
- if (listboxLadderSelect)
- listboxLadderSelect->winEnable(TRUE);
- TheWindowManager->winSetFocus(listboxLadderSelect);
- break;
- case PASS_ENTRY:
- if (passwordParent)
- passwordParent->winHide(FALSE);
- if (badPasswordParent)
- badPasswordParent->winHide(TRUE);
- if (buttonOk)
- buttonOk->winEnable(FALSE);
- if (buttonCancel)
- buttonCancel->winEnable(FALSE);
- if (textEntryPassword)
- {
- textEntryPassword->winEnable(TRUE);
- GadgetTextEntrySetText(textEntryPassword, UnicodeString::TheEmptyString);
- }
- if (listboxLadderSelect)
- listboxLadderSelect->winEnable(FALSE);
- TheWindowManager->winSetFocus(textEntryPassword);
- break;
- case PASS_ERROR:
- if (passwordParent)
- passwordParent->winHide(TRUE);
- if (badPasswordParent)
- badPasswordParent->winHide(FALSE);
- if (buttonOk)
- buttonOk->winEnable(FALSE);
- if (buttonCancel)
- buttonCancel->winEnable(FALSE);
- if (textEntryPassword)
- textEntryPassword->winEnable(FALSE);
- if (listboxLadderSelect)
- listboxLadderSelect->winEnable(FALSE);
- TheWindowManager->winSetFocus(parent);
- break;
- }
-}
-
-//-----------------------------------------------------------------------------
-// PUBLIC FUNCTIONS ///////////////////////////////////////////////////////////
-//-----------------------------------------------------------------------------
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the menu */
-//-------------------------------------------------------------------------------------------------
-void PopupLadderSelectInit( WindowLayout *layout, void *userData )
-{
- parentID = NAMEKEY("PopupLadderSelect.wnd:Parent");
- parent = TheWindowManager->winGetWindowFromId(NULL, parentID);
-
- listboxLadderSelectID = NAMEKEY("PopupLadderSelect.wnd:ListBoxLadderSelect");
- listboxLadderSelect = TheWindowManager->winGetWindowFromId(parent, listboxLadderSelectID);
-
- listboxLadderDetailsID = NAMEKEY("PopupLadderSelect.wnd:ListBoxLadderDetails");
- listboxLadderDetails = TheWindowManager->winGetWindowFromId(parent, listboxLadderDetailsID);
-
- staticTextLadderNameID = NAMEKEY("PopupLadderSelect.wnd:StaticTextLadderName");
- staticTextLadderName = TheWindowManager->winGetWindowFromId(parent, staticTextLadderNameID);
-
- buttonOkID = NAMEKEY("PopupLadderSelect.wnd:ButtonOk");
- buttonCancelID = NAMEKEY("PopupLadderSelect.wnd:ButtonCancel");
-
- buttonOk = TheWindowManager->winGetWindowFromId(parent, buttonOkID);
- buttonCancel = TheWindowManager->winGetWindowFromId(parent, buttonCancelID);
-
- TheWindowManager->winSetFocus( parent );
- TheWindowManager->winSetModal( parent );
-
- // password entry popup
- passwordParentID = NAMEKEY("PopupLadderSelect.wnd:PasswordParent");
- passwordParent = TheWindowManager->winGetWindowFromId(parent, passwordParentID);
- buttonPasswordOkID = NAMEKEY("PopupLadderSelect.wnd:ButtonPasswordOk");
- buttonPasswordCancelID = NAMEKEY("PopupLadderSelect.wnd:ButtonPasswordCancel");
- textEntryPasswordID = NAMEKEY("PopupLadderSelect.wnd:PasswordEntry");
- textEntryPassword = TheWindowManager->winGetWindowFromId(parent, textEntryPasswordID);
-
- // bad password popup
- badPasswordParentID = NAMEKEY("PopupLadderSelect.wnd:BadPasswordParent");
- badPasswordParent = TheWindowManager->winGetWindowFromId(parent, badPasswordParentID);
- buttonBadPasswordOkID = NAMEKEY("PopupLadderSelect.wnd:ButtonBadPasswordOk");
-
- setPasswordMode(PASS_NONE);
-
- CustomMatchHideHostPopup(TRUE);
-
- // populate list box (based on whether we're in custom or quickmatch)
- populateLadderListBox();
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType PopupLadderSelectInput( GameWindow *window, UnsignedInt msg, WindowMsgData mData1, WindowMsgData mData2 )
-{
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
- UnsignedByte key = mData1;
- UnsignedByte state = mData2;
-// if (buttonPushed)
-// break;
-
- switch( key )
- {
-
- // ----------------------------------------------------------------------------------------
- case KEY_ESC:
- {
-
- //
- // send a simulated selected event to the parent window of the
- // back/exit button
- //
- if( BitTest( state, KEY_STATE_UP ) )
- {
- switch (s_currentMode)
- {
- case PASS_NONE:
- // re-select whatever was chosen before
- populateLadderComboBox();
- GameSpyCloseOverlay(GSOVERLAY_LADDERSELECT);
- break;
- case PASS_ENTRY:
- case PASS_ERROR:
- setPasswordMode(PASS_NONE);
- break;
- }
-
- } // end if
-
- // don't let key fall through anywhere else
- return MSG_HANDLED;
-
- } // end escape
-
- } // end switch( key )
-
- } // end char
-
- } // end switch( msg )
-
- return MSG_IGNORED;
-
-}
-
-static Int ladderIndex = 0;
-void ladderSelectedCallback(void)
-{
- handleLadderSelection( ladderIndex );
-
- // update combo box
- populateLadderComboBox();
-
- // tear down overlay
- GameSpyCloseOverlay( GSOVERLAY_LADDERSELECT );
-}
-
-//-------------------------------------------------------------------------------------------------
-/** System callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType PopupLadderSelectSystem( GameWindow *window, UnsignedInt msg, WindowMsgData mData1, WindowMsgData mData2 )
-{
- switch( msg )
- {
- // --------------------------------------------------------------------------------------------
- case GWM_CREATE:
- {
- break;
- } // end create
- //---------------------------------------------------------------------------------------------
- case GWM_DESTROY:
- {
- parent = NULL;
- listboxLadderSelect = NULL;
- listboxLadderDetails = NULL;
- CustomMatchHideHostPopup(FALSE);
- break;
- } // end case
-
- //----------------------------------------------------------------------------------------------
- case GWM_INPUT_FOCUS:
- {
- // if we're given the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
- break;
- } // end input
- //----------------------------------------------------------------------------------------------
- case GBM_SELECTED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- if (controlID == buttonOkID)
- {
- // save selection
- Int selectPos = -1;
- GadgetListBoxGetSelected( listboxLadderSelect, &selectPos );
- if (selectPos < 0)
- break;
-
- ladderIndex = (Int)GadgetListBoxGetItemData( listboxLadderSelect, selectPos, 0 );
- const LadderInfo *li = TheLadderList->findLadderByIndex( ladderIndex );
- if (li && li->cryptedPassword.isNotEmpty())
- {
- // need password asking
- setPasswordMode(PASS_ENTRY);
- }
- else
- {
- ladderSelectedCallback();
- }
- }
- else if (controlID == buttonCancelID)
- {
- // reset what had been
- populateLadderComboBox();
-
- // tear down overlay
- GameSpyCloseOverlay( GSOVERLAY_LADDERSELECT );
- }
- else if (controlID == buttonPasswordOkID)
- {
- const LadderInfo *li = TheLadderList->findLadderByIndex( ladderIndex );
- if (!li || li->cryptedPassword.isEmpty())
- {
- // eh? something's not right. just pretend they typed something wrong...
- setPasswordMode(PASS_ERROR);
- break;
- }
-
- AsciiString pass;
- pass.translate(GadgetTextEntryGetText(textEntryPassword));
- if ( pass.isNotEmpty() ) // password ok
- {
- AsciiString cryptPass = EncryptString(pass.str());
- DEBUG_LOG(("pass is %s, crypted pass is %s, comparing to %s\n",
- pass.str(), cryptPass.str(), li->cryptedPassword.str()));
- if (cryptPass == li->cryptedPassword)
- ladderSelectedCallback();
- else
- setPasswordMode(PASS_ERROR);
- }
- else
- {
- setPasswordMode(PASS_ERROR);
- }
- }
- else if (controlID == buttonPasswordCancelID)
- {
- setPasswordMode(PASS_NONE);
- }
- else if (controlID == buttonBadPasswordOkID)
- {
- setPasswordMode(PASS_NONE);
- }
- break;
- } // end input
-
- //---------------------------------------------------------------------------------------------
- case GLM_SELECTED:
- {
- Int selIndex, selID;
- GadgetListBoxGetSelected(listboxLadderSelect, &selIndex);
- if (selIndex < 0)
- break;
-
- selID = (Int)GadgetListBoxGetItemData(listboxLadderSelect, selIndex);
- if (!selID)
- break;
-
- updateLadderDetails(selID, staticTextLadderName, listboxLadderDetails);
- break;
- } // end GLM_DOUBLE_CLICKED
-
- //---------------------------------------------------------------------------------------------
- case GLM_DOUBLE_CLICKED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- Int selectPos = (Int)mData2;
- GadgetListBoxSetSelected(control, &selectPos);
-
- if( controlID == listboxLadderSelectID )
- {
- TheWindowManager->winSendSystemMsg( parent, GBM_SELECTED,
- (WindowMsgData)buttonOk, buttonOk->winGetWindowId() );
- }
- break;
- }
-
- //---------------------------------------------------------------------------------------------
- case GEM_EDIT_DONE:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- if (controlID == textEntryPasswordID)
- {
- TheWindowManager->winSendSystemMsg( parent, GBM_SELECTED,
- (WindowMsgData)(TheWindowManager->winGetWindowFromId(passwordParent, buttonPasswordOkID)), buttonPasswordOkID );
- }
- break;
- }
-
- default:
- return MSG_IGNORED;
-
- } // end switch
-
- return MSG_HANDLED;
-
-}
-
-
-//-----------------------------------------------------------------------------
-// PRIVATE FUNCTIONS //////////////////////////////////////////////////////////
-//-----------------------------------------------------------------------------
-
-static void updateLadderDetails( Int selID, GameWindow *staticTextLadderName, GameWindow *listboxLadderDetails )
-{
- if (!staticTextLadderName || !listboxLadderDetails)
- return;
-
- GadgetStaticTextSetText(staticTextLadderName, UnicodeString::TheEmptyString);
- GadgetListBoxReset(listboxLadderDetails);
-
- const LadderInfo *info = TheLadderList->findLadderByIndex(selID);
- if (!info)
- return;
-
- UnicodeString line;
- Color color = GameMakeColor( 255, 255, 255, 255 );
- Color captionColor = GameMakeColor( 0, 255, 255, 255 );
-
- // name
- line.format(TheGameText->fetch("GUI:LadderNameAndSize"), info->name.str(), info->playersPerTeam, info->playersPerTeam);
- GadgetStaticTextSetText(staticTextLadderName, line);
-
- // location
- if (!info->location.isEmpty())
- GadgetListBoxAddEntryText(listboxLadderDetails, info->location, captionColor, -1);
-
- // homepage
- line.format(TheGameText->fetch("GUI:LadderURL"), info->homepageURL.str());
- GadgetListBoxAddEntryText(listboxLadderDetails, line, captionColor, -1);
-
- // description
- if (!info->description.isEmpty())
- GadgetListBoxAddEntryText(listboxLadderDetails, info->description, color, -1);
-
- // requires password?
- if (info->cryptedPassword.isNotEmpty())
- {
- GadgetListBoxAddEntryText(listboxLadderDetails, TheGameText->fetch("GUI:LadderHasPassword"), captionColor, -1);
- }
-
- // wins limits
- if (info->minWins)
- {
- line.format(TheGameText->fetch("GUI:LadderMinWins"), info->minWins);
- GadgetListBoxAddEntryText(listboxLadderDetails, line, captionColor, -1);
- }
- if (info->maxWins)
- {
- line.format(TheGameText->fetch("GUI:LadderMaxWins"), info->maxWins);
- GadgetListBoxAddEntryText(listboxLadderDetails, line, captionColor, -1);
- }
-
- // random factions?
- if (info->randomFactions)
- {
- GadgetListBoxAddEntryText(listboxLadderDetails, TheGameText->fetch("GUI:LadderRandomFactions"), captionColor, -1);
- }
- else
- {
- GadgetListBoxAddEntryText(listboxLadderDetails, TheGameText->fetch("GUI:LadderFactions"), captionColor, -1);
- }
-
- // factions
- AsciiStringList validFactions = info->validFactions;
- for (AsciiStringListIterator it = validFactions.begin(); it != validFactions.end(); ++it)
- {
- AsciiString marker;
- marker.format("INI:Faction%s", it->str());
- GadgetListBoxAddEntryText(listboxLadderDetails, TheGameText->fetch(marker), color, -1);
- }
-
- // random maps?
- if (info->randomMaps)
- {
- GadgetListBoxAddEntryText(listboxLadderDetails, TheGameText->fetch("GUI:LadderRandomMaps"), captionColor, -1);
- }
- else
- {
- GadgetListBoxAddEntryText(listboxLadderDetails, TheGameText->fetch("GUI:LadderMaps"), captionColor, -1);
- }
-
- // maps
- AsciiStringList validMaps = info->validMaps;
- for (it = validMaps.begin(); it != validMaps.end(); ++it)
- {
- const MapMetaData *md = TheMapCache->findMap(*it);
- if (md)
- {
- GadgetListBoxAddEntryText(listboxLadderDetails, md->m_displayName, color, -1);
- }
- }
-}
-
-static void closeRightClickMenu(GameWindow *win)
-{
-
- if(win)
- {
- WindowLayout *winLay = win->winGetLayout();
- if(!winLay)
- return;
- winLay->destroyWindows();
- winLay->deleteInstance();
- winLay = NULL;
-
- }
-}
-void RCGameDetailsMenuInit( WindowLayout *layout, void *userData )
-{
-}
-
-WindowMsgHandledType RCGameDetailsMenuSystem( GameWindow *window, UnsignedInt msg, WindowMsgData mData1, WindowMsgData mData2 )
-{
-
- static NameKeyType ladderInfoID = NAMEKEY_INVALID;
- static NameKeyType buttonOkID = NAMEKEY_INVALID;
- switch( msg )
- {
-
- case GWM_CREATE:
- {
- ladderInfoID = NAMEKEY("RCGameDetailsMenu.wnd:ButtonLadderDetails");
- buttonOkID = NAMEKEY("PopupLadderDetails.wnd:ButtonOk");
- break;
- } // case GWM_DESTROY:
-
- case GGM_CLOSE:
- {
- closeRightClickMenu(window);
- //rcMenu = NULL;
- break;
- }
-
- case GWM_DESTROY:
- {
- break;
- } // case GWM_DESTROY:
-
- case GBM_SELECTED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- Int selectedID = (Int)window->winGetUserData();
- if(!selectedID)
- break;
- closeRightClickMenu(window);
-
- if (controlID == ladderInfoID)
- {
- StagingRoomMap *srm = TheGameSpyInfo->getStagingRoomList();
- StagingRoomMap::iterator srmIt = srm->find(selectedID);
- if (srmIt != srm->end())
- {
- GameSpyStagingRoom *theRoom = srmIt->second;
- if (!theRoom)
- break;
- const LadderInfo *linfo = TheLadderList->findLadder(theRoom->getLadderIP(), theRoom->getLadderPort());
- if (linfo)
- {
- WindowLayout *rcLayout = TheWindowManager->winCreateLayout(AsciiString("Menus/PopupLadderDetails.wnd"));
- if (!rcLayout)
- break;
-
- GameWindow *rcMenu = rcLayout->getFirstWindow();
- rcMenu->winGetLayout()->runInit();
- rcMenu->winBringToTop();
- rcMenu->winHide(FALSE);
-
- rcMenu->winSetUserData((void *)selectedID);
- TheWindowManager->winSetLoneWindow(rcMenu);
-
- GameWindow *st = TheWindowManager->winGetWindowFromId(NULL,
- NAMEKEY("PopupLadderDetails.wnd:StaticTextLadderName"));
- GameWindow *lb = TheWindowManager->winGetWindowFromId(NULL,
- NAMEKEY("PopupLadderDetails.wnd:ListBoxLadderDetails"));
- updateLadderDetails(selectedID, st, lb);
- }
- }
- }
- break;
- }
- default:
- return MSG_IGNORED;
-
- }//Switch
- return MSG_HANDLED;
-}
diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/ScoreScreen.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/ScoreScreen.cpp
index 46eb2eefce7..f6e95713109 100644
--- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/ScoreScreen.cpp
+++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/ScoreScreen.cpp
@@ -60,7 +60,6 @@
#include "Common/GameEngine.h"
#include "Common/GameLOD.h"
#include "Common/GameState.h"
-#include "Common/GameSpyMiscPreferences.h"
#include "Common/GlobalData.h"
#include "Common/NameKeyGenerator.h"
#include "Common/Player.h"
@@ -90,13 +89,8 @@
#include "GameClient/CampaignManager.h"
#include "GameClient/GameWindowTransitions.h"
#include "GameClient/VideoPlayer.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpy/GameResultsThread.h"
#include "GameNetwork/NetworkDefs.h"
#include "GameNetwork/LANAPICallbacks.h"
-#include "GameNetwork/GameSpyOverlay.h"
-#include "GameNetwork/GameSpy/BuddyThread.h"
-#include "GameNetwork/GameSpy/PersistentStorageThread.h"
#include "GameClient/InGameUI.h"
#include "GameClient/ChallengeGenerals.h"
diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLBuddyOverlay.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLBuddyOverlay.cpp
deleted file mode 100644
index be7280dec14..00000000000
--- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLBuddyOverlay.cpp
+++ /dev/null
@@ -1,1450 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////////////
-// FILE: WOLBuddyOverlay.cpp
-// Author: Chris Huybregts, November 2001
-// Description: Lan Lobby Menu
-///////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/AudioEventRTS.h"
-#include "Common/PlayerList.h"
-#include "Common/Player.h"
-#include "GameClient/GameText.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/Shell.h"
-#include "GameClient/KeyDefs.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/GadgetListBox.h"
-#include "GameClient/GadgetPushButton.h"
-#include "GameClient/GadgetStaticText.h"
-#include "GameClient/GadgetTextEntry.h"
-#include "GameClient/GadgetRadioButton.h"
-#include "GameClient/Display.h"
-#include "GameNetwork/GameSpyOverlay.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpy/BuddyDefs.h"
-#include "GameNetwork/GameSpy/BuddyThread.h"
-#include "GameNetwork/GameSpy/LobbyUtils.h"
-#include "GameNetwork/GameSpy/PersistentStorageDefs.h"
-#include "GameNetwork/GameSpy/PersistentStorageThread.h"
-#include "GameNetwork/GameSpy/ThreadUtils.h"
-
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-
-// window ids ------------------------------------------------------------------------------
-static NameKeyType parentID = NAMEKEY_INVALID;
-static NameKeyType buttonHideID = NAMEKEY_INVALID;
-static NameKeyType buttonAddBuddyID = NAMEKEY_INVALID;
-static NameKeyType buttonDeleteBuddyID = NAMEKEY_INVALID;
-static NameKeyType textEntryID = NAMEKEY_INVALID;
-static NameKeyType listboxBuddyID = NAMEKEY_INVALID;
-static NameKeyType listboxChatID = NAMEKEY_INVALID;
-static NameKeyType buttonAcceptBuddyID = NAMEKEY_INVALID;
-static NameKeyType buttonDenyBuddyID = NAMEKEY_INVALID;
-static NameKeyType radioButtonBuddiesID = NAMEKEY_INVALID;
-static NameKeyType radioButtonIgnoreID = NAMEKEY_INVALID;
-static NameKeyType parentBuddiesID = NAMEKEY_INVALID;
-static NameKeyType parentIgnoreID = NAMEKEY_INVALID;
-static NameKeyType listboxIgnoreID = NAMEKEY_INVALID;
-static NameKeyType buttonNotificationID = NAMEKEY_INVALID;
-
-
-// Window Pointers ------------------------------------------------------------------------
-static GameWindow *parent = NULL;
-static GameWindow *buttonHide = NULL;
-static GameWindow *buttonAddBuddy = NULL;
-static GameWindow *buttonDeleteBuddy = NULL;
-static GameWindow *textEntry = NULL;
-static GameWindow *listboxBuddy = NULL;
-static GameWindow *listboxChat = NULL;
-static GameWindow *buttonAcceptBuddy = NULL;
-static GameWindow *buttonDenyBuddy = NULL;
-static GameWindow *radioButtonBuddies = NULL;
-static GameWindow *radioButtonIgnore = NULL;
-static GameWindow *parentBuddies = NULL;
-static GameWindow *parentIgnore = NULL;
-static GameWindow *listboxIgnore = NULL;
-
-static Bool isOverlayActive = false;
-void insertChat( BuddyMessage msg );
-// RightClick pointers ---------------------------------------------------------------------
-static GameWindow *rcMenu = NULL;
-static WindowLayout *noticeLayout = NULL;
-static UnsignedInt noticeExpires = 0;
-enum { NOTIFICATION_EXPIRES = 3000 };
-
-void setUnignoreText( WindowLayout *layout, AsciiString nick, GPProfile id);
-void refreshIgnoreList( void );
-void showNotificationBox( AsciiString nick, UnicodeString message);
-void deleteNotificationBox( void );
-static Bool lastNotificationWasStatus = FALSE;
-static Int numOnlineInNotification = 0;
-
-class BuddyControls
-{
-public:
- BuddyControls(void );
- GameWindow *listboxChat;
- NameKeyType listboxChatID;
-
- GameWindow *listboxBuddies;
- NameKeyType listboxBuddiesID;
-
- GameWindow *textEntryEdit;
- NameKeyType textEntryEditID;
- Bool isInit;
-};
-
-static BuddyControls buddyControls;
-BuddyControls::BuddyControls( void )
-{
- listboxChat = NULL;
- listboxChatID = NAMEKEY_INVALID;
- listboxBuddies = NULL;
- listboxBuddiesID = NAMEKEY_INVALID;
- textEntryEdit = NULL;
- textEntryEditID = NAMEKEY_INVALID;
- isInit = FALSE;
-}
-// At this point I don't give a damn about how good this way is. I'm doing it anyway.
-enum
-{
- BUDDY_RESETALL_CRAP = -1,
- BUDDY_WINDOW_BUDDIES = 0,
- BUDDY_WINDOW_DIPLOMACY,
- BUDDY_WINDOW_WELCOME_SCREEN,
-};
-
-void InitBuddyControls(Int type)
-{
- if(!TheGameSpyInfo)
- {
- buddyControls.textEntryEditID = NAMEKEY_INVALID;
- buddyControls.textEntryEdit = NULL;
- buddyControls.listboxBuddiesID = NAMEKEY_INVALID;
- buddyControls.listboxChatID = NAMEKEY_INVALID;
- buddyControls.listboxBuddies = NULL;
- buddyControls.listboxChat = NULL;
- buddyControls.isInit = FALSE;
- return;
- }
- switch (type) {
- case BUDDY_RESETALL_CRAP:
- buddyControls.textEntryEditID = NAMEKEY_INVALID;
- buddyControls.textEntryEdit = NULL;
- buddyControls.listboxBuddiesID = NAMEKEY_INVALID;
- buddyControls.listboxChatID = NAMEKEY_INVALID;
- buddyControls.listboxBuddies = NULL;
- buddyControls.listboxChat = NULL;
- buddyControls.isInit = FALSE;
- break;
- case BUDDY_WINDOW_BUDDIES:
- buddyControls.textEntryEditID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:TextEntryChat" ) );
- buddyControls.textEntryEdit = TheWindowManager->winGetWindowFromId(NULL, buddyControls.textEntryEditID);
- buddyControls.listboxBuddiesID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:ListboxBuddies" ) );
- buddyControls.listboxChatID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:ListboxBuddyChat" ) );
- buddyControls.listboxBuddies = TheWindowManager->winGetWindowFromId( NULL, buddyControls.listboxBuddiesID );
- buddyControls.listboxChat = TheWindowManager->winGetWindowFromId( NULL, buddyControls.listboxChatID);
- GadgetTextEntrySetText(buddyControls.textEntryEdit, UnicodeString.TheEmptyString);
- buddyControls.isInit = TRUE;
- break;
- case BUDDY_WINDOW_DIPLOMACY:
- buddyControls.textEntryEditID = TheNameKeyGenerator->nameToKey( AsciiString( "Diplomacy.wnd:TextEntryChat" ) );
- buddyControls.textEntryEdit = TheWindowManager->winGetWindowFromId(NULL, buddyControls.textEntryEditID);
- buddyControls.listboxBuddiesID = TheNameKeyGenerator->nameToKey( AsciiString( "Diplomacy.wnd:ListboxBuddies" ) );
- buddyControls.listboxChatID = TheNameKeyGenerator->nameToKey( AsciiString( "Diplomacy.wnd:ListboxBuddyChat" ) );
- buddyControls.listboxBuddies = TheWindowManager->winGetWindowFromId( NULL, buddyControls.listboxBuddiesID );
- buddyControls.listboxChat = TheWindowManager->winGetWindowFromId( NULL, buddyControls.listboxChatID);
- GadgetTextEntrySetText(buddyControls.textEntryEdit, UnicodeString.TheEmptyString);
- buddyControls.isInit = TRUE;
- break;
- case BUDDY_WINDOW_WELCOME_SCREEN:
- break;
- default:
- DEBUG_ASSERTCRASH(FALSE, ("Well, you really shouldn't have gotten here, if you really care about GUI Bugs, search for this string, you you don't care, call chris (who probably doesn't care either"));
- }
-
-}
-
-WindowMsgHandledType BuddyControlSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2)
-{
- if(!TheGameSpyInfo || TheGameSpyInfo->getLocalProfileID() == 0 || !buddyControls.isInit)
- {
- return MSG_IGNORED;
- }
-
- switch( msg )
- {
- case GLM_RIGHT_CLICKED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if( controlID == buddyControls.listboxBuddiesID )
- {
- RightClickStruct *rc = (RightClickStruct *)mData2;
- WindowLayout *rcLayout;
- if(rc->pos < 0)
- break;
-
- GPProfile profileID = (GPProfile)GadgetListBoxGetItemData(control, rc->pos, 0);
- RCItemType itemType = (RCItemType)(Int)GadgetListBoxGetItemData(control, rc->pos, 1);
- UnicodeString nick = GadgetListBoxGetText(control, rc->pos);
-
- GadgetListBoxSetSelected(control, rc->pos);
- if (itemType == ITEM_BUDDY)
- rcLayout = TheWindowManager->winCreateLayout(AsciiString("Menus/RCBuddiesMenu.wnd"));
- else if (itemType == ITEM_REQUEST)
- rcLayout = TheWindowManager->winCreateLayout(AsciiString("Menus/RCBuddyRequestMenu.wnd"));
- else
- rcLayout = TheWindowManager->winCreateLayout(AsciiString("Menus/RCNonBuddiesMenu.wnd"));
- rcMenu = rcLayout->getFirstWindow();
- rcMenu->winGetLayout()->runInit();
- rcMenu->winBringToTop();
- rcMenu->winHide(FALSE);
-
-
- ICoord2D rcSize, rcPos;
- rcMenu->winGetSize(&rcSize.x, &rcSize.y);
- rcPos.x = rc->mouseX;
- rcPos.y = rc->mouseY;
- if(rc->mouseX + rcSize.x > TheDisplay->getWidth())
- rcPos.x = TheDisplay->getWidth() - rcSize.x;
- if(rc->mouseY + rcSize.y > TheDisplay->getHeight())
- rcPos.y = TheDisplay->getHeight() - rcSize.y;
- rcMenu->winSetPosition(rcPos.x, rcPos.y);
-
-
- GameSpyRCMenuData *rcData = NEW GameSpyRCMenuData;
- rcData->m_id = profileID;
- rcData->m_nick.translate(nick);
- rcData->m_itemType = itemType;
- setUnignoreText(rcLayout, rcData->m_nick, rcData->m_id);
- rcMenu->winSetUserData((void *)rcData);
- TheWindowManager->winSetLoneWindow(rcMenu);
- }
- else
- return MSG_IGNORED;
- break;
- }
- case GEM_EDIT_DONE:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- if(controlID != buddyControls.textEntryEditID)
- return MSG_IGNORED;
-
- // see if someone's selected
- Int selected = -1;
- GadgetListBoxGetSelected(buddyControls.listboxBuddies, &selected);
- if (selected >= 0)
- {
- GPProfile selectedProfile = (GPProfile)GadgetListBoxGetItemData(buddyControls.listboxBuddies, selected);
- BuddyInfoMap *m = TheGameSpyInfo->getBuddyMap();
- BuddyInfoMap::iterator recipIt = m->find(selectedProfile);
- if (recipIt == m->end())
- break;
-
- DEBUG_LOG(("Trying to send a buddy message to %d.\n", selectedProfile));
- if (TheGameSpyGame && TheGameSpyGame->isInGame() && TheGameSpyGame->isGameInProgress() &&
- !ThePlayerList->getLocalPlayer()->isPlayerActive())
- {
- DEBUG_LOG(("I'm dead - gotta look for cheats.\n"));
- for (Int i=0; igetGameSpySlot(i)->getProfileID()));
- if (TheGameSpyGame->getGameSpySlot(i)->getProfileID() == selectedProfile)
- {
- // can't send to someone in our game if we're dead/observing. security breach and all that. no seances for you.
- if (buddyControls.listboxChat)
- {
- GadgetListBoxAddEntryText( buddyControls.listboxChat, TheGameText->fetch("Buddy:CantTalkToIngameBuddy"),
- GameSpyColor[GSCOLOR_DEFAULT], -1, -1 );
- }
- return MSG_HANDLED;
- }
- }
- }
-
- // read the user's input and clear the entry box
- UnicodeString txtInput;
- txtInput.set(GadgetTextEntryGetText( buddyControls.textEntryEdit ));
- GadgetTextEntrySetText(buddyControls.textEntryEdit, UnicodeString::TheEmptyString);
- txtInput.trim();
- if (!txtInput.isEmpty())
- {
- // Send the message
- BuddyRequest req;
- req.buddyRequestType = BuddyRequest::BUDDYREQUEST_MESSAGE;
- wcsncpy(req.arg.message.text, txtInput.str(), MAX_BUDDY_CHAT_LEN);
- req.arg.message.text[MAX_BUDDY_CHAT_LEN-1] = 0;
- req.arg.message.recipient = selectedProfile;
- TheGameSpyBuddyMessageQueue->addRequest(req);
-
- // save message for future incarnations of the buddy window
- BuddyMessageList *messages = TheGameSpyInfo->getBuddyMessages();
- BuddyMessage message;
- message.m_timestamp = time(NULL);
- message.m_senderID = TheGameSpyInfo->getLocalProfileID();
- message.m_senderNick = TheGameSpyInfo->getLocalBaseName();
- message.m_recipientID = selectedProfile;
- message.m_recipientNick = recipIt->second.m_name;
- message.m_message = UnicodeString(req.arg.message.text);
- messages->push_back(message);
-
- // put message on screen
- insertChat(message);
- }
- }
- else
- {
- // nobody selected. Prompt the user.
- if (buddyControls.listboxChat)
- {
- GadgetListBoxAddEntryText( buddyControls.listboxChat, TheGameText->fetch("Buddy:SelectBuddyToChat"),
- GameSpyColor[GSCOLOR_DEFAULT], -1, -1 );
- }
- }
- break;
- }
- default:
- return MSG_IGNORED;
- }
- return MSG_HANDLED;
-}
-
-
-static void insertChat( BuddyMessage msg )
-{
- if (buddyControls.listboxChat)
- {
- BuddyInfoMap *m = TheGameSpyInfo->getBuddyMap();
- BuddyInfoMap::iterator senderIt = m->find(msg.m_senderID);
- BuddyInfoMap::iterator recipientIt = m->find(msg.m_recipientID);
- Bool localSender = (msg.m_senderID == TheGameSpyInfo->getLocalProfileID());
- UnicodeString s;
- //UnicodeString timeStr = UnicodeString(_wctime( (const time_t *)&msg.m_timestamp ));
- UnicodeString timeStr;
- if (localSender /*&& recipientIt != m->end()*/)
- {
- s.format(L"[%hs -> %hs] %s", TheGameSpyInfo->getLocalBaseName().str(), msg.m_recipientNick.str(), msg.m_message.str());
- Int index = GadgetListBoxAddEntryText( buddyControls.listboxChat, s, GameSpyColor[GSCOLOR_PLAYER_SELF], -1, -1 );
- GadgetListBoxAddEntryText( buddyControls.listboxChat, timeStr, GameSpyColor[GSCOLOR_PLAYER_SELF], index, 1);
- }
- else if (!localSender /*&& senderIt != m->end()*/)
- {
- if (!msg.m_senderID)
- {
- s = msg.m_message;
- Int index = GadgetListBoxAddEntryText( buddyControls.listboxChat, s, GameSpyColor[GSCOLOR_DEFAULT], -1, -1 );
- GadgetListBoxAddEntryText( buddyControls.listboxChat, timeStr, GameSpyColor[GSCOLOR_DEFAULT], index, 1);
- }
- else
- {
- s.format(L"[%hs] %s", msg.m_senderNick.str(), msg.m_message.str());
- Int index = GadgetListBoxAddEntryText( buddyControls.listboxChat, s, GameSpyColor[GSCOLOR_PLAYER_BUDDY], -1, -1 );
- GadgetListBoxAddEntryText( buddyControls.listboxChat, timeStr, GameSpyColor[GSCOLOR_PLAYER_BUDDY], index, 1);
- }
- }
- }
-}
-
-void updateBuddyInfo( void )
-{
- if (!TheGameSpyBuddyMessageQueue->isConnected())
- {
- GadgetListBoxReset(buddyControls.listboxBuddies);
- return;
- }
-
- if (!buddyControls.isInit)
- return;
-
- int selected;
- GPProfile selectedProfile = 0;
- int visiblePos = GadgetListBoxGetTopVisibleEntry(buddyControls.listboxBuddies);
-
- GadgetListBoxGetSelected(buddyControls.listboxBuddies, &selected);
- if (selected >= 0)
- selectedProfile = (GPProfile)GadgetListBoxGetItemData(buddyControls.listboxBuddies, selected);
-
- selected = -1;
- GadgetListBoxReset(buddyControls.listboxBuddies);
-
- // Add buddies
- BuddyInfoMap *buddies = TheGameSpyInfo->getBuddyMap();
- BuddyInfoMap::iterator bIt;
- for (bIt = buddies->begin(); bIt != buddies->end(); ++bIt)
- {
- BuddyInfo info = bIt->second;
- GPProfile profileID = bIt->first;
-
- // insert name into box
- UnicodeString formatStr;
- formatStr.translate(info.m_name.str());//, info.m_status, info.m_statusString.str(), info.m_locationString.str());
- Color nameColor = (TheGameSpyInfo->isSavedIgnored(profileID)) ?
- GameSpyColor[GSCOLOR_PLAYER_IGNORED] : GameSpyColor[GSCOLOR_PLAYER_BUDDY];
- int index = GadgetListBoxAddEntryText(buddyControls.listboxBuddies, formatStr, nameColor, -1, -1);
-
- // insert status into box
- AsciiString marker;
- marker.format("Buddy:%ls", info.m_statusString.str());
- if (!info.m_statusString.compareNoCase(L"Offline") ||
- !info.m_statusString.compareNoCase(L"Online") ||
- !info.m_statusString.compareNoCase(L"Matching"))
- {
- formatStr = TheGameText->fetch(marker);
- }
- else if (!info.m_statusString.compareNoCase(L"Staging") ||
- !info.m_statusString.compareNoCase(L"Loading") ||
- !info.m_statusString.compareNoCase(L"Playing"))
- {
- formatStr.format(TheGameText->fetch(marker), info.m_locationString.str());
- }
- else if (!info.m_statusString.compareNoCase(L"Chatting"))
- {
- UnicodeString roomName;
- GroupRoomMap::iterator gIt = TheGameSpyInfo->getGroupRoomList()->find( _wtoi(info.m_locationString.str()) );
- if (gIt != TheGameSpyInfo->getGroupRoomList()->end())
- {
- AsciiString s;
- s.format("GUI:%s", gIt->second.m_name.str());
- roomName = TheGameText->fetch(s);
- }
- formatStr.format(TheGameText->fetch(marker), roomName.str());
- }
- else
- {
- formatStr = info.m_statusString;
- }
- GadgetListBoxAddEntryText(buddyControls.listboxBuddies, formatStr, GameSpyColor[GSCOLOR_DEFAULT], index, 1);
- GadgetListBoxSetItemData(buddyControls.listboxBuddies, (void *)(profileID), index, 0 );
- GadgetListBoxSetItemData(buddyControls.listboxBuddies, (void *)(ITEM_BUDDY), index, 1 );
-
- if (profileID == selectedProfile)
- selected = index;
- }
-
- // add requests
- buddies = TheGameSpyInfo->getBuddyRequestMap();
- for (bIt = buddies->begin(); bIt != buddies->end(); ++bIt)
- {
- BuddyInfo info = bIt->second;
- GPProfile profileID = bIt->first;
-
- // insert name into box
- UnicodeString formatStr;
- formatStr.translate(info.m_name.str());
- int index = GadgetListBoxAddEntryText(buddyControls.listboxBuddies, formatStr, GameSpyColor[GSCOLOR_DEFAULT], -1, -1);
- GadgetListBoxSetItemData(buddyControls.listboxBuddies, (void *)(profileID), index, 0 );
-
- // insert status into box
- formatStr = TheGameText->fetch("GUI:BuddyAddReq");
- GadgetListBoxAddEntryText(buddyControls.listboxBuddies, formatStr, GameSpyColor[GSCOLOR_DEFAULT], index, 1);
- GadgetListBoxSetItemData(buddyControls.listboxBuddies, (void *)(ITEM_REQUEST), index, 1 );
-
- if (profileID == selectedProfile)
- selected = index;
- }
-
-
- // select the same guy
- if (selected >= 0)
- {
- GadgetListBoxSetSelected(buddyControls.listboxBuddies, selected);
- }
-
- // view the same spot
- GadgetListBoxSetTopVisibleEntry(buddyControls.listboxBuddies, visiblePos);
-}
-
-void HandleBuddyResponses( void )
-{
- if (TheGameSpyBuddyMessageQueue)
- {
- BuddyResponse resp;
- if (TheGameSpyBuddyMessageQueue->getResponse( resp ))
- {
- switch (resp.buddyResponseType)
- {
- case BuddyResponse::BUDDYRESPONSE_LOGIN:
- {
- deleteNotificationBox();
- }
- break;
- case BuddyResponse::BUDDYRESPONSE_DISCONNECT:
- {
- lastNotificationWasStatus = FALSE;
- numOnlineInNotification = 0;
- showNotificationBox(AsciiString::TheEmptyString, TheGameText->fetch("Buddy:MessageDisconnected"));
- }
- break;
- case BuddyResponse::BUDDYRESPONSE_MESSAGE:
- {
- if ( !wcscmp(resp.arg.message.text, L"I have authorized your request to add me to your list") )
- break;
-
- if (TheGameSpyInfo->isSavedIgnored(resp.profile))
- {
- //DEBUG_CRASH(("Player is ignored!\n"));
- break; // no buddy messages from ignored people
- }
-
- // save message for future incarnations of the buddy window
- BuddyMessageList *messages = TheGameSpyInfo->getBuddyMessages();
- BuddyMessage message;
- message.m_timestamp = resp.arg.message.date;
- message.m_senderID = resp.profile;
- message.m_recipientID = TheGameSpyInfo->getLocalProfileID();
- message.m_recipientNick = TheGameSpyInfo->getLocalBaseName();
- message.m_message = resp.arg.message.text;
- // insert status into box
- BuddyInfoMap *m = TheGameSpyInfo->getBuddyMap();
- BuddyInfoMap::iterator senderIt = m->find(message.m_senderID);
- AsciiString nick;
- if (senderIt != m->end())
- nick = senderIt->second.m_name.str();
- else
- nick = resp.arg.message.nick;
- message.m_senderNick = nick;
- messages->push_back(message);
-
- DEBUG_LOG(("Inserting buddy chat from '%s'/'%s'\n", nick.str(), resp.arg.message.nick));
-
- // put message on screen
- insertChat(message);
-
- // play audio notification
- AudioEventRTS buddyMsgAudio("GUIMessageReceived");
- if( TheAudio )
- {
- TheAudio->addAudioEvent( &buddyMsgAudio );
- } // end if
-
- UnicodeString snippet = message.m_message;
- while (snippet.getLength() > 11)
- {
- snippet.removeLastChar();
- }
- UnicodeString s;
- s.format(TheGameText->fetch("Buddy:MessageNotification"), nick.str(), snippet.str());
- lastNotificationWasStatus = FALSE;
- numOnlineInNotification = 0;
- showNotificationBox(AsciiString::TheEmptyString, s);
- }
- break;
- case BuddyResponse::BUDDYRESPONSE_REQUEST:
- {
- // save request for future incarnations of the buddy window
- BuddyInfoMap *m = TheGameSpyInfo->getBuddyRequestMap();
- BuddyInfo info;
- info.m_countryCode = resp.arg.request.countrycode;
- info.m_email = resp.arg.request.email;
- info.m_name = resp.arg.request.nick;
- info.m_id = resp.profile;
- info.m_status = (GPEnum)0;
- info.m_statusString = resp.arg.request.text;
- (*m)[resp.profile] = info;
-
- // TODO: put request on screen
- updateBuddyInfo();
- // insert status into box
- lastNotificationWasStatus = FALSE;
- numOnlineInNotification = 0;
- showNotificationBox(info.m_name, TheGameText->fetch("Buddy:AddNotification"));
- }
- break;
- case BuddyResponse::BUDDYRESPONSE_STATUS:
- {
- BuddyInfoMap *m = TheGameSpyInfo->getBuddyMap();
- BuddyInfoMap::const_iterator bit = m->find(resp.profile);
- Bool seenPreviously = FALSE;
- GPEnum oldStatus = GP_OFFLINE;
- GPEnum newStatus = resp.arg.status.status;
- if (bit != m->end())
- {
- seenPreviously = TRUE;
- oldStatus = (*m)[resp.profile].m_status;
- }
- BuddyInfo info;
- info.m_countryCode = resp.arg.status.countrycode;
- info.m_email = resp.arg.status.email;
- info.m_name = resp.arg.status.nick;
- info.m_id = resp.profile;
- info.m_status = newStatus;
- info.m_statusString = UnicodeString(MultiByteToWideCharSingleLine(resp.arg.status.statusString).c_str());
- info.m_locationString = UnicodeString(MultiByteToWideCharSingleLine(resp.arg.status.location).c_str());
- (*m)[resp.profile] = info;
-
- updateBuddyInfo();
- PopulateLobbyPlayerListbox();
- RefreshGameListBoxes();
- if ( (newStatus == GP_OFFLINE && seenPreviously) ||
- (newStatus == GP_ONLINE && (oldStatus == GP_OFFLINE || !seenPreviously)) )
- //if (!info.m_statusString.compareNoCase(L"Offline") ||
- //!info.m_statusString.compareNoCase(L"Online"))
- {
- // insert status into box
- AsciiString marker;
- marker.format("Buddy:%lsNotification", info.m_statusString.str());
-
- lastNotificationWasStatus = TRUE;
- if (newStatus != GP_OFFLINE)
- ++numOnlineInNotification;
-
- showNotificationBox(info.m_name, TheGameText->fetch(marker));
- }
- else if( newStatus == GP_RECV_GAME_INVITE && !seenPreviously)
- {
- lastNotificationWasStatus = TRUE;
- if (newStatus != GP_OFFLINE)
- ++numOnlineInNotification;
-
- showNotificationBox(info.m_name, TheGameText->fetch("Buddy:OnlineNotification"));
- }
- }
- break;
- }
- }
- }
- else
- {
- DEBUG_CRASH(("No buddy message queue!\n"));
- }
- if(noticeLayout && timeGetTime() > noticeExpires)
- {
- deleteNotificationBox();
- }
-}
-
-void showNotificationBox( AsciiString nick, UnicodeString message)
-{
-// if(!GameSpyIsOverlayOpen(GSOVERLAY_BUDDY))
-// return;
- if( !noticeLayout )
- noticeLayout = TheWindowManager->winCreateLayout( "Menus/PopupBuddyListNotification.wnd" );
- noticeLayout->hide( FALSE );
- if (buttonNotificationID == NAMEKEY_INVALID)
- {
- buttonNotificationID = TheNameKeyGenerator->nameToKey("PopupBuddyListNotification.wnd:ButtonNotification");
- }
- GameWindow *win = TheWindowManager->winGetWindowFromId(NULL,buttonNotificationID);
- if(!win)
- {
- deleteNotificationBox();
- return;
- }
-
- if (lastNotificationWasStatus && numOnlineInNotification > 1)
- {
- message = TheGameText->fetch("Buddy:MultipleOnlineNotification");
- }
-
- if (nick.isNotEmpty())
- message.format(message, nick.str());
- GadgetButtonSetText(win, message);
- //GadgetStaticTextSetText(win, message);
- noticeExpires = timeGetTime() + NOTIFICATION_EXPIRES;
- noticeLayout->bringForward();
-
- AudioEventRTS buttonClick("GUICommunicatorIncoming");
-
- if( TheAudio )
- {
- TheAudio->addAudioEvent( &buttonClick );
- } // end if
-
-}
-
-void deleteNotificationBox( void )
-{
- lastNotificationWasStatus = FALSE;
- numOnlineInNotification = 0;
- if(noticeLayout)
- {
- noticeLayout->destroyWindows();
- noticeLayout->deleteInstance();
- noticeLayout = NULL;
- }
-}
-
-void PopulateOldBuddyMessages(void)
-{
- // show previous messages
- BuddyMessageList *messages = TheGameSpyInfo->getBuddyMessages();
- for (BuddyMessageList::iterator mIt = messages->begin(); mIt != messages->end(); ++mIt)
- {
- BuddyMessage message = *mIt;
- insertChat(message);
- }
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the WOL Buddy Overlay */
-//-------------------------------------------------------------------------------------------------
-void WOLBuddyOverlayInit( WindowLayout *layout, void *userData )
-{
- parentID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:BuddyMenuParent" ) );
- buttonHideID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:ButtonHide" ) );
- buttonAddBuddyID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:ButtonAdd" ) );
- buttonDeleteBuddyID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:ButtonDelete" ) );
- //textEntryID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:TextEntryChat" ) );
- //listboxBuddyID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:ListboxBuddies" ) );
- //listboxChatID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:ListboxBuddyChat" ) );
- buttonAcceptBuddyID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:ButtonYes" ) );
- buttonDenyBuddyID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:ButtonNo" ) );
- radioButtonBuddiesID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:RadioButtonBuddies" ) );
- radioButtonIgnoreID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:RadioButtonIgnore" ) );
- parentBuddiesID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:BuddiesParent" ) );
- parentIgnoreID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:IgnoreParent" ) );
- listboxIgnoreID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLBuddyOverlay.wnd:ListboxIgnore" ) );
-
-
- parent = TheWindowManager->winGetWindowFromId( NULL, parentID );
- buttonHide = TheWindowManager->winGetWindowFromId( parent, buttonHideID);
- buttonAddBuddy = TheWindowManager->winGetWindowFromId( parent, buttonAddBuddyID);
- buttonDeleteBuddy = TheWindowManager->winGetWindowFromId( parent, buttonDeleteBuddyID);
- // textEntry = TheWindowManager->winGetWindowFromId( parent, textEntryID);
- //listboxBuddy = TheWindowManager->winGetWindowFromId( parent, listboxBuddyID);
- //listboxChat = TheWindowManager->winGetWindowFromId( parent, listboxChatID);
- buttonAcceptBuddy = TheWindowManager->winGetWindowFromId( parent, buttonAcceptBuddyID);
- buttonDenyBuddy = TheWindowManager->winGetWindowFromId( parent, buttonDenyBuddyID);
- radioButtonBuddies = TheWindowManager->winGetWindowFromId( parent, radioButtonBuddiesID);
- radioButtonIgnore = TheWindowManager->winGetWindowFromId( parent, radioButtonIgnoreID);
- parentBuddies = TheWindowManager->winGetWindowFromId( parent, parentBuddiesID);
- parentIgnore = TheWindowManager->winGetWindowFromId( parent, parentIgnoreID);
- listboxIgnore = TheWindowManager->winGetWindowFromId( parent, listboxIgnoreID);
-
- InitBuddyControls(BUDDY_WINDOW_BUDDIES);
-
- GadgetRadioSetSelection(radioButtonBuddies,FALSE);
- parentBuddies->winHide(FALSE);
- parentIgnore->winHide(TRUE);
-
- //GadgetTextEntrySetText(textEntry, UnicodeString.TheEmptyString);
-
- PopulateOldBuddyMessages();
-
- // Show Menu
- layout->hide( FALSE );
-
- // Set Keyboard to Main Parent
- TheWindowManager->winSetFocus( parent );
-
- isOverlayActive = true;
- updateBuddyInfo();
-
-} // WOLBuddyOverlayInit
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Buddy Overlay shutdown method */
-//-------------------------------------------------------------------------------------------------
-void WOLBuddyOverlayShutdown( WindowLayout *layout, void *userData )
-{
- listboxIgnore = NULL;
-
- // hide menu
- layout->hide( TRUE );
-
- // our shutdown is complete
- //TheShell->shutdownComplete( layout );
-
- isOverlayActive = false;
-
- InitBuddyControls(BUDDY_RESETALL_CRAP);
-
-} // WOLBuddyOverlayShutdown
-
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Buddy Overlay update method */
-//-------------------------------------------------------------------------------------------------
-void WOLBuddyOverlayUpdate( WindowLayout * layout, void *userData)
-{
- if (!TheGameSpyBuddyMessageQueue || !TheGameSpyBuddyMessageQueue->isConnected())
- GameSpyCloseOverlay(GSOVERLAY_BUDDY);
-}// WOLBuddyOverlayUpdate
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Buddy Overlay input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLBuddyOverlayInput( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
- UnsignedByte key = mData1;
- UnsignedByte state = mData2;
-
- switch( key )
- {
-
- // ----------------------------------------------------------------------------------------
- case KEY_ESC:
- {
-
- //
- // send a simulated selected event to the parent window of the
- // back/exit button
- //
- if( BitTest( state, KEY_STATE_UP ) )
- {
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)buttonHide, buttonHideID );
-
- } // end if
-
- // don't let key fall through anywhere else
- return MSG_HANDLED;
-
- } // end escape
-
- } // end switch( key )
-
- } // end char
-
- } // end switch( msg )
-
- return MSG_IGNORED;
-}// WOLBuddyOverlayInput
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Buddy Overlay window system callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLBuddyOverlaySystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- UnicodeString txtInput;
- if(BuddyControlSystem(window, msg, mData1, mData2) == MSG_HANDLED)
- {
- return MSG_HANDLED;
- }
- switch( msg )
- {
-
-
- case GWM_CREATE:
- {
-
- break;
- } // case GWM_DESTROY:
-
- case GWM_DESTROY:
- {
- break;
- } // case GWM_DESTROY:
-
- case GWM_INPUT_FOCUS:
- {
- // if we're givin the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
-
- return MSG_HANDLED;
- }//case GWM_INPUT_FOCUS:
- case GLM_RIGHT_CLICKED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if( controlID == listboxIgnoreID )
- {
- RightClickStruct *rc = (RightClickStruct *)mData2;
- WindowLayout *rcLayout;
- if(rc->pos < 0)
- break;
-
- Bool isBuddy = false, isRequest = false;
- GPProfile profileID = (GPProfile)GadgetListBoxGetItemData(control, rc->pos);
- UnicodeString nick = GadgetListBoxGetText(control, rc->pos);
- BuddyInfoMap *buddies = TheGameSpyInfo->getBuddyMap();
- BuddyInfoMap::iterator bIt;
- bIt = buddies->find(profileID);
- if (bIt != buddies->end())
- {
- isBuddy = true;
- }
- else
- {
- buddies = TheGameSpyInfo->getBuddyRequestMap();
- bIt = buddies->find(profileID);
- if (bIt != buddies->end())
- {
- isRequest = true;
- }
- else
- {
- // neither buddy nor request
- //break;
- }
- }
-
- GadgetListBoxSetSelected(control, rc->pos);
- if (isBuddy)
- rcLayout = TheWindowManager->winCreateLayout(AsciiString("Menus/RCBuddiesMenu.wnd"));
- else if (isRequest)
- rcLayout = TheWindowManager->winCreateLayout(AsciiString("Menus/RCBuddyRequestMenu.wnd"));
- else
- rcLayout = TheWindowManager->winCreateLayout(AsciiString("Menus/RCNonBuddiesMenu.wnd"));
- rcMenu = rcLayout->getFirstWindow();
- rcMenu->winGetLayout()->runInit();
- rcMenu->winBringToTop();
- rcMenu->winHide(FALSE);
-
-
-
- rcMenu->winSetPosition(rc->mouseX, rc->mouseY);
- GameSpyRCMenuData *rcData = NEW GameSpyRCMenuData;
- rcData->m_id = profileID;
- rcData->m_nick.translate(nick);
- rcData->m_itemType = (isBuddy)?ITEM_BUDDY:((isRequest)?ITEM_REQUEST:ITEM_NONBUDDY);
- setUnignoreText(rcLayout, rcData->m_nick, rcData->m_id);
- rcMenu->winSetUserData((void *)rcData);
- TheWindowManager->winSetLoneWindow(rcMenu);
- }
- break;
- }
- case GBM_SELECTED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if (controlID == buttonHideID)
- {
- GameSpyCloseOverlay( GSOVERLAY_BUDDY );
- }
- else if (controlID == radioButtonBuddiesID)
- {
- parentBuddies->winHide(FALSE);
- parentIgnore->winHide(TRUE);
- }
- else if (controlID == radioButtonIgnoreID)
- {
- parentBuddies->winHide(TRUE);
- parentIgnore->winHide(FALSE);
- refreshIgnoreList();
- }
- else if (controlID == buttonAddBuddyID)
- {
- /*
- UnicodeString uName = GadgetTextEntryGetText(textEntry);
- AsciiString aName;
- aName.translate(uName);
- if (!aName.isEmpty())
- {
- TheWOLBuddyList->requestBuddyAdd(aName);
- }
- GadgetTextEntrySetText(textEntry, UnicodeString::TheEmptyString);
- */
- }
- else if (controlID == buttonDeleteBuddyID)
- {
- /*
- int selected;
- AsciiString selectedName = AsciiString::TheEmptyString;
-
- GadgetListBoxGetSelected(listbox, &selected);
- if (selected >= 0)
- selectedName = TheNameKeyGenerator->keyToName((NameKeyType)(int)GadgetListBoxGetItemData(listbox, selected));
-
- if (!selectedName.isEmpty())
- {
- TheWOLBuddyList->requestBuddyDelete(selectedName);
- }
- */
- }
- break;
- }// case GBM_SELECTED:
- case GLM_DOUBLE_CLICKED:
- {
- /*
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- if( controlID == listboxBuddyID )
- {
- int rowSelected = mData2;
-
- if (rowSelected >= 0)
- {
- UnicodeString buddyName;
- GameWindow *listboxWindow = TheWindowManager->winGetWindowFromId( parent, listboxBuddyID );
-
- // get text of buddy name
- buddyName = GadgetListBoxGetText( listboxWindow, rowSelected,0 );
- GPProfile buddyID = (GPProfile)GadgetListBoxGetItemData( listboxWindow, rowSelected, 0 );
-
- Int index = -1;
- gpGetBuddyIndex(TheGPConnection, buddyID, &index);
- if (index >= 0)
- {
- GPBuddyStatus status;
- gpGetBuddyStatus(TheGPConnection, rowSelected, &status);
-
- UnicodeString string;
- string.format(L"To join %s in %hs:", buddyName.str(), status.locationString);
- GameSpyAddText(string, GSCOLOR_DEFAULT);
-
- if (status.status == GP_CHATTING)
- {
- AsciiString location = status.locationString;
- AsciiString val;
- location.nextToken(&val, "/");
- location.nextToken(&val, "/");
- location.nextToken(&val, "/");
-
- string.format(L" ???");
- if (!val.isEmpty())
- {
- Int groupRoom = atoi(val.str());
- if (TheGameSpyChat->getCurrentGroupRoomID() == groupRoom)
- {
- // already there
- string.format(L" nothing");
- GameSpyAddText(string, GSCOLOR_DEFAULT);
- }
- else
- {
- GroupRoomMap *rooms = TheGameSpyChat->getGroupRooms();
- if (rooms)
- {
- Bool needToJoin = true;
- GroupRoomMap::iterator it = rooms->find(groupRoom);
- if (it != rooms->end())
- {
- // he's in a different room
- if (TheGameSpyChat->getCurrentGroupRoomID())
- {
- string.format(L" leave group room");
- GameSpyAddText(string, GSCOLOR_DEFAULT);
-
- TheGameSpyChat->leaveRoom(GroupRoom);
- }
- else if (TheGameSpyGame->isInGame())
- {
- if (TheGameSpyGame->isGameInProgress())
- {
- string.format(L" can't leave game in progress");
- GameSpyAddText(string, GSCOLOR_DEFAULT);
- needToJoin = false;
- }
- else
- {
- string.format(L" leave game setup");
- GameSpyAddText(string, GSCOLOR_DEFAULT);
-
- TheGameSpyChat->leaveRoom(StagingRoom);
- TheGameSpyGame->leaveGame();
- }
- }
- if (needToJoin)
- {
- string.format(L" join lobby %d", groupRoom);
- TheGameSpyChat->joinGroupRoom(groupRoom);
- GameSpyAddText(string, GSCOLOR_DEFAULT);
- }
- }
- }
- }
- }
- }
- }
- else
- {
- DEBUG_CRASH(("No buddy associated with that ProfileID"));
- GameSpyUpdateBuddyOverlay();
- }
- }
- }
- */
- break;
- }
-
- default:
- return MSG_IGNORED;
-
- }//Switch
-
- return MSG_HANDLED;
-}// WOLBuddyOverlaySystem
-
-WindowMsgHandledType PopupBuddyNotificationSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- switch( msg )
- {
- case GWM_CREATE:
- {
- break;
- } // case GWM_DESTROY:
-
- case GWM_DESTROY:
- {
- break;
- } // case GWM_DESTROY:
-
- case GBM_SELECTED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if (controlID == buttonNotificationID)
- {
- GameSpyOpenOverlay( GSOVERLAY_BUDDY );
- }
- break;
- }
-
- default:
- return MSG_IGNORED;
-
- }//Switch
-
- return MSG_HANDLED;
-}// PopupBuddyNotificationSystem
-
-/*
-static NameKeyType buttonAcceptBuddyID = NAMEKEY_INVALID;
-static NameKeyType buttonDenyBuddyID = NAMEKEY_INVALID;
-*/
-static NameKeyType buttonAddID = NAMEKEY_INVALID;
-static NameKeyType buttonDeleteID = NAMEKEY_INVALID;
-static NameKeyType buttonPlayID = NAMEKEY_INVALID;
-static NameKeyType buttonIgnoreID = NAMEKEY_INVALID;
-static NameKeyType buttonStatsID = NAMEKEY_INVALID;
-// Window Pointers ------------------------------------------------------------------------
-//static GameWindow *rCparent = NULL;
-
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Buddy Overlay Right Click menu callbacks */
-//-------------------------------------------------------------------------------------------------
-void WOLBuddyOverlayRCMenuInit( WindowLayout *layout, void *userData )
-{
- AsciiString controlName;
- controlName.format("%s:ButtonAdd",layout->getFilename().str()+6);
- buttonAddID = TheNameKeyGenerator->nameToKey( controlName );
- controlName.format("%s:ButtonDelete",layout->getFilename().str()+6);
- buttonDeleteID = TheNameKeyGenerator->nameToKey( controlName );
- controlName.format("%s:ButtonPlay",layout->getFilename().str()+6);
- buttonPlayID = TheNameKeyGenerator->nameToKey( controlName );
- controlName.format("%s:ButtonIgnore",layout->getFilename().str()+6);
- buttonIgnoreID = TheNameKeyGenerator->nameToKey( controlName );
- controlName.format("%s:ButtonStats",layout->getFilename().str()+6);
- buttonStatsID = TheNameKeyGenerator->nameToKey( controlName );
-}
-static void closeRightClickMenu(GameWindow *win)
-{
-
- if(win)
- {
- WindowLayout *winLay = win->winGetLayout();
- if(!winLay)
- return;
- winLay->destroyWindows();
- winLay->deleteInstance();
- winLay = NULL;
-
- }
-}
-
-void RequestBuddyAdd(Int profileID, AsciiString nick)
-{
- // request to add a buddy
- BuddyRequest req;
- req.buddyRequestType = BuddyRequest::BUDDYREQUEST_ADDBUDDY;
- req.arg.addbuddy.id = profileID;
- UnicodeString buddyAddstr;
- buddyAddstr = TheGameText->fetch("GUI:BuddyAddReq");
- wcsncpy(req.arg.addbuddy.text, buddyAddstr.str(), MAX_BUDDY_CHAT_LEN);
- req.arg.addbuddy.text[MAX_BUDDY_CHAT_LEN-1] = 0;
- TheGameSpyBuddyMessageQueue->addRequest(req);
-
- UnicodeString s;
- Bool exists = TRUE;
- s.format(TheGameText->fetch("Buddy:InviteSent", &exists));
- if (!exists)
- {
- // no string yet. don't display.
- return;
- }
-
- // save message for future incarnations of the buddy window
- BuddyMessageList *messages = TheGameSpyInfo->getBuddyMessages();
- BuddyMessage message;
- message.m_timestamp = time(NULL);
- message.m_senderID = 0;
- message.m_senderNick = "";
- message.m_recipientID = TheGameSpyInfo->getLocalProfileID();
- message.m_recipientNick = TheGameSpyInfo->getLocalBaseName();
- message.m_message.format(TheGameText->fetch("Buddy:InviteSentToPlayer"), nick.str());
-
- // insert status into box
- messages->push_back(message);
-
- DEBUG_LOG(("Inserting buddy add request\n"));
-
- // put message on screen
- insertChat(message);
-
- // play audio notification
- AudioEventRTS buddyMsgAudio("GUIMessageReceived");
- if( TheAudio )
- {
- TheAudio->addAudioEvent( &buddyMsgAudio );
- } // end if
-
- lastNotificationWasStatus = FALSE;
- numOnlineInNotification = 0;
- showNotificationBox(AsciiString::TheEmptyString, s);
-}
-
-WindowMsgHandledType WOLBuddyOverlayRCMenuSystem( GameWindow *window, UnsignedInt msg, WindowMsgData mData1, WindowMsgData mData2 )
-{
-
- switch( msg )
- {
-
- case GWM_CREATE:
- {
-
- break;
- } // case GWM_DESTROY:
-
- case GWM_DESTROY:
- {
- rcMenu = NULL;
- break;
- } // case GWM_DESTROY:
-
- case GGM_CLOSE:
- {
- closeRightClickMenu(window);
- //rcMenu = NULL;
- break;
- }
-
-
- case GBM_SELECTED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- GameSpyRCMenuData *rcData = (GameSpyRCMenuData*)window->winGetUserData();
- if(!rcData)
- break;
- DEBUG_ASSERTCRASH(rcData, ("WOLBuddyOverlayRCMenuSystem GBM_SELECTED:: we're attempting to read the GameSpyRCMenuData from the window, but the data's not there"));
- GPProfile profileID = rcData->m_id;
- AsciiString nick = rcData->m_nick;
-
- Bool isBuddy = false, isRequest = false;
- Bool isGameSpyUser = profileID > 0;
- if (rcData->m_itemType == ITEM_BUDDY)
- isBuddy = TRUE;
- else if (rcData->m_itemType == ITEM_REQUEST)
- isRequest = TRUE;
-
- if(rcData)
- {
- delete rcData;
- rcData = NULL;
- }
- window->winSetUserData(NULL);
- //DEBUG_ASSERTCRASH(profileID > 0, ("Bad profile ID in user data!"));
-
- if( controlID == buttonAddID )
- {
- if(!isGameSpyUser)
- break;
- DEBUG_LOG(("ButtonAdd was pushed\n"));
- if (isRequest)
- {
- // ok the request
- BuddyRequest req;
- req.buddyRequestType = BuddyRequest::BUDDYREQUEST_OKADD;
- req.arg.profile.id = profileID;
- TheGameSpyBuddyMessageQueue->addRequest(req);
-
- BuddyInfoMap *m = TheGameSpyInfo->getBuddyRequestMap();
- m->erase( profileID );
- // if the profile ID is not from a buddy and we're okaying his request, then
- // request to add him to our list automatically CLH 2-18-03
- if(!TheGameSpyInfo->isBuddy(profileID))
- {
- RequestBuddyAdd(profileID, nick);
- }
- updateBuddyInfo();
- }
- else if (!isBuddy)
- {
- RequestBuddyAdd(profileID, nick);
- }
- }
- else if( controlID == buttonDeleteID )
- {
- if(!isGameSpyUser)
- break;
- if (isBuddy)
- {
- // delete the buddy
- BuddyRequest req;
- req.buddyRequestType = BuddyRequest::BUDDYREQUEST_DELBUDDY;
- req.arg.profile.id = profileID;
- TheGameSpyBuddyMessageQueue->addRequest(req);
- }
- else
- {
- // delete the request
- BuddyRequest req;
- req.buddyRequestType = BuddyRequest::BUDDYREQUEST_DENYADD;
- req.arg.profile.id = profileID;
- TheGameSpyBuddyMessageQueue->addRequest(req);
- BuddyInfoMap *m = TheGameSpyInfo->getBuddyRequestMap();
- m->erase( profileID );
- }
- BuddyInfoMap *buddies = (isBuddy)?TheGameSpyInfo->getBuddyMap():TheGameSpyInfo->getBuddyRequestMap();
- buddies->erase(profileID);
- updateBuddyInfo();
- DEBUG_LOG(("ButtonDelete was pushed\n"));
- PopulateLobbyPlayerListbox();
- }
- else if( controlID == buttonPlayID )
- {
- DEBUG_LOG(("buttonPlayID was pushed\n"));
- }
- else if( controlID == buttonIgnoreID )
- {
- DEBUG_LOG(("%s is isGameSpyUser %d", nick.str(), isGameSpyUser));
- if( isGameSpyUser )
- {
- if(TheGameSpyInfo->isSavedIgnored(profileID))
- {
- TheGameSpyInfo->removeFromSavedIgnoreList(profileID);
- }
- else
- {
- TheGameSpyInfo->addToSavedIgnoreList(profileID, nick);
- }
- }
- else
- {
- if(TheGameSpyInfo->isIgnored(nick))
- {
- TheGameSpyInfo->removeFromIgnoreList(nick);
- }
- else
- {
- TheGameSpyInfo->addToIgnoreList(nick);
- }
- }
- updateBuddyInfo();
- refreshIgnoreList();
- // repopulate our player listboxes now
- PopulateLobbyPlayerListbox();
- }
- else if( controlID == buttonStatsID )
- {
- DEBUG_LOG(("buttonStatsID was pushed\n"));
- GameSpyCloseOverlay(GSOVERLAY_PLAYERINFO);
- SetLookAtPlayer(profileID,nick );
- GameSpyOpenOverlay(GSOVERLAY_PLAYERINFO);
- PSRequest req;
- req.requestType = PSRequest::PSREQUEST_READPLAYERSTATS;
- req.player.id = profileID;
- TheGameSpyPSMessageQueue->addRequest(req);
- }
- closeRightClickMenu(window);
- break;
- }
- default:
- return MSG_IGNORED;
-
- }//Switch
- return MSG_HANDLED;
-}
-
-
-void setUnignoreText( WindowLayout *layout, AsciiString nick, GPProfile id)
-{
- AsciiString controlName;
- controlName.format("%s:ButtonIgnore",layout->getFilename().str()+6);
- NameKeyType ID = TheNameKeyGenerator->nameToKey( controlName );
- GameWindow *win = TheWindowManager->winGetWindowFromId(layout->getFirstWindow(), ID);
- if(win)
- {
- if(TheGameSpyInfo->isSavedIgnored(id) || TheGameSpyInfo->isIgnored(nick))
- GadgetButtonSetText(win, TheGameText->fetch("GUI:Unignore"));
- }
-}
-
-void refreshIgnoreList( void )
-{
-
-
- SavedIgnoreMap tempMap;
- tempMap = TheGameSpyInfo->returnSavedIgnoreList();
- SavedIgnoreMap::iterator it = tempMap.begin();
- GadgetListBoxReset(listboxIgnore);
- while(it != tempMap.end())
- {
- UnicodeString name;
- name.translate(it->second);
- Int pos = GadgetListBoxAddEntryText(listboxIgnore, name, GameMakeColor(255,100,100,255),-1);
- GadgetListBoxSetItemData(listboxIgnore, (void *)it->first,pos );
- ++it;
- }
- IgnoreList tempList;
- tempList = TheGameSpyInfo->returnIgnoreList();
- IgnoreList::iterator iListIt = tempList.begin();
- while( iListIt != tempList.end())
- {
- AsciiString aName = *iListIt;
- UnicodeString name;
- name.translate(aName);
- Int pos = GadgetListBoxAddEntryText(listboxIgnore, name, GameMakeColor(255,100,100,255),-1);
- GadgetListBoxSetItemData(listboxIgnore, 0,pos );
- ++iListIt;
- }
-
-//
-// GPProfile profileID = 0;
-// PlayerInfoMap::iterator it = TheGameSpyInfo->getPlayerInfoMap()->find(aName);
-// if (it != TheGameSpyInfo->getPlayerInfoMap()->end())
-// profileID = it->second.m_profileID;
-
-}
diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLCustomScoreScreen.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLCustomScoreScreen.cpp
deleted file mode 100644
index a045c27f255..00000000000
--- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLCustomScoreScreen.cpp
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////////////
-// FILE: WOLCustomScoreScreen.cpp
-// Author: Matt Campbell, December 2001
-// Description: Custom match score screen
-///////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Lib/BaseType.h"
-#include "Common/GameEngine.h"
-#include "Common/NameKeyGenerator.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/Shell.h"
-#include "GameClient/KeyDefs.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/GadgetListBox.h"
-#include "GameClient/GadgetTextEntry.h"
-#include "Common/GlobalData.h"
-//#include "GameNetwork/WOL.h"
-//#include "GameNetwork/WOLmenus.h"
-
-
-
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-// window ids ------------------------------------------------------------------------------
-static NameKeyType parentWOLCustomScoreID = NAMEKEY_INVALID;
-static NameKeyType buttonDisconnectID = NAMEKEY_INVALID;
-static NameKeyType buttonLobbyID = NAMEKEY_INVALID;
-
-// Window Pointers ------------------------------------------------------------------------
-static GameWindow *parentWOLCustomScore = NULL;
-static GameWindow *buttonDisconnect = NULL;
-static GameWindow *buttonLobby = NULL;
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the WOL Status Menu */
-//-------------------------------------------------------------------------------------------------
-void WOLCustomScoreScreenInit( WindowLayout *layout, void *userData )
-{
- parentWOLCustomScoreID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLCustomScoreScreen.wnd:WOLCustomScoreScreenParent" ) );
- buttonDisconnectID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLCustomScoreScreen.wnd:ButtonDisconnect" ) );
- buttonLobbyID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLCustomScoreScreen.wnd:ButtonLobby" ) );
- parentWOLCustomScore = TheWindowManager->winGetWindowFromId( NULL, parentWOLCustomScoreID );
- buttonDisconnect = TheWindowManager->winGetWindowFromId( NULL, buttonDisconnectID);
- buttonLobby = TheWindowManager->winGetWindowFromId( NULL, buttonLobbyID);
-
- /*
- if (WOL::TheWOL->getState() == WOL::WOLAPI_FATAL_ERROR)
- {
- // We can get to the score screen even though we've been disconnected. Just hide
- // any buttons that lead back into WOL.
- buttonLobby->winHide( TRUE );
- }
- */
-
- // Show Menu
- layout->hide( FALSE );
-
- // Set Keyboard to Main Parent
- TheWindowManager->winSetFocus( parentWOLCustomScore );
-} // WOLCustomScoreScreenInit
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Status Menu shutdown method */
-//-------------------------------------------------------------------------------------------------
-void WOLCustomScoreScreenShutdown( WindowLayout *layout, void *userData )
-{
- // hide menu
- layout->hide( TRUE );
-
- // our shutdown is complete
- TheShell->shutdownComplete( layout );
-} // WOLCustomScoreScreenShutdown
-
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Status Menu update method */
-//-------------------------------------------------------------------------------------------------
-void WOLCustomScoreScreenUpdate( WindowLayout * layout, void *userData)
-{
- /*
- if (WOL::TheWOL)
- WOL::TheWOL->update();
- */
-}// WOLCustomScoreScreenUpdate
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Status Menu input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLCustomScoreScreenInput( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
- UnsignedByte key = mData1;
- UnsignedByte state = mData2;
-
- switch( key )
- {
-
- // ----------------------------------------------------------------------------------------
- case KEY_ESC:
- {
-
- //
- // send a simulated selected event to the parent window of the
- // back/exit button
- //
- if( BitTest( state, KEY_STATE_UP ) )
- {
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)buttonDisconnect, buttonDisconnectID );
-
- } // end if
-
- // don't let key fall through anywhere else
- return MSG_HANDLED;
-
- } // end escape
-
- } // end switch( key )
-
- } // end char
-
- } // end switch( msg )
-
- return MSG_IGNORED;
-}// WOLCustomScoreScreenInput
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Status Menu window system callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLCustomScoreScreenSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- UnicodeString txtInput;
-
- switch( msg )
- {
-
- case GWM_CREATE:
- {
-
- break;
- } // case GWM_DESTROY:
-
- case GWM_DESTROY:
- {
- break;
- } // case GWM_DESTROY:
-
- case GWM_INPUT_FOCUS:
- {
- // if we're given the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
-
- return MSG_HANDLED;
- }//case GWM_INPUT_FOCUS:
-
- case GBM_SELECTED:
- {
- /*
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if ( controlID == buttonDisconnectID )
- {
- if (WOL::TheWOL->setState( WOL::WOLAPI_FATAL_ERROR ))
- {
- WOL::TheWOL->addCommand( WOL::WOLCOMMAND_RESET ); // don't display an error, log out, or anything
- }
-
- } //if ( controlID == buttonDisconnect )
- else if ( controlID == buttonLobbyID )
- {
- if (WOL::TheWOL->getState() != WOL::WOLAPI_FATAL_ERROR)
- {
- WOL::TheWOL->setScreen(WOL::WOLAPI_MENU_CUSTOMLOBBY);
- WOL::TheWOL->setGameMode(WOL::WOLTYPE_CUSTOM);
- WOL::TheWOL->setState( WOL::WOLAPI_LOBBY );
- WOL::TheWOL->addCommand( WOL::WOLCOMMAND_REFRESH_CHANNELS );
- }
- else
- {
- }
- } //if ( controlID == buttonDisconnect )
- */
- break;
- }// case GBM_SELECTED:
-
- case GEM_EDIT_DONE:
- {
- break;
- }
- default:
- return MSG_IGNORED;
-
- }//Switch
-
- return MSG_HANDLED;
-}// WOLCustomScoreScreenSystem
diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp
deleted file mode 100644
index 43d42d7e109..00000000000
--- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp
+++ /dev/null
@@ -1,2887 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////////////
-// FILE: WOLGameSetupMenu.cpp
-// Author: Matt Campbell, December 2001
-// Description: WOL Game Options Menu
-///////////////////////////////////////////////////////////////////////////////////////
-
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/GameEngine.h"
-#include "Common/GameState.h"
-#include "GameClient/GameText.h"
-#include "Common/MultiplayerSettings.h"
-#include "Common/PlayerTemplate.h"
-#include "Common/CustomMatchPreferences.h"
-#include "GameClient/AnimateWindowManager.h"
-#include "GameClient/InGameUI.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Mouse.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/Shell.h"
-#include "GameClient/KeyDefs.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/GadgetComboBox.h"
-#include "GameClient/GadgetListBox.h"
-#include "GameClient/GadgetTextEntry.h"
-#include "GameClient/GadgetPushButton.h"
-#include "GameClient/GadgetStaticText.h"
-#include "GameClient/GadgetCheckBox.h"
-#include "GameClient/MapUtil.h"
-#include "GameClient/EstablishConnectionsMenu.h"
-#include "GameClient/GameWindowTransitions.h"
-#include "GameNetwork/GameSpy/LobbyUtils.h"
-
-#include "GameNetwork/GameSpy/BuddyDefs.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpy/PeerThread.h"
-#include "GameNetwork/GameSpy/PersistentStorageDefs.h"
-#include "GameNetwork/GameSpy/PersistentStorageThread.h"
-#include "GameNetwork/GameSpyOverlay.h"
-#include "GameNetwork/NAT.h"
-#include "GameNetwork/GUIUtil.h"
-#include "GameNetwork/GameSpy/GSConfig.h"
-
-void WOLDisplaySlotList( void );
-
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-
-extern std::list TheLobbyQueuedUTMs;
-extern void MapSelectorTooltip(GameWindow *window, WinInstanceData *instData, UnsignedInt mouse);
-
-
-#if defined(_DEBUG) || defined(_INTERNAL)
-extern Bool g_debugSlots;
-void slotListDebugLog(const char *fmt, ...)
-{
- static char buf[1024];
- va_list va;
- va_start( va, fmt );
- _vsnprintf(buf, 1024, fmt, va );
- va_end( va );
- buf[1023] = 0;
-
- DEBUG_LOG(("%s", buf));
- if (g_debugSlots)
- {
- UnicodeString msg;
- msg.translate(buf);
- TheGameSpyInfo->addText(msg, GameSpyColor[GSCOLOR_DEFAULT], NULL);
- }
-}
-#define SLOTLIST_DEBUG_LOG(x) slotListDebugLog x
-#else
-#define SLOTLIST_DEBUG_LOG(x) DEBUG_LOG(x)
-#endif
-
-void SendStatsToOtherPlayers(const GameInfo *game)
-{
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMPLAYER;
- req.UTM.isStagingRoom = TRUE;
- req.id = "STATS/";
- AsciiString fullStr;
- PSPlayerStats fullStats = TheGameSpyPSMessageQueue->findPlayerStatsByID(TheGameSpyInfo->getLocalProfileID());
- PSPlayerStats subStats;
- subStats.id = fullStats.id;
- subStats.wins = fullStats.wins;
- subStats.losses = fullStats.losses;
- subStats.discons = fullStats.discons;
- subStats.desyncs = fullStats.desyncs;
- subStats.games = fullStats.games;
- subStats.locale = fullStats.locale;
- subStats.gamesAsRandom = fullStats.gamesAsRandom;
- GetAdditionalDisconnectsFromUserFile(&subStats);
- fullStr.format("%d %s", TheGameSpyInfo->getLocalProfileID(), TheGameSpyPSMessageQueue->formatPlayerKVPairs( subStats ));
- req.options = fullStr.str();
-
- Int localIndex = game->getLocalSlotNum();
- for (Int i=0; igetConstSlot(i);
- if (slot->isHuman() && i != localIndex)
- {
- AsciiString hostName;
- hostName.translate(slot->getName());
- req.nick = hostName.str();
- DEBUG_LOG(("SendStatsToOtherPlayers() - sending to '%s', data of\n\t'%s'\n", hostName.str(), req.options.c_str()));
- TheGameSpyPeerMessageQueue->addRequest(req);
- }
- }
-}
-
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-static Bool isShuttingDown = false;
-static Bool buttonPushed = false;
-static char *nextScreen = NULL;
-static Bool raiseMessageBoxes = false;
-static Bool launchGameNext = FALSE;
-
-// window ids ------------------------------------------------------------------------------
-static NameKeyType parentWOLGameSetupID = NAMEKEY_INVALID;
-
-static NameKeyType comboBoxPlayerID[MAX_SLOTS] = { NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID };
-
-static NameKeyType staticTextPlayerID[MAX_SLOTS] = { NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID };
-
-static NameKeyType buttonAcceptID[MAX_SLOTS] = { NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID };
-
-static NameKeyType comboBoxColorID[MAX_SLOTS] = { NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID };
-
-static NameKeyType comboBoxPlayerTemplateID[MAX_SLOTS] = { NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID };
-
-static NameKeyType comboBoxTeamID[MAX_SLOTS] = { NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID };
-//static NameKeyType buttonStartPositionID[MAX_SLOTS] = { NAMEKEY_INVALID,NAMEKEY_INVALID,
-// NAMEKEY_INVALID,NAMEKEY_INVALID,
-// NAMEKEY_INVALID,NAMEKEY_INVALID,
-// NAMEKEY_INVALID,NAMEKEY_INVALID };
-
-static NameKeyType buttonMapStartPositionID[MAX_SLOTS] = { NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID };
-static NameKeyType genericPingWindowID[MAX_SLOTS] = { NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID };
-
-static NameKeyType textEntryChatID = NAMEKEY_INVALID;
-static NameKeyType textEntryMapDisplayID = NAMEKEY_INVALID;
-static NameKeyType buttonBackID = NAMEKEY_INVALID;
-static NameKeyType buttonStartID = NAMEKEY_INVALID;
-static NameKeyType buttonEmoteID = NAMEKEY_INVALID;
-static NameKeyType buttonSelectMapID = NAMEKEY_INVALID;
-static NameKeyType windowMapID = NAMEKEY_INVALID;
-
-static NameKeyType windowMapSelectMapID = NAMEKEY_INVALID;
-static NameKeyType checkBoxUseStatsID = NAMEKEY_INVALID;
-static NameKeyType checkBoxLimitSuperweaponsID = NAMEKEY_INVALID;
-static NameKeyType comboBoxStartingCashID = NAMEKEY_INVALID;
-static NameKeyType checkBoxLimitArmiesID = NAMEKEY_INVALID;
-
-// Window Pointers ------------------------------------------------------------------------
-static GameWindow *parentWOLGameSetup = NULL;
-static GameWindow *buttonBack = NULL;
-static GameWindow *buttonStart = NULL;
-static GameWindow *buttonSelectMap = NULL;
-static GameWindow *buttonEmote = NULL;
-static GameWindow *textEntryChat = NULL;
-static GameWindow *textEntryMapDisplay = NULL;
-static GameWindow *windowMap = NULL;
-static GameWindow *checkBoxUseStats = NULL;
-static GameWindow *checkBoxLimitSuperweapons = NULL;
-static GameWindow *comboBoxStartingCash = NULL;
-static GameWindow *checkBoxLimitArmies = NULL;
-
-static GameWindow *comboBoxPlayer[MAX_SLOTS] = {NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL };
-static GameWindow *staticTextPlayer[MAX_SLOTS] = {NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL };
-static GameWindow *buttonAccept[MAX_SLOTS] = {NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL };
-
-static GameWindow *comboBoxColor[MAX_SLOTS] = {NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL };
-
-static GameWindow *comboBoxPlayerTemplate[MAX_SLOTS] = {NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL };
-
-static GameWindow *comboBoxTeam[MAX_SLOTS] = {NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL };
-
-//static GameWindow *buttonStartPosition[MAX_SLOTS] = {NULL,NULL,NULL,NULL,
-// NULL,NULL,NULL,NULL };
-//
-static GameWindow *buttonMapStartPosition[MAX_SLOTS] = {NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL };
-
-static GameWindow *genericPingWindow[MAX_SLOTS] = {NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL };
-
-static const Image *pingImages[3] = { NULL, NULL, NULL };
-
-WindowLayout *WOLMapSelectLayout = NULL;
-
-void PopBackToLobby( void )
-{
- // delete TheNAT, its no good for us anymore.
- delete TheNAT;
- TheNAT = NULL;
-
- if (TheGameSpyInfo) // this can be blown away by a disconnect on the map transfer screen
- {
- TheGameSpyInfo->getCurrentStagingRoom()->reset();
- TheGameSpyInfo->leaveStagingRoom();
- //TheGameSpyInfo->joinBestGroupRoom();
- }
-
- DEBUG_LOG(("PopBackToLobby() - parentWOLGameSetup is %X\n", parentWOLGameSetup));
- if (parentWOLGameSetup)
- {
- nextScreen = "Menus/WOLCustomLobby.wnd";
- TheShell->pop();
- }
-}
-
-void updateMapStartSpots( GameInfo *myGame, GameWindow *buttonMapStartPositions[], Bool onLoadScreen = FALSE );
-void positionStartSpots( GameInfo *myGame, GameWindow *buttonMapStartPositions[], GameWindow *mapWindow);
-void positionStartSpots(AsciiString mapName, GameWindow *buttonMapStartPositions[], GameWindow *mapWindow);
-void WOLPositionStartSpots( void )
-{
- GameWindow *win = windowMap;
- if (WOLMapSelectLayout != NULL) {
- win = TheWindowManager->winGetWindowFromId(NULL, windowMapSelectMapID);
-
- // get the controls.
- NameKeyType listboxMapID = TheNameKeyGenerator->nameToKey( AsciiString("WOLMapSelectMenu.wnd:ListboxMap") );
- GameWindow *listboxMap = TheWindowManager->winGetWindowFromId( NULL, listboxMapID );
-
- if (listboxMap != NULL) {
- Int selected;
- UnicodeString map;
-
- // get the selected index
- GadgetListBoxGetSelected( listboxMap, &selected );
-
- if( selected != -1 )
- {
-
- // get text of the map to load
- map = GadgetListBoxGetText( listboxMap, selected, 0 );
-
-
- // set the map name in the global data map name
- AsciiString asciiMap;
- const char *mapFname = (const char *)GadgetListBoxGetItemData( listboxMap, selected );
- DEBUG_ASSERTCRASH(mapFname, ("No map item data"));
- if (mapFname) {
- asciiMap = mapFname;
- } else {
- asciiMap.translate( map );
- }
-
- positionStartSpots(asciiMap, buttonMapStartPosition, win);
- }
- }
-
- } else {
- DEBUG_ASSERTCRASH(win != NULL, ("no map preview window"));
- positionStartSpots( TheGameSpyInfo->getCurrentStagingRoom(), buttonMapStartPosition, win);
- }
-}
-static void savePlayerInfo( void )
-{
- if (TheGameSpyGame)
- {
- Int slotNum = TheGameSpyGame->getLocalSlotNum();
- if (slotNum >= 0)
- {
- GameSpyGameSlot *slot = TheGameSpyGame->getGameSpySlot(slotNum);
- if (slot)
- {
- // save off some prefs
- CustomMatchPreferences pref;
- pref.setPreferredColor(slot->getColor());
- pref.setPreferredFaction(slot->getPlayerTemplate());
- if (TheGameSpyGame->amIHost())
- {
- pref.setPreferredMap(TheGameSpyGame->getMap());
- pref.setSuperweaponRestricted( TheGameSpyGame->getSuperweaponRestriction() != 0 );
- pref.setStartingCash( TheGameSpyGame->getStartingCash() );
- }
- pref.write();
- }
- }
- }
-}
-
-// Tooltips -------------------------------------------------------------------------------
-
-static void playerTooltip(GameWindow *window,
- WinInstanceData *instData,
- UnsignedInt mouse)
-{
- Int slotIdx = -1;
- for (Int i=0; isetCursorTooltip( UnicodeString::TheEmptyString, -1, NULL, 1.5f );
- return;
- }
-
- GameSpyStagingRoom *game = TheGameSpyInfo->getCurrentStagingRoom();
- if (!game)
- {
- TheMouse->setCursorTooltip( UnicodeString::TheEmptyString, -1, NULL, 1.5f );
- return;
- }
-
- GameSpyGameSlot *slot = game->getGameSpySlot(slotIdx);
- if (!slot || !slot->isHuman())
- {
- TheMouse->setCursorTooltip( UnicodeString::TheEmptyString, -1, NULL, 1.5f );
- return;
- }
-
- // for tooltip, we want:
- // * player name
- // * ping
- // * locale
- // * win/loss history
- // * discons/desyncs as one var
- // * favorite army
- // in that order. got it? good.
-
- UnicodeString uName = slot->getName();
-
- AsciiString aName;
- aName.translate(uName);
- PlayerInfoMap::iterator pmIt = TheGameSpyInfo->getPlayerInfoMap()->find(aName);
- if (pmIt == TheGameSpyInfo->getPlayerInfoMap()->end())
- {
- TheMouse->setCursorTooltip( uName, -1, NULL, 1.5f );
- return;
- }
- Int profileID = pmIt->second.m_profileID;
-
- PSPlayerStats stats = TheGameSpyPSMessageQueue->findPlayerStatsByID(profileID);
- if (stats.id == 0)
- {
- TheMouse->setCursorTooltip( uName, -1, NULL, 1.5f );
- return;
- }
-
- Bool isLocalPlayer = slot == game->getGameSpySlot(game->getLocalSlotNum());
-
- AsciiString localeIdentifier;
- localeIdentifier.format("WOL:Locale%2.2d", stats.locale);
- UnicodeString playerInfo;
- Int totalWins = 0, totalLosses = 0, totalDiscons = 0;
- PerGeneralMap::iterator it;
-
- for (it = stats.wins.begin(); it != stats.wins.end(); ++it)
- {
- totalWins += it->second;
- }
- for (it = stats.losses.begin(); it != stats.losses.end(); ++it)
- {
- totalLosses += it->second;
- }
- for (it = stats.discons.begin(); it != stats.discons.end(); ++it)
- {
- totalDiscons += it->second;
- }
- for (it = stats.desyncs.begin(); it != stats.desyncs.end(); ++it)
- {
- totalDiscons += it->second;
- }
- UnicodeString favoriteSide;
- Int numGames = 0;
- Int favorite = 0;
- for(it = stats.games.begin(); it != stats.games.end(); ++it)
- {
- if(it->second >= numGames)
- {
- numGames = it->second;
- favorite = it->first;
- }
- }
- if(numGames == 0)
- favoriteSide = TheGameText->fetch("GUI:None");
- else if( stats.gamesAsRandom >= numGames )
- favoriteSide = TheGameText->fetch("GUI:Random");
- else
- {
- const PlayerTemplate *fac = ThePlayerTemplateStore->getNthPlayerTemplate(favorite);
- if (fac)
- {
- AsciiString side;
- side.format("SIDE:%s", fac->getSide().str());
-
- favoriteSide = TheGameText->fetch(side);
- }
- }
-
- playerInfo.format(TheGameText->fetch("TOOLTIP:StagingPlayerInfo"),
- TheGameText->fetch(localeIdentifier).str(),
- slot->getPingAsInt(),
- totalWins, totalLosses, totalDiscons,
- favoriteSide.str());
-
- UnicodeString tooltip = UnicodeString::TheEmptyString;
- if (isLocalPlayer)
- {
- tooltip.format(TheGameText->fetch("TOOLTIP:LocalPlayer"), uName.str());
- }
- else
- {
- // not us
- if (TheGameSpyInfo->getBuddyMap()->find(profileID) != TheGameSpyInfo->getBuddyMap()->end())
- {
- // buddy
- tooltip.format(TheGameText->fetch("TOOLTIP:BuddyPlayer"), uName.str());
- }
- else
- {
- if (profileID)
- {
- // non-buddy profiled player
- tooltip.format(TheGameText->fetch("TOOLTIP:ProfiledPlayer"), uName.str());
- }
- else
- {
- // non-profiled player
- tooltip.format(TheGameText->fetch("TOOLTIP:GenericPlayer"), uName.str());
- }
- }
- }
-
- tooltip.concat(playerInfo);
-
- TheMouse->setCursorTooltip( tooltip, -1, NULL, 1.5f ); // the text and width are the only params used. the others are the default values.
-}
-
-void gameAcceptTooltip(GameWindow *window, WinInstanceData *instData, UnsignedInt mouse)
-{
- Int x, y;
- x = LOLONGTOSHORT(mouse);
- y = HILONGTOSHORT(mouse);
-
- Int winPosX, winPosY, winWidth, winHeight;
-
- window->winGetScreenPosition(&winPosX, &winPosY);
-
- window->winGetSize(&winWidth, &winHeight);
-
- if ((x > winPosX && x < (winPosX + winWidth)) && (y > winPosY && y < (winPosY + winHeight)))
- {
- TheMouse->setCursorTooltip(TheGameText->fetch("TOOLTIP:GameAcceptance"), -1, NULL);
- }
-}
-
-void pingTooltip(GameWindow *window, WinInstanceData *instData, UnsignedInt mouse)
-{
- Int x, y;
- x = LOLONGTOSHORT(mouse);
- y = HILONGTOSHORT(mouse);
-
-
- Int winPosX, winPosY, winWidth, winHeight;
-
- window->winGetScreenPosition(&winPosX, &winPosY);
-
- window->winGetSize(&winWidth, &winHeight);
-
- if ((x > winPosX && x < (winPosX + winWidth)) && (y > winPosY && y < (winPosY + winHeight)))
- {
- TheMouse->setCursorTooltip(TheGameText->fetch("TOOLTIP:ConnectionSpeed"), -1, NULL);
- }
-}
-
-//external declarations of the Gadgets the callbacks can use
-GameWindow *listboxGameSetupChat = NULL;
-NameKeyType listboxGameSetupChatID = NAMEKEY_INVALID;
-
-static void handleColorSelection(int index)
-{
- GameWindow *combo = comboBoxColor[index];
- Int color, selIndex;
- GadgetComboBoxGetSelectedPos(combo, &selIndex);
- color = (Int)GadgetComboBoxGetItemData(combo, selIndex);
-
- GameInfo *myGame = TheGameSpyInfo->getCurrentStagingRoom();
-
- if (myGame)
- {
- GameSlot * slot = myGame->getSlot(index);
- if (color == slot->getColor())
- return;
-
- if (color >= -1 && color < TheMultiplayerSettings->getNumColors())
- {
- Bool colorAvailable = TRUE;
- if(color != -1 )
- {
- for(Int i=0; i getSlot(i);
- if(color == checkSlot->getColor() && slot != checkSlot)
- {
- colorAvailable = FALSE;
- break;
- }
- }
- }
- if(!colorAvailable)
- return;
- }
-
- slot->setColor(color);
-
- if (TheGameSpyInfo->amIHost())
- {
- // send around a new slotlist
- TheGameSpyInfo->setGameOptions();
- WOLDisplaySlotList();
- }
- else
- {
- // request the color from the host
- if (!slot->isPlayer(TheGameSpyInfo->getLocalName()))
- return;
-
- AsciiString options;
- options.format("Color=%d", color);
- AsciiString hostName;
- hostName.translate(myGame->getSlot(0)->getName());
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMPLAYER;
- req.UTM.isStagingRoom = TRUE;
- req.id = "REQ/";
- req.nick = hostName.str();
- req.options = options.str();
- TheGameSpyPeerMessageQueue->addRequest(req);
- }
- }
-}
-
-static void handlePlayerTemplateSelection(int index)
-{
- GameWindow *combo = comboBoxPlayerTemplate[index];
- Int playerTemplate, selIndex;
- GadgetComboBoxGetSelectedPos(combo, &selIndex);
- playerTemplate = (Int)GadgetComboBoxGetItemData(combo, selIndex);
- GameInfo *myGame = TheGameSpyInfo->getCurrentStagingRoom();
-
- if (myGame)
- {
- GameSlot * slot = myGame->getSlot(index);
- if (playerTemplate == slot->getPlayerTemplate())
- return;
-
- Int oldTemplate = slot->getPlayerTemplate();
- slot->setPlayerTemplate(playerTemplate);
-
- if (oldTemplate == PLAYERTEMPLATE_OBSERVER)
- {
- // was observer, so populate color & team with all, and enable
- GadgetComboBoxSetSelectedPos(comboBoxColor[index], 0);
- GadgetComboBoxSetSelectedPos(comboBoxTeam[index], 0);
- slot->setStartPos(-1);
- }
- else if (playerTemplate == PLAYERTEMPLATE_OBSERVER)
- {
- // is becoming observer, so populate color & team with random only, and disable
- GadgetComboBoxSetSelectedPos(comboBoxColor[index], 0);
- GadgetComboBoxSetSelectedPos(comboBoxTeam[index], 0);
- slot->setStartPos(-1);
- }
-
-
- if (TheGameSpyInfo->amIHost())
- {
- // send around a new slotlist
- myGame->resetAccepted();
- TheGameSpyInfo->setGameOptions();
- WOLDisplaySlotList();
- }
- else
- {
- // request the playerTemplate from the host
- AsciiString options;
- options.format("PlayerTemplate=%d", playerTemplate);
- AsciiString hostName;
- hostName.translate(myGame->getSlot(0)->getName());
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMPLAYER;
- req.UTM.isStagingRoom = TRUE;
- req.id = "REQ/";
- req.nick = hostName.str();
- req.options = options.str();
- TheGameSpyPeerMessageQueue->addRequest(req);
- }
- }
-}
-
-
-static void handleStartPositionSelection(Int player, int startPos)
-{
- GameSpyStagingRoom *myGame = TheGameSpyInfo->getCurrentStagingRoom();
-
- if (myGame)
- {
- GameSpyGameSlot * slot = myGame->getGameSpySlot(player);
- if (!slot)
- return;
-
- if (startPos == slot->getStartPos())
- return;
- Bool skip = FALSE;
- if (startPos < 0)
- {
- skip = TRUE;
- }
-
- if(!skip)
- {
- Bool isAvailable = TRUE;
- for(Int i = 0; i < MAX_SLOTS; ++i)
- {
- if(i != player && myGame->getSlot(i)->getStartPos() == startPos)
- {
- isAvailable = FALSE;
- break;
- }
- }
- if( !isAvailable )
- return;
- }
- slot->setStartPos(startPos);
-
- if (myGame->amIHost())
- {
- // send around a new slotlist
- myGame->resetAccepted();
- TheGameSpyInfo->setGameOptions();
- WOLDisplaySlotList();
- }
- else
- {
- // request the color from the host
- if (AreSlotListUpdatesEnabled())
- {
- // request the playerTemplate from the host
- AsciiString options;
- options.format("StartPos=%d", slot->getStartPos());
- AsciiString hostName;
- hostName.translate(myGame->getSlot(0)->getName());
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMPLAYER;
- req.UTM.isStagingRoom = TRUE;
- req.id = "REQ/";
- req.nick = hostName.str();
- req.options = options.str();
- TheGameSpyPeerMessageQueue->addRequest(req);
-
- }
- }
- }
-}
-
-
-
-static void handleTeamSelection(int index)
-{
- GameWindow *combo = comboBoxTeam[index];
- Int team, selIndex;
- GadgetComboBoxGetSelectedPos(combo, &selIndex);
- team = (Int)GadgetComboBoxGetItemData(combo, selIndex);
- GameInfo *myGame = TheGameSpyInfo->getCurrentStagingRoom();
-
- if (myGame)
- {
- GameSlot * slot = myGame->getSlot(index);
- if (team == slot->getTeamNumber())
- return;
-
- slot->setTeamNumber(team);
-
- if (TheGameSpyInfo->amIHost())
- {
- // send around a new slotlist
- myGame->resetAccepted();
- TheGameSpyInfo->setGameOptions();
- WOLDisplaySlotList();
- }
- else
- {
- // request the team from the host
- AsciiString options;
- options.format("Team=%d", team);
- AsciiString hostName;
- hostName.translate(myGame->getSlot(0)->getName());
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMPLAYER;
- req.UTM.isStagingRoom = TRUE;
- req.id = "REQ/";
- req.nick = hostName.str();
- req.options = options.str();
- TheGameSpyPeerMessageQueue->addRequest(req);
- }
- }
-}
-
-static void handleStartingCashSelection()
-{
- GameInfo *myGame = TheGameSpyInfo->getCurrentStagingRoom();
-
- if (myGame)
- {
- Int selIndex;
- GadgetComboBoxGetSelectedPos(comboBoxStartingCash, &selIndex);
-
- Money startingCash;
- startingCash.deposit( (UnsignedInt)GadgetComboBoxGetItemData( comboBoxStartingCash, selIndex ), FALSE );
- myGame->setStartingCash( startingCash );
- myGame->resetAccepted();
-
- if (myGame->amIHost())
- {
- // send around the new data
- TheGameSpyInfo->setGameOptions();
- WOLDisplaySlotList();// Update the accepted button UI
- }
- }
-}
-
-static void handleLimitSuperweaponsClick()
-{
- GameInfo *myGame = TheGameSpyInfo->getCurrentStagingRoom();
-
- if (myGame)
- {
- // At the moment, 1 and 0 are the only choices supported in the GUI, though the system could
- // support more.
- if ( GadgetCheckBoxIsChecked( checkBoxLimitSuperweapons ) )
- {
- myGame->setSuperweaponRestriction( 1 );
- }
- else
- {
- myGame->setSuperweaponRestriction( 0 );
- }
- myGame->resetAccepted();
-
- if (myGame->amIHost())
- {
- // send around a new slotlist
- TheGameSpyInfo->setGameOptions();
- WOLDisplaySlotList();// Update the accepted button UI
- }
- }
-}
-
-
-static void StartPressed(void)
-{
- Bool isReady = TRUE;
- Bool allHaveMap = TRUE;
- Int playerCount = 0;
- Int humanCount = 0;
- GameSpyStagingRoom *myGame = TheGameSpyInfo->getCurrentStagingRoom();
- if (!myGame)
- return;
-
- // see if everyone's accepted and count the number of players in the game
- UnicodeString mapDisplayName;
- const MapMetaData *mapData = TheMapCache->findMap( myGame->getMap() );
- Bool willTransfer = TRUE;
- if (mapData)
- {
- mapDisplayName.format(L"%ls", mapData->m_displayName.str());
- willTransfer = !mapData->m_isOfficial;
- }
- else
- {
- mapDisplayName.format(L"%hs", myGame->getMap().str());
- willTransfer = WouldMapTransfer(myGame->getMap());
- }
- for( int i = 0; i < MAX_SLOTS; i++ )
- {
- if ((myGame->getSlot(i)->isAccepted() == FALSE) && (myGame->getSlot(i)->isHuman() == TRUE))
- {
- isReady = FALSE;
- if (!myGame->getSlot(i)->hasMap() && !willTransfer)
- {
- UnicodeString msg;
- msg.format(TheGameText->fetch("GUI:PlayerNoMap"), myGame->getSlot(i)->getName().str(), mapDisplayName.str());
- TheGameSpyInfo->addText(msg, GameSpyColor[GSCOLOR_DEFAULT], listboxGameSetupChat);
- allHaveMap = FALSE;
- }
- }
- if(myGame->getSlot(i)->isOccupied() && myGame->getSlot(i)->getPlayerTemplate() != PLAYERTEMPLATE_OBSERVER)
- {
- if (myGame->getSlot(i)->isHuman())
- humanCount++;
- playerCount++;
- }
- }
-
- // Check for too many players
- const MapMetaData *md = TheMapCache->findMap( myGame->getMap() );
- if (!md || md->m_numPlayers < playerCount)
- {
- if (myGame->amIHost())
- {
- UnicodeString text;
- text.format(TheGameText->fetch("LAN:TooManyPlayers"), (md)?md->m_numPlayers:0);
- TheGameSpyInfo->addText(text, GameSpyColor[GSCOLOR_DEFAULT], listboxGameSetupChat);
- }
- return;
- }
-
- // Check for observer + AI players
- if (TheGlobalData->m_netMinPlayers && !humanCount)
- {
- if (myGame->amIHost())
- {
- UnicodeString text = TheGameText->fetch("GUI:NeedHumanPlayers");
- TheGameSpyInfo->addText(text, GameSpyColor[GSCOLOR_DEFAULT], listboxGameSetupChat);
- }
- return;
- }
-
- // Check for too few players
- if (playerCount < TheGlobalData->m_netMinPlayers)
- {
- if (myGame->amIHost())
- {
- UnicodeString text;
- text.format(TheGameText->fetch("LAN:NeedMorePlayers"),playerCount);
- TheGameSpyInfo->addText(text, GameSpyColor[GSCOLOR_DEFAULT], listboxGameSetupChat);
- }
- return;
- }
-
- // Check for too few teams
- int numRandom = 0;
- std::set teams;
- for (i=0; igetSlot(i);
- if (slot && slot->isOccupied() && slot->getPlayerTemplate() != PLAYERTEMPLATE_OBSERVER)
- {
- if (slot->getTeamNumber() >= 0)
- {
- teams.insert(slot->getTeamNumber());
- }
- else
- {
- ++numRandom;
- }
- }
- }
- if (numRandom + teams.size() < TheGlobalData->m_netMinPlayers)
- {
- if (myGame->amIHost())
- {
- UnicodeString text;
- text.format(TheGameText->fetch("LAN:NeedMoreTeams"));
- TheGameSpyInfo->addText(text, GameSpyColor[GSCOLOR_DEFAULT], listboxGameSetupChat);
- }
- return;
- }
-
- if (numRandom + teams.size() < 2)
- {
- UnicodeString text;
- text.format(TheGameText->fetch("GUI:SandboxMode"));
- TheGameSpyInfo->addText(text, GameSpyColor[GSCOLOR_DEFAULT], listboxGameSetupChat);
- }
-
- if(isReady)
- {
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_STARTGAME;
- TheGameSpyPeerMessageQueue->addRequest(req);
-
- SendStatsToOtherPlayers(myGame);
-
- // we've started, there's no going back
- // i.e. disable the back button.
- buttonBack->winEnable(FALSE);
- GameWindow *buttonBuddy = TheWindowManager->winGetWindowFromId(NULL, NAMEKEY("GameSpyGameOptionsMenu.wnd:ButtonCommunicator"));
- if (buttonBuddy)
- buttonBuddy->winEnable(FALSE);
- GameSpyCloseOverlay(GSOVERLAY_BUDDY);
-
- *TheGameSpyGame = *myGame;
- TheGameSpyGame->startGame(0);
- }
- else if (allHaveMap)
- {
- TheGameSpyInfo->addText(TheGameText->fetch("GUI:NotifiedStartIntent"), GameSpyColor[GSCOLOR_DEFAULT], listboxGameSetupChat);
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMROOM;
- req.UTM.isStagingRoom = TRUE;
- req.id = "HWS/";
- req.options = "true";
- TheGameSpyPeerMessageQueue->addRequest(req);
- }
-
-}//void StartPressed(void)
-
-//-------------------------------------------------------------------------------------------------
-/** Update options on screen */
-//-------------------------------------------------------------------------------------------------
-void WOLDisplayGameOptions( void )
-{
- GameSpyStagingRoom *theGame = TheGameSpyInfo->getCurrentStagingRoom();
- if (!parentWOLGameSetup || !theGame)
- return;
-
- const GameSlot *localSlot = NULL;
- if (theGame->getLocalSlotNum() >= 0)
- localSlot = theGame->getConstSlot(theGame->getLocalSlotNum());
-
- const MapMetaData *md = TheMapCache->findMap(TheGameSpyInfo->getCurrentStagingRoom()->getMap());
- if (md && localSlot && localSlot->hasMap())
- {
- GadgetStaticTextSetText(textEntryMapDisplay, md->m_displayName);
- }
- else
- {
- AsciiString s = TheGameSpyInfo->getCurrentStagingRoom()->getMap();
- if (s.reverseFind('\\'))
- {
- s = s.reverseFind('\\') + 1;
- }
- UnicodeString mapDisplay;
- mapDisplay.translate(s);
- GadgetStaticTextSetText(textEntryMapDisplay, mapDisplay);
- }
- WOLPositionStartSpots();
- updateMapStartSpots(TheGameSpyInfo->getCurrentStagingRoom(), buttonMapStartPosition);
-
- //If our display does not match the current state of game settings, update the checkbox.
- Bool isUsingStats = TheGameSpyInfo->getCurrentStagingRoom()->getUseStats() ? TRUE : FALSE;
- if (GadgetCheckBoxIsChecked(checkBoxUseStats) != isUsingStats)
- {
- GadgetCheckBoxSetChecked(checkBoxUseStats, isUsingStats);
- checkBoxUseStats->winSetTooltip( TheGameText->fetch( isUsingStats ? "TOOLTIP:UseStatsOn" : "TOOLTIP:UseStatsOff" ) );
- }
-
- Bool oldFactionsOnly = theGame->oldFactionsOnly();
- if (GadgetCheckBoxIsChecked(checkBoxLimitArmies) != oldFactionsOnly)
- {
- GadgetCheckBoxSetChecked(checkBoxLimitArmies, oldFactionsOnly);
- // Repopulate the lists of available armies, since the old list is now wrong
- for (Int i = 0; i < MAX_SLOTS; i++)
- {
- PopulatePlayerTemplateComboBox(i, comboBoxPlayerTemplate, theGame, theGame->getAllowObservers() );
-
- // Make sure selections are up to date on all machines
- handlePlayerTemplateSelection(i) ;
- }
- }
-
- // Note: must check if checkbox is already correct to avoid infinite recursion
- Bool limitSuperweapons = (theGame->getSuperweaponRestriction() != 0);
- if ( limitSuperweapons != GadgetCheckBoxIsChecked(checkBoxLimitSuperweapons))
- GadgetCheckBoxSetChecked( checkBoxLimitSuperweapons, limitSuperweapons );
-
- Int itemCount = GadgetComboBoxGetLength(comboBoxStartingCash);
- for ( Int index = 0; index < itemCount; index++ )
- {
- Int value = (Int)GadgetComboBoxGetItemData(comboBoxStartingCash, index);
- if ( value == theGame->getStartingCash().countMoney() )
- {
- // Note: must check if combobox is already correct to avoid infinite recursion
- Int selectedIndex;
- GadgetComboBoxGetSelectedPos( comboBoxStartingCash, &selectedIndex );
- if ( index != selectedIndex )
- GadgetComboBoxSetSelectedPos(comboBoxStartingCash, index, TRUE);
-
- break;
- }
- }
-
- DEBUG_ASSERTCRASH( index < itemCount, ("Could not find new starting cash amount %d in list", theGame->getStartingCash().countMoney() ) );
-}
-
-
-// -----------------------------------------------------------------------------------------
-// The Bad munkee slot list displaying function
-//-------------------------------------------------------------------------------------------------
-void WOLDisplaySlotList( void )
-{
- if (!parentWOLGameSetup || !TheGameSpyInfo->getCurrentStagingRoom())
- return;
-
- GameSpyStagingRoom *game = TheGameSpyInfo->getCurrentStagingRoom();
- if (!game->isInGame())
- return;
-
- DEBUG_ASSERTCRASH(!game->getConstSlot(0)->isOpen(), ("Open host!"));
-
- UpdateSlotList( game, comboBoxPlayer, comboBoxColor,
- comboBoxPlayerTemplate, comboBoxTeam, buttonAccept, buttonStart, buttonMapStartPosition );
-
- WOLDisplayGameOptions();
-
- for (Int i=0; igetGameSpySlot(i);
- if (slot && slot->isHuman())
- {
- if (i == game->getLocalSlotNum())
- {
- // set up my own ping...
- slot->setPingString(TheGameSpyInfo->getPingString());
- }
-
- if (genericPingWindow[i])
- {
- genericPingWindow[i]->winHide(FALSE);
- Int ping = slot->getPingAsInt();
- if (ping < TheGameSpyConfig->getPingCutoffGood())
- {
- genericPingWindow[i]->winSetEnabledImage(0, pingImages[0]);
- }
- else if (ping < TheGameSpyConfig->getPingCutoffBad())
- {
- genericPingWindow[i]->winSetEnabledImage(0, pingImages[1]);
- }
- else
- {
- genericPingWindow[i]->winSetEnabledImage(0, pingImages[2]);
- }
- }
- }
- else
- {
- if (genericPingWindow[i])
- genericPingWindow[i]->winHide(TRUE);
- }
- }
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the Gadgets Options Menu */
-//-------------------------------------------------------------------------------------------------
-void InitWOLGameGadgets( void )
-{
- GameSpyStagingRoom *theGameInfo = TheGameSpyInfo->getCurrentStagingRoom();
- pingImages[0] = TheMappedImageCollection->findImageByName("Ping03");
- pingImages[1] = TheMappedImageCollection->findImageByName("Ping02");
- pingImages[2] = TheMappedImageCollection->findImageByName("Ping01");
- DEBUG_ASSERTCRASH(pingImages[0], ("Can't find ping image!"));
- DEBUG_ASSERTCRASH(pingImages[1], ("Can't find ping image!"));
- DEBUG_ASSERTCRASH(pingImages[2], ("Can't find ping image!"));
-
- //Initialize the gadget IDs
- parentWOLGameSetupID = TheNameKeyGenerator->nameToKey( AsciiString( "GameSpyGameOptionsMenu.wnd:GameSpyGameOptionsMenuParent" ) );
- buttonBackID = TheNameKeyGenerator->nameToKey( AsciiString( "GameSpyGameOptionsMenu.wnd:ButtonBack" ) );
- buttonStartID = TheNameKeyGenerator->nameToKey( AsciiString( "GameSpyGameOptionsMenu.wnd:ButtonStart" ) );
- textEntryChatID = TheNameKeyGenerator->nameToKey( AsciiString( "GameSpyGameOptionsMenu.wnd:TextEntryChat" ) );
- textEntryMapDisplayID = TheNameKeyGenerator->nameToKey( AsciiString( "GameSpyGameOptionsMenu.wnd:TextEntryMapDisplay" ) );
- listboxGameSetupChatID = TheNameKeyGenerator->nameToKey( AsciiString( "GameSpyGameOptionsMenu.wnd:ListboxChatWindowGameSpyGameSetup" ) );
- buttonEmoteID = TheNameKeyGenerator->nameToKey( AsciiString( "GameSpyGameOptionsMenu.wnd:ButtonEmote" ) );
- buttonSelectMapID = TheNameKeyGenerator->nameToKey( AsciiString( "GameSpyGameOptionsMenu.wnd:ButtonSelectMap" ) );
- checkBoxUseStatsID = TheNameKeyGenerator->nameToKey( AsciiString( "GameSpyGameOptionsMenu.wnd:CheckBoxUseStats" ) );
- windowMapID = TheNameKeyGenerator->nameToKey( AsciiString( "GameSpyGameOptionsMenu.wnd:MapWindow" ) );
- checkBoxLimitSuperweaponsID = TheNameKeyGenerator->nameToKey(AsciiString("GameSpyGameOptionsMenu.wnd:CheckboxLimitSuperweapons"));
- comboBoxStartingCashID = TheNameKeyGenerator->nameToKey(AsciiString("GameSpyGameOptionsMenu.wnd:ComboBoxStartingCash"));
- checkBoxLimitArmiesID = TheNameKeyGenerator->nameToKey(AsciiString("GameSpyGameOptionsMenu.wnd:CheckBoxLimitArmies"));
- windowMapSelectMapID = TheNameKeyGenerator->nameToKey(AsciiString("WOLMapSelectMenu.wnd:WinMapPreview"));
-
- NameKeyType staticTextTitleID = NAMEKEY("GameSpyGameOptionsMenu.wnd:StaticTextGameName");
-
- // Initialize the pointers to our gadgets
- parentWOLGameSetup = TheWindowManager->winGetWindowFromId( NULL, parentWOLGameSetupID );
- buttonEmote = TheWindowManager->winGetWindowFromId( parentWOLGameSetup,buttonEmoteID );
- buttonSelectMap = TheWindowManager->winGetWindowFromId( parentWOLGameSetup,buttonSelectMapID );
- checkBoxUseStats = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, checkBoxUseStatsID );
- buttonStart = TheWindowManager->winGetWindowFromId( parentWOLGameSetup,buttonStartID );
- buttonBack = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, buttonBackID);
- listboxGameSetupChat = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, listboxGameSetupChatID );
- textEntryChat = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, textEntryChatID );
- textEntryMapDisplay = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, textEntryMapDisplayID );
- windowMap = TheWindowManager->winGetWindowFromId( parentWOLGameSetup,windowMapID );
- DEBUG_ASSERTCRASH(windowMap, ("Could not find the parentWOLGameSetup.wnd:MapWindow" ));
-
- checkBoxLimitSuperweapons = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, checkBoxLimitSuperweaponsID );
- DEBUG_ASSERTCRASH(windowMap, ("Could not find the GameSpyGameOptionsMenu.wnd:CheckboxLimitSuperweapons" ));
- comboBoxStartingCash = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, comboBoxStartingCashID );
- DEBUG_ASSERTCRASH(windowMap, ("Could not find the GameSpyGameOptionsMenu.wnd:ComboBoxStartingCash" ));
- PopulateStartingCashComboBox( comboBoxStartingCash, TheGameSpyGame );
- checkBoxLimitArmies = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, checkBoxLimitArmiesID );
- DEBUG_ASSERTCRASH(windowMap, ("Could not find the GameSpyGameOptionsMenu.wnd:CheckBoxLimitArmies" ));
-
- // Limit Armies can ONLY be set in the Host Game window (PopupHostGame.wnd)
- checkBoxLimitArmies->winEnable( false );
- // Ditto use stats
- checkBoxUseStats->winEnable( false );
- Int isUsingStats = TheGameSpyGame->getUseStats();
- GadgetCheckBoxSetChecked(checkBoxUseStats, isUsingStats );
- checkBoxUseStats->winSetTooltip( TheGameText->fetch( isUsingStats ? "TOOLTIP:UseStatsOn" : "TOOLTIP:UseStatsOff" ) );
-
- if ( !TheGameSpyGame->amIHost() )
- {
- checkBoxLimitSuperweapons->winEnable( false );
- comboBoxStartingCash->winEnable( false );
- NameKeyType labelID = TheNameKeyGenerator->nameToKey(AsciiString("GameSpyGameOptionsMenu.wnd:StartingCashLabel"));
- TheWindowManager->winGetWindowFromId(parentWOLGameSetup, labelID)->winEnable( FALSE );
- }
-
- if (isUsingStats)
- {
- // Recorded stats games can never limit superweapons, limit armies, or have inflated starting cash.
- // This should probably be enforced at the gamespy level as well, to prevent expoits.
- checkBoxLimitSuperweapons->winEnable( FALSE );
- comboBoxStartingCash->winEnable( FALSE );
- checkBoxLimitArmies->winEnable( FALSE );
- NameKeyType labelID = TheNameKeyGenerator->nameToKey(AsciiString("GameSpyGameOptionsMenu.wnd:StartingCashLabel"));
- TheWindowManager->winGetWindowFromId(parentWOLGameSetup, labelID)->winEnable( FALSE );
- }
-
- //Added By Sadullah Nader
- //Tooltip Function set
- windowMap->winSetTooltipFunc(MapSelectorTooltip);
- //
-
- GameWindow *staticTextTitle = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, staticTextTitleID );
- if (staticTextTitle)
- {
- GadgetStaticTextSetText(staticTextTitle, TheGameSpyGame->getGameName());
- }
-
- if (!theGameInfo)
- {
- DEBUG_CRASH(("No staging room!"));
- return;
- }
-
- for (Int i = 0; i < MAX_SLOTS; i++)
- {
- AsciiString tmpString;
- tmpString.format("GameSpyGameOptionsMenu.wnd:ComboBoxPlayer%d", i);
- comboBoxPlayerID[i] = TheNameKeyGenerator->nameToKey( tmpString );
- comboBoxPlayer[i] = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, comboBoxPlayerID[i] );
- GadgetComboBoxReset(comboBoxPlayer[i]);
- comboBoxPlayer[i]->winSetTooltipFunc(playerTooltip);
-
- tmpString.format("GameSpyGameOptionsMenu.wnd:StaticTextPlayer%d", i);
- staticTextPlayerID[i] = TheNameKeyGenerator->nameToKey( tmpString );
- staticTextPlayer[i] = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, staticTextPlayerID[i] );
- staticTextPlayer[i]->winSetTooltipFunc(playerTooltip);
- if (TheGameSpyInfo->amIHost())
- staticTextPlayer[i]->winHide(TRUE);
-
- if(i==0 && TheGameSpyInfo->amIHost())
- {
- UnicodeString uName;
- uName.translate(TheGameSpyInfo->getLocalName());
- GadgetComboBoxAddEntry(comboBoxPlayer[i],uName,GameSpyColor[GSCOLOR_PLAYER_OWNER]);
- GadgetComboBoxSetSelectedPos(comboBoxPlayer[0],0);
- }
- else
- {
- GadgetComboBoxAddEntry(comboBoxPlayer[i],TheGameText->fetch("GUI:Open"),GameSpyColor[GSCOLOR_PLAYER_NORMAL]);
- GadgetComboBoxAddEntry(comboBoxPlayer[i],TheGameText->fetch("GUI:Closed"),GameSpyColor[GSCOLOR_PLAYER_NORMAL]);
- GadgetComboBoxAddEntry(comboBoxPlayer[i],TheGameText->fetch("GUI:EasyAI"),GameSpyColor[GSCOLOR_PLAYER_NORMAL]);
- GadgetComboBoxAddEntry(comboBoxPlayer[i],TheGameText->fetch("GUI:MediumAI"),GameSpyColor[GSCOLOR_PLAYER_NORMAL]);
- GadgetComboBoxAddEntry(comboBoxPlayer[i],TheGameText->fetch("GUI:HardAI"),GameSpyColor[GSCOLOR_PLAYER_NORMAL]);
- GadgetComboBoxSetSelectedPos(comboBoxPlayer[i],0);
- }
-
- tmpString.format("GameSpyGameOptionsMenu.wnd:ComboBoxColor%d", i);
- comboBoxColorID[i] = TheNameKeyGenerator->nameToKey( tmpString );
- comboBoxColor[i] = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, comboBoxColorID[i] );
- DEBUG_ASSERTCRASH(comboBoxColor[i], ("Could not find the comboBoxColor[%d]",i ));
- PopulateColorComboBox(i, comboBoxColor, theGameInfo);
- GadgetComboBoxSetSelectedPos(comboBoxColor[i], 0);
-
- tmpString.format("GameSpyGameOptionsMenu.wnd:ComboBoxPlayerTemplate%d", i);
- comboBoxPlayerTemplateID[i] = TheNameKeyGenerator->nameToKey( tmpString );
- comboBoxPlayerTemplate[i] = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, comboBoxPlayerTemplateID[i] );
- DEBUG_ASSERTCRASH(comboBoxPlayerTemplate[i], ("Could not find the comboBoxPlayerTemplate[%d]",i ));
- PopulatePlayerTemplateComboBox(i, comboBoxPlayerTemplate, theGameInfo, theGameInfo->getAllowObservers() );
-
- // add tooltips to the player template combobox and listbox
- comboBoxPlayerTemplate[i]->winSetTooltipFunc(playerTemplateComboBoxTooltip);
- GadgetComboBoxGetListBox(comboBoxPlayerTemplate[i])->winSetTooltipFunc(playerTemplateListBoxTooltip);
-
- tmpString.format("GameSpyGameOptionsMenu.wnd:ComboBoxTeam%d", i);
- comboBoxTeamID[i] = TheNameKeyGenerator->nameToKey( tmpString );
- comboBoxTeam[i] = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, comboBoxTeamID[i] );
- DEBUG_ASSERTCRASH(comboBoxTeam[i], ("Could not find the comboBoxTeam[%d]",i ));
- PopulateTeamComboBox(i, comboBoxTeam, theGameInfo);
-
- tmpString.format("GameSpyGameOptionsMenu.wnd:ButtonAccept%d", i);
- buttonAcceptID[i] = TheNameKeyGenerator->nameToKey( tmpString );
- buttonAccept[i] = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, buttonAcceptID[i] );
- DEBUG_ASSERTCRASH(buttonAccept[i], ("Could not find the buttonAccept[%d]",i ));
- buttonAccept[i]->winSetTooltipFunc(gameAcceptTooltip);
-
- tmpString.format("GameSpyGameOptionsMenu.wnd:GenericPing%d", i);
- genericPingWindowID[i] = TheNameKeyGenerator->nameToKey( tmpString );
- genericPingWindow[i] = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, genericPingWindowID[i] );
- DEBUG_ASSERTCRASH(genericPingWindow[i], ("Could not find the genericPingWindow[%d]",i ));
- genericPingWindow[i]->winSetTooltipFunc(pingTooltip);
-
-// tmpString.format("GameSpyGameOptionsMenu.wnd:ButtonStartPosition%d", i);
-// buttonStartPositionID[i] = TheNameKeyGenerator->nameToKey( tmpString );
-// buttonStartPosition[i] = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, buttonStartPositionID[i] );
-// DEBUG_ASSERTCRASH(buttonStartPosition[i], ("Could not find the ButtonStartPosition[%d]",i ));
-
- tmpString.format("GameSpyGameOptionsMenu.wnd:ButtonMapStartPosition%d", i);
- buttonMapStartPositionID[i] = TheNameKeyGenerator->nameToKey( tmpString );
- buttonMapStartPosition[i] = TheWindowManager->winGetWindowFromId( parentWOLGameSetup, buttonMapStartPositionID[i] );
- DEBUG_ASSERTCRASH(buttonMapStartPosition[i], ("Could not find the ButtonMapStartPosition[%d]",i ));
-
-// if (buttonStartPosition[i])
-// buttonStartPosition[i]->winHide(TRUE);
-
- if(i !=0 && buttonAccept[i])
- buttonAccept[i]->winHide(TRUE);
- }
-
- if( buttonAccept[0] )
- buttonAccept[0]->winEnable(TRUE);
-
- if (buttonBack != NULL)
- {
- buttonBack->winEnable(TRUE);
- }
- //GadgetButtonSetEnabledColor(buttonAccept[0], GameSpyColor[GSCOLOR_ACCEPT_TRUE]);
-}
-
-void DeinitWOLGameGadgets( void )
-{
- parentWOLGameSetup = NULL;
- buttonEmote = NULL;
- buttonSelectMap = NULL;
- buttonStart = NULL;
- buttonBack = NULL;
- listboxGameSetupChat = NULL;
- textEntryChat = NULL;
- textEntryMapDisplay = NULL;
- windowMap = NULL;
- checkBoxUseStats = NULL;
- checkBoxLimitSuperweapons = NULL;
- comboBoxStartingCash = NULL;
-
-// GameWindow *staticTextTitle = NULL;
- for (Int i = 0; i < MAX_SLOTS; i++)
- {
- comboBoxPlayer[i] = NULL;
- staticTextPlayer[i] = NULL;
- comboBoxColor[i] = NULL;
- comboBoxPlayerTemplate[i] = NULL;
- comboBoxTeam[i] = NULL;
- buttonAccept[i] = NULL;
-// buttonStartPosition[i] = NULL;
- buttonMapStartPosition[i] = NULL;
- genericPingWindow[i] = NULL;
- }
-}
-
-static Bool initDone = false;
-UnsignedInt lastSlotlistTime = 0;
-UnsignedInt enterTime = 0;
-Bool initialAcceptEnable = FALSE;
-//-------------------------------------------------------------------------------------------------
-/** Initialize the Lan Game Options Menu */
-//-------------------------------------------------------------------------------------------------
-void WOLGameSetupMenuInit( WindowLayout *layout, void *userData )
-{
- if (TheGameSpyGame && TheGameSpyGame->isGameInProgress())
- {
- TheGameSpyGame->setGameInProgress(FALSE);
-
- // check if we were disconnected
- Int disconReason;
- if (TheGameSpyInfo->isDisconnectedAfterGameStart(&disconReason))
- {
- AsciiString disconMunkee;
- disconMunkee.format("GUI:GSDisconReason%d", disconReason);
- UnicodeString title, body;
- title = TheGameText->fetch( "GUI:GSErrorTitle" );
- body = TheGameText->fetch( disconMunkee );
- GameSpyCloseAllOverlays();
- GSMessageBoxOk( title, body );
- TheGameSpyInfo->reset();
- DEBUG_LOG(("WOLGameSetupMenuInit() - game was in progress, and we were disconnected, so pop immediate back to main menu\n"));
- TheShell->popImmediate();
- return;
- }
-
- // If we init while the game is in progress, we are really returning to the menu
- // after the game. So, we pop the menu and go back to the lobby. Whee!
- DEBUG_LOG(("WOLGameSetupMenuInit() - game was in progress, so pop immediate back to lobby\n"));
- TheShell->popImmediate();
- if (TheGameSpyPeerMessageQueue && TheGameSpyPeerMessageQueue->isConnected())
- {
- DEBUG_LOG(("We're still connected, so pushing back on the lobby\n"));
- TheShell->push("Menus/WOLCustomLobby.wnd", TRUE);
- }
- return;
- }
- TheGameSpyInfo->setCurrentGroupRoom(0);
-
- if (TheNAT != NULL) {
- delete TheNAT;
- TheNAT = NULL;
- }
-
- nextScreen = NULL;
- buttonPushed = false;
- isShuttingDown = false;
- launchGameNext = FALSE;
-
- //initialize the gadgets
- EnableSlotListUpdates(FALSE);
- InitWOLGameGadgets();
- EnableSlotListUpdates(TRUE);
- TheGameSpyInfo->registerTextWindow(listboxGameSetupChat);
-
- //The dialog needs to react differently depending on whether it's the host or not.
- TheMapCache->updateCache();
- GameSpyStagingRoom *game = TheGameSpyInfo->getCurrentStagingRoom();
- GameSpyGameSlot *hostSlot = game->getGameSpySlot(0);
- hostSlot->setAccept();
- if (TheGameSpyInfo->amIHost())
- {
- OptionPreferences natPref;
- CustomMatchPreferences customPref;
- hostSlot->setColor( customPref.getPreferredColor() );
- hostSlot->setPlayerTemplate( customPref.getPreferredFaction() );
- hostSlot->setNATBehavior((FirewallHelperClass::FirewallBehaviorType)natPref.getFirewallBehavior());
- hostSlot->setPingString(TheGameSpyInfo->getPingString());
- game->setMap(customPref.getPreferredMap());
-
- // Recorded stats games can never limit superweapons, limit armies, or have inflated starting cash.
- // This should probably be enforced at the gamespy level as well, to prevent expoits.
- Int isUsingStats = TheGameSpyGame->getUseStats();
- game->setStartingCash( isUsingStats? TheMultiplayerSettings->getDefaultStartingMoney() : customPref.getStartingCash() );
- game->setSuperweaponRestriction( isUsingStats? 0 : customPref.getSuperweaponRestricted() ? 1 : 0 );
- if (isUsingStats)
- game->setOldFactionsOnly( 0 );
-
- //game->setOldFactionsOnly( customPref.getFactionsLimited() );
- if ( game->oldFactionsOnly() )
- {
- // Make sure host follows the old factions only restrictions!
- const PlayerTemplate *fac = ThePlayerTemplateStore->getNthPlayerTemplate(hostSlot->getPlayerTemplate());
-
- if ( fac != NULL && !fac->isOldFaction() )
- {
- hostSlot->setPlayerTemplate( PLAYERTEMPLATE_RANDOM );
- }
- }
-
- for (Int i=1; igetGameSpySlot(i);
- slot->setState( SLOT_OPEN );
- }
-
- AsciiString lowerMap = customPref.getPreferredMap();
- lowerMap.toLower();
- std::map::iterator it = TheMapCache->find(lowerMap);
- if (it != TheMapCache->end())
- {
- hostSlot->setMapAvailability(TRUE);
- game->setMapCRC( it->second.m_CRC );
- game->setMapSize( it->second.m_filesize );
-
- game->adjustSlotsForMap(); // BGC- adjust the slots for the new map.
- }
-
-
- WOLDisplaySlotList();
- WOLDisplayGameOptions();
- }
- else
- {
- OptionPreferences natPref;
- CustomMatchPreferences customPref;
- AsciiString options;
- PeerRequest req;
- UnicodeString uName = hostSlot->getName();
- AsciiString aName;
- aName.translate(uName);
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMPLAYER;
- req.UTM.isStagingRoom = TRUE;
- req.id = "REQ/";
- req.nick = aName.str();
- options.format("PlayerTemplate=%d", customPref.getPreferredFaction());
- req.options = options.str();
- TheGameSpyPeerMessageQueue->addRequest(req);
- options.format("Color=%d", customPref.getPreferredColor());
- req.options = options.str();
- TheGameSpyPeerMessageQueue->addRequest(req);
- options.format("NAT=%d", natPref.getFirewallBehavior());
- req.options = options.str();
- TheGameSpyPeerMessageQueue->addRequest(req);
- options.format("Ping=%s", TheGameSpyInfo->getPingString().str());
- req.options = options.str();
- TheGameSpyPeerMessageQueue->addRequest(req);
-
- game->setMapCRC( game->getMapCRC() ); // force a recheck
- game->setMapSize( game->getMapSize() ); // of if we have the map
-
- for (Int i = 0; i < MAX_SLOTS; ++i)
- {
- //I'm a client, disable the controls I can't touch.
- comboBoxPlayer[i]->winEnable(FALSE);
-
- comboBoxColor[i]->winEnable(FALSE);
- comboBoxPlayerTemplate[i]->winEnable(FALSE);
- comboBoxTeam[i]->winEnable(FALSE);
-// buttonStartPosition[i]->winEnable(FALSE);
- buttonMapStartPosition[i]->winEnable(FALSE);
-
- }
- buttonStart->winSetText(TheGameText->fetch("GUI:Accept"));
- buttonStart->winEnable( FALSE );
- buttonSelectMap->winEnable( FALSE );
- checkBoxLimitSuperweapons->winEnable( FALSE ); // Can look but only host can touch
- comboBoxStartingCash->winEnable( FALSE ); // Ditto
- initialAcceptEnable = FALSE;
- }
-
- // Show the Menu
- layout->hide( FALSE );
-
- // Make sure the text fields are clear
- GadgetListBoxReset( listboxGameSetupChat );
- GadgetTextEntrySetText(textEntryChat, UnicodeString::TheEmptyString);
-
- initDone = true;
- TheGameSpyInfo->setGameOptions();
- //TheShell->registerWithAnimateManager(parentWOLGameSetup, WIN_ANIMATION_SLIDE_TOP, TRUE);
- WOLPositionStartSpots();
-
- lastSlotlistTime = 0;
- enterTime = timeGetTime();
-
- // Set Keyboard to chat entry
- TheWindowManager->winSetFocus( textEntryChat );
- raiseMessageBoxes = true;
- TheTransitionHandler->setGroup("GameSpyGameOptionsMenuFade");
-}// void WOLGameSetupMenuInit( WindowLayout *layout, void *userData )
-
-//-------------------------------------------------------------------------------------------------
-/** This is called when a shutdown is complete for this menu */
-//-------------------------------------------------------------------------------------------------
-static void shutdownComplete( WindowLayout *layout )
-{
-
- isShuttingDown = false;
-
- // hide the layout
- layout->hide( TRUE );
-
- // our shutdown is complete
- TheShell->shutdownComplete( layout, (nextScreen != NULL) );
-
- if (nextScreen != NULL)
- {
- if (!TheGameSpyPeerMessageQueue || !TheGameSpyPeerMessageQueue->isConnected())
- {
- DEBUG_LOG(("GameSetup shutdownComplete() - skipping push because we're disconnected\n"));
- }
- else
- {
- TheShell->push(nextScreen);
- }
- }
-
- /*
- if (launchGameNext)
- {
- TheGameSpyGame->launchGame();
- TheGameSpyInfo->leaveStagingRoom();
- }
- */
-
- nextScreen = NULL;
-
-} // end if
-
-//-------------------------------------------------------------------------------------------------
-/** GameSpy Game Options menu shutdown method */
-//-------------------------------------------------------------------------------------------------
-void WOLGameSetupMenuShutdown( WindowLayout *layout, void *userData )
-{
- TheGameSpyInfo->unregisterTextWindow(listboxGameSetupChat);
-
- if( WOLMapSelectLayout )
- {
- WOLMapSelectLayout->destroyWindows();
- WOLMapSelectLayout->deleteInstance();
- WOLMapSelectLayout = NULL;
- }
- parentWOLGameSetup = NULL;
- EnableSlotListUpdates(FALSE);
- DeinitWOLGameGadgets();
- if (TheEstablishConnectionsMenu != NULL)
- {
- TheEstablishConnectionsMenu->endMenu();
- }
- initDone = false;
-
- isShuttingDown = true;
-
- // if we are shutting down for an immediate pop, skip the animations
- Bool popImmediate = *(Bool *)userData;
- if( popImmediate )
- {
-
- shutdownComplete( layout );
- return;
-
- } //end if
-
- TheShell->reverseAnimatewindow();
-
- RaiseGSMessageBox();
- TheTransitionHandler->reverse("GameSpyGameOptionsMenuFade");
-} // void WOLGameSetupMenuShutdown( WindowLayout *layout, void *userData )
-
-static void fillPlayerInfo(const PeerResponse *resp, PlayerInfo *info)
-{
- info->m_name = resp->nick.c_str();
- info->m_profileID = resp->player.profileID;
- info->m_flags = resp->player.flags;
- info->m_wins = resp->player.wins;
- info->m_losses = resp->player.losses;
- info->m_locale = resp->locale.c_str();
- info->m_rankPoints= resp->player.rankPoints;
- info->m_side = resp->player.side;
- info->m_preorder = resp->player.preorder;
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Lan Game Options menu update method */
-//-------------------------------------------------------------------------------------------------
-void WOLGameSetupMenuUpdate( WindowLayout * layout, void *userData)
-{
- // We'll only be successful if we've requested to
- if(isShuttingDown && TheShell->isAnimFinished() && TheTransitionHandler->isFinished())
- {
- shutdownComplete(layout);
- return;
- }
-
- if (raiseMessageBoxes)
- {
- RaiseGSMessageBox();
- raiseMessageBoxes = false;
- }
-
- if (TheShell->isAnimFinished() && !buttonPushed && TheGameSpyPeerMessageQueue)
- {
- HandleBuddyResponses();
- HandlePersistentStorageResponses();
-
- if (TheGameSpyGame && TheGameSpyGame->isGameInProgress())
- {
- if (TheGameSpyInfo->isDisconnectedAfterGameStart(NULL))
- {
- return; // already been disconnected, so don't worry.
- }
-
- Int allowedMessages = TheGameSpyInfo->getMaxMessagesPerUpdate();
- Bool sawImportantMessage = FALSE;
- PeerResponse resp;
- while (allowedMessages-- && !sawImportantMessage && TheGameSpyPeerMessageQueue->getResponse( resp ))
- {
- switch (resp.peerResponseType)
- {
- case PeerResponse::PEERRESPONSE_DISCONNECT:
- {
- sawImportantMessage = TRUE;
- AsciiString disconMunkee;
- disconMunkee.format("GUI:GSDisconReason%d", resp.discon.reason);
-
- // check for scorescreen
- NameKeyType listboxChatWindowScoreScreenID = NAMEKEY("ScoreScreen.wnd:ListboxChatWindowScoreScreen");
- GameWindow *listboxChatWindowScoreScreen = TheWindowManager->winGetWindowFromId( NULL, listboxChatWindowScoreScreenID );
- if (listboxChatWindowScoreScreen)
- {
- GadgetListBoxAddEntryText(listboxChatWindowScoreScreen, TheGameText->fetch(disconMunkee),
- GameSpyColor[GSCOLOR_DEFAULT], -1);
- }
- else
- {
- // still ingame
- TheInGameUI->message(disconMunkee);
- }
- TheGameSpyInfo->markAsDisconnectedAfterGameStart(resp.discon.reason);
- }
- }
- }
-
- return; // if we're in game, all we care about is if we've been disconnected from the chat server
- }
-
- Bool isHosting = TheGameSpyInfo->amIHost(); // only while in game setup screen
- isHosting = isHosting || (TheGameSpyGame && TheGameSpyGame->isInGame() && TheGameSpyGame->amIHost()); // while in game
- if (!isHosting && !lastSlotlistTime && timeGetTime() > enterTime + 10000)
- {
- // don't do this if we're disconnected
- if (TheGameSpyPeerMessageQueue->isConnected())
- {
- // haven't seen ourselves
- buttonPushed = true;
- DEBUG_LOG(("Haven't seen ourselves in slotlist\n"));
- if (TheGameSpyGame)
- TheGameSpyGame->reset();
- TheGameSpyInfo->leaveStagingRoom();
- //TheGameSpyInfo->joinBestGroupRoom();
- GSMessageBoxOk(TheGameText->fetch("GUI:HostLeftTitle"), TheGameText->fetch("GUI:HostLeft"));
- nextScreen = "Menus/WOLCustomLobby.wnd";
- TheShell->pop();
- }
- return;
- }
-
- if (TheNAT != NULL) {
- NATStateType NATState = TheNAT->update();
- if (NATState == NATSTATE_DONE)
- {
- //launchGameNext = TRUE;
- //TheShell->pop();
- TheGameSpyGame->launchGame();
- if (TheGameSpyInfo) // this can be blown away by a disconnect on the map transfer screen
- TheGameSpyInfo->leaveStagingRoom();
- return;
- }
- else if (NATState == NATSTATE_FAILED)
- {
- // Just back out. This cleans up some slot list problems
- buttonPushed = true;
-
- // delete TheNAT, its no good for us anymore.
- delete TheNAT;
- TheNAT = NULL;
-
- TheGameSpyInfo->getCurrentStagingRoom()->reset();
- TheGameSpyInfo->leaveStagingRoom();
- //TheGameSpyInfo->joinBestGroupRoom();
- GSMessageBoxOk(TheGameText->fetch("GUI:Error"), TheGameText->fetch("GUI:NATNegotiationFailed"));
- nextScreen = "Menus/WOLCustomLobby.wnd";
- TheShell->pop();
- return;
- }
- }
-
- PeerResponse resp;
-
- Int allowedMessages = TheGameSpyInfo->getMaxMessagesPerUpdate();
- Bool sawImportantMessage = FALSE;
- while (allowedMessages-- && !sawImportantMessage)
- {
-
- if (!TheLobbyQueuedUTMs.empty())
- {
- DEBUG_LOG(("Got response from queued lobby UTM list\n"));
- resp = TheLobbyQueuedUTMs.front();
- TheLobbyQueuedUTMs.pop_front();
- }
- else if (TheGameSpyPeerMessageQueue->getResponse( resp ))
- {
- DEBUG_LOG(("Got response from message queue\n"));
- }
- else
- {
- break;
- }
- switch (resp.peerResponseType)
- {
- case PeerResponse::PEERRESPONSE_FAILEDTOHOST:
- {
- // oops - we've not heard from the qr server. bail.
- TheGameSpyInfo->addText(TheGameText->fetch("GUI:GSFailedToHost"), GameSpyColor[GSCOLOR_DEFAULT], NULL);
- }
- break;
- case PeerResponse::PEERRESPONSE_GAMESTART:
- {
- sawImportantMessage = TRUE;
- GameSpyStagingRoom *myGame = TheGameSpyInfo->getCurrentStagingRoom();
- if (!myGame || !myGame->isInGame())
- break;
-
- if (!TheGameSpyGame)
- break;
-
- SendStatsToOtherPlayers(TheGameSpyGame);
-
- // we've started, there's no going back
- // i.e. disable the back button.
- buttonBack->winEnable(FALSE);
- GameWindow *buttonBuddy = TheWindowManager->winGetWindowFromId(NULL, NAMEKEY("GameSpyGameOptionsMenu.wnd:ButtonCommunicator"));
- if (buttonBuddy)
- buttonBuddy->winEnable(FALSE);
- GameSpyCloseOverlay(GSOVERLAY_BUDDY);
-
- *TheGameSpyGame = *myGame;
- TheGameSpyGame->startGame(0);
- }
- break;
- case PeerResponse::PEERRESPONSE_PLAYERCHANGEDFLAGS:
- {
- PlayerInfo p;
- fillPlayerInfo(&resp, &p);
- TheGameSpyInfo->updatePlayerInfo(p);
- WOLDisplaySlotList();
- }
- break;
- case PeerResponse::PEERRESPONSE_PLAYERINFO:
- {
- PlayerInfo p;
- fillPlayerInfo(&resp, &p);
- TheGameSpyInfo->updatePlayerInfo(p);
- WOLDisplaySlotList();
- // send out new slotlist if I'm host
- TheGameSpyInfo->setGameOptions();
- }
- break;
- case PeerResponse::PEERRESPONSE_PLAYERJOIN:
- {
- if (resp.player.roomType != StagingRoom)
- {
- break;
- }
- sawImportantMessage = TRUE;
- PlayerInfo p;
- fillPlayerInfo(&resp, &p);
- TheGameSpyInfo->updatePlayerInfo(p);
-
- if (p.m_profileID)
- {
- if (TheGameSpyPSMessageQueue->findPlayerStatsByID(p.m_profileID).id == 0)
- {
- PSRequest req;
- req.requestType = PSRequest::PSREQUEST_READPLAYERSTATS;
- req.player.id = p.m_profileID;
- TheGameSpyPSMessageQueue->addRequest(req);
- }
- }
-
- // check if we have room for the dude
- GameInfo *game = TheGameSpyInfo->getCurrentStagingRoom();
- if (TheGameSpyInfo->amIHost() && game)
- {
- if (TheNAT)
- {
- // ditch him
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMPLAYER;
- req.UTM.isStagingRoom = TRUE;
- req.id = "KICK/";
- req.nick = p.m_name.str();
- req.options = "GameStarted";
- TheGameSpyPeerMessageQueue->addRequest(req);
- }
- else
- {
- // look for room for him
- // See if there's room
- // First get the number of players currently in the room.
- Int numPlayers = 0;
- for (Int player = 0; player < MAX_SLOTS; ++player)
- {
- if (game->getSlot(player)->isOccupied() &&
- game->getSlot(player)->getPlayerTemplate() != PLAYERTEMPLATE_OBSERVER)
- {
- ++numPlayers;
- }
- }
-
- // now get the number of starting spots on the map.
- Int numStartingSpots = MAX_SLOTS;
- const MapMetaData *md = TheMapCache->findMap(game->getMap());
- if (md != NULL)
- {
- numStartingSpots = md->m_numPlayers;
- }
-
- Int openSlotIndex = -1;
- for (Int i=0; igetConstSlot(i);
- if (slot && slot->isOpen())
- {
- openSlotIndex = i;
- break;
- }
- }
-
- if (openSlotIndex >= 0)
- {
- // add him
- GameSlot newSlot;
- UnicodeString uName;
- uName.translate(p.m_name);
- newSlot.setState(SLOT_PLAYER, uName);
- newSlot.setIP(ntohl(resp.player.IP));
- game->setSlot( openSlotIndex, newSlot );
- game->resetAccepted(); // BGC - need to unaccept everyone if someone joins the game.
- }
- else
- {
- // ditch him
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMPLAYER;
- req.UTM.isStagingRoom = TRUE;
- req.id = "KICK/";
- req.nick = p.m_name.str();
- req.options = "GameFull";
- TheGameSpyPeerMessageQueue->addRequest(req);
- }
-
- // send out new slotlist if I'm host
- TheGameSpyInfo->setGameOptions();
- }
- }
- WOLDisplaySlotList();
- }
- break;
-
- case PeerResponse::PEERRESPONSE_PLAYERLEFT:
- {
- sawImportantMessage = TRUE;
- PlayerInfo p;
- fillPlayerInfo(&resp, &p);
- TheGameSpyInfo->playerLeftGroupRoom(resp.nick.c_str());
-
- if (TheGameSpyGame && TheGameSpyGame->isGameInProgress())
- {
- break;
- }
-
- if (TheNAT == NULL) // don't update slot list if we're trying to start a game
- {
-
- GameInfo *game = TheGameSpyInfo->getCurrentStagingRoom();
- if (game && TheGameSpyInfo->amIHost())
- {
- Int idx = game->getSlotNum(resp.nick.c_str());
- if (idx >= 0)
- {
- game->getSlot(idx)->setState(SLOT_OPEN);
- game->resetAccepted(); // BGC - need to unaccept everyone if someone leaves the game.
- }
- }
-
- // send out new slotlist if I'm host
- TheGameSpyInfo->setGameOptions();
- WOLDisplaySlotList();
-
- if (game && !TheGameSpyInfo->amIHost())
- {
- Int idx = game->getSlotNum(resp.nick.c_str());
- if (idx == 0)
- {
- // host left
- buttonPushed = true;
- TheGameSpyInfo->getCurrentStagingRoom()->reset();
- TheGameSpyInfo->leaveStagingRoom();
- //TheGameSpyInfo->joinBestGroupRoom();
- GSMessageBoxOk(TheGameText->fetch("GUI:HostLeftTitle"), TheGameText->fetch("GUI:HostLeft"));
- nextScreen = "Menus/WOLCustomLobby.wnd";
- TheShell->pop();
- }
- }
-
- }
- }
- break;
-
- case PeerResponse::PEERRESPONSE_MESSAGE:
- {
- TheGameSpyInfo->addChat(resp.nick.c_str(), resp.message.profileID,
- UnicodeString(resp.text.c_str()), !resp.message.isPrivate, resp.message.isAction, listboxGameSetupChat);
- }
- break;
-
- case PeerResponse::PEERRESPONSE_DISCONNECT:
- {
- sawImportantMessage = TRUE;
- UnicodeString title, body;
- AsciiString disconMunkee;
- disconMunkee.format("GUI:GSDisconReason%d", resp.discon.reason);
- title = TheGameText->fetch( "GUI:GSErrorTitle" );
- body = TheGameText->fetch( disconMunkee );
- GameSpyCloseAllOverlays();
- GSMessageBoxOk( title, body );
- TheGameSpyInfo->reset();
- TheShell->pop();
- }
-
- case PeerResponse::PEERRESPONSE_ROOMUTM:
- {
- sawImportantMessage = TRUE;
-#if defined(_DEBUG) || defined(_INTERNAL)
- if (g_debugSlots)
- {
- DEBUG_LOG(("About to process a room UTM. Command is '%s', command options is '%s'\n",
- resp.command.c_str(), resp.commandOptions.c_str()));
- }
-#endif
- if (!strcmp(resp.command.c_str(), "SL"))
- {
- // slotlist
- GameSpyStagingRoom *game = TheGameSpyInfo->getCurrentStagingRoom();
- Bool isValidSlotList = game && game->getSlot(0) && game->getSlot(0)->isPlayer( resp.nick.c_str() ) && !TheGameSpyInfo->amIHost();
- if (!isValidSlotList)
- {
- SLOTLIST_DEBUG_LOG(("Not a valid slotlist\n"));
- if (!game)
- {
- SLOTLIST_DEBUG_LOG(("No game!\n"));
- }
- else
- {
- if (!game->getSlot(0))
- {
- SLOTLIST_DEBUG_LOG(("No slot 0!\n"));
- }
- else
- {
- if (TheGameSpyInfo->amIHost())
- {
- SLOTLIST_DEBUG_LOG(("I'm the host!\n"));
- }
- else
- {
- SLOTLIST_DEBUG_LOG(("Not from the host! isHuman:%d, name:'%ls', sender:'%s'\n",
- game->getSlot(0)->isHuman(), game->getSlot(0)->getName().str(),
- resp.nick.c_str()));
- }
- }
- }
- }
- else // isValidSlotList
- {
- Int oldLocalSlotNum = (game->isInGame()) ? game->getLocalSlotNum() : -1;
- Bool wasInGame = oldLocalSlotNum >= 0;
- AsciiString oldMap = game->getMap();
- UnsignedInt oldMapCRC, newMapCRC;
- oldMapCRC = game->getMapCRC();
-
- AsciiString options = resp.commandOptions.c_str();
- options.trim();
- UnsignedShort ports[MAX_SLOTS];
- UnsignedInt ips[MAX_SLOTS];
- Int i;
- for (i=0; igetConstSlot(i))
- {
- ips[i] = game->getConstSlot(i)->getIP();
- ports[i] = game->getConstSlot(i)->getPort();
- }
- else
- {
- ips[i] = 0;
- ports[i] = 0;
- }
- }
- Bool optionsOK = ParseAsciiStringToGameInfo(game, options.str());
- if (TheNAT)
- {
- for (i=0; igetSlot(i))
- {
-#ifdef DEBUG_LOGGING
- UnsignedShort newPort = game->getConstSlot(i)->getPort();
- UnsignedInt newIP = game->getConstSlot(i)->getIP();
- DEBUG_ASSERTLOG(newIP == ips[i], ("IP was different for player %d (%X --> %X)\n",
- i, ips[i], newIP));
- DEBUG_ASSERTLOG(newPort == ports[i], ("Port was different for player %d (%d --> %d)\n",
- i, ports[i], newPort));
-#endif
- game->getSlot(i)->setPort(ports[i]);
- game->getSlot(i)->setIP(ips[i]);
- }
- }
- }
- Int newLocalSlotNum = (game->isInGame()) ? game->getLocalSlotNum() : -1;
- Bool isInGame = newLocalSlotNum >= 0;
- if (!optionsOK)
- {
- SLOTLIST_DEBUG_LOG(("Options are bad! bailing!\n"));
- break;
- }
- else
- {
- SLOTLIST_DEBUG_LOG(("Options are good, local slot is %d\n", newLocalSlotNum));
- if (!isInGame)
- {
- SLOTLIST_DEBUG_LOG(("Not in game; players are:\n"));
- for (Int i=0; igetGameSpySlot(i);
- if (slot && slot->isHuman())
- {
- UnicodeString munkee;
- munkee.format(L"\t%d: %ls", i, slot->getName().str());
- SLOTLIST_DEBUG_LOG(("%ls\n", munkee.str()));
- }
- }
- }
- }
- WOLDisplaySlotList();
-
- // if I changed map availability, send it across
- newMapCRC = game->getMapCRC();
- if (isInGame)
- {
- lastSlotlistTime = timeGetTime();
- if ( (oldMapCRC ^ newMapCRC) || (!wasInGame && isInGame) )
- {
- // it changed. send it
- UnicodeString hostName = TheGameSpyInfo->getCurrentStagingRoom()->getSlot(0)->getName();
- AsciiString asciiName;
- asciiName.translate(hostName);
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMPLAYER;
- req.UTM.isStagingRoom = TRUE;
- req.id = "MAP";
- req.nick = asciiName.str();
- req.options = (game->getSlot(newLocalSlotNum)->hasMap())?"1":"0";
- TheGameSpyPeerMessageQueue->addRequest(req);
- if (!game->getSlot(newLocalSlotNum)->hasMap())
- {
- UnicodeString text;
- UnicodeString mapDisplayName;
- const MapMetaData *mapData = TheMapCache->findMap( game->getMap() );
- Bool willTransfer = TRUE;
- if (mapData)
- {
- mapDisplayName.format(L"%ls", mapData->m_displayName.str());
- willTransfer = !mapData->m_isOfficial;
- }
- else
- {
- mapDisplayName.format(L"%hs", TheGameState->getMapLeafName(game->getMap()).str());
- willTransfer = WouldMapTransfer(game->getMap());
- }
- if (willTransfer)
- text.format(TheGameText->fetch("GUI:LocalPlayerNoMapWillTransfer"), mapDisplayName.str());
- else
- text.format(TheGameText->fetch("GUI:LocalPlayerNoMap"), mapDisplayName.str());
- TheGameSpyInfo->addText(text, GameSpyColor[GSCOLOR_DEFAULT], listboxGameSetupChat);
- }
- }
- if (!initialAcceptEnable)
- {
- buttonStart->winEnable( TRUE );
- initialAcceptEnable = TRUE;
- }
- }
- else
- {
- if (lastSlotlistTime)
- {
- // can't see ourselves
- buttonPushed = true;
- DEBUG_LOG(("Can't see ourselves in slotlist %s\n", options.str()));
- TheGameSpyInfo->getCurrentStagingRoom()->reset();
- TheGameSpyInfo->leaveStagingRoom();
- //TheGameSpyInfo->joinBestGroupRoom();
- GSMessageBoxOk(TheGameText->fetch("GUI:GSErrorTitle"), TheGameText->fetch("GUI:GSKicked"));
- nextScreen = "Menus/WOLCustomLobby.wnd";
- TheShell->pop();
- }
- }
- }
- }
- else if (!strcmp(resp.command.c_str(), "HWS"))
- {
- // host wants to start
- GameInfo *game = TheGameSpyInfo->getCurrentStagingRoom();
- if (game && game->isInGame() && game->getSlot(0) && game->getSlot(0)->isPlayer( resp.nick.c_str() ))
- {
- Int slotNum = game->getLocalSlotNum();
- GameSlot *slot = game->getSlot(slotNum);
- if (slot && (slot->isAccepted() == false))
- {
- TheGameSpyInfo->addText(TheGameText->fetch("GUI:HostWantsToStart"), GameSpyColor[GSCOLOR_DEFAULT], listboxGameSetupChat);
- }
- }
- }
- else if (!stricmp(resp.command.c_str(), "NAT"))
- {
- if (TheNAT != NULL) {
- TheNAT->processGlobalMessage(-1, resp.commandOptions.c_str());
- }
- }
- else if (!stricmp(resp.command.c_str(), "Pings"))
- {
- if (!TheGameSpyInfo->amIHost())
- {
- AsciiString pings = resp.commandOptions.c_str();
- AsciiString token;
- for (Int i=0; igetCurrentStagingRoom()->getGameSpySlot(i);
- if (pings.nextToken(&token, ","))
- {
- token.trim();
- slot->setPingString(token);
- }
- else
- {
- slot->setPingString("");
- }
- }
- }
- }
- }
- break;
-
- case PeerResponse::PEERRESPONSE_PLAYERUTM:
- {
- sawImportantMessage = TRUE;
- if (!strcmp(resp.command.c_str(), "STATS"))
- {
- PSPlayerStats stats = TheGameSpyPSMessageQueue->parsePlayerKVPairs(resp.commandOptions.c_str());
- if (stats.id && (TheGameSpyPSMessageQueue->findPlayerStatsByID(stats.id).id == 0))
- TheGameSpyPSMessageQueue->trackPlayerStats(stats);
- break;
- }
- GameSpyStagingRoom *game = TheGameSpyInfo->getCurrentStagingRoom();
- if (game)
- {
- Int slotNum = game->getSlotNum(resp.nick.c_str());
- if ((slotNum >= 0) && (slotNum < MAX_SLOTS) && (!stricmp(resp.command.c_str(), "NAT"))) {
- // this is a command for NAT negotiations, pass if off to TheNAT
- if (TheNAT != NULL) {
- TheNAT->processGlobalMessage(slotNum, resp.commandOptions.c_str());
- }
- }
- if (slotNum == 0 && !TheGameSpyInfo->amIHost())
- {
- if (!strcmp(resp.command.c_str(), "KICK"))
- {
- // oops - we've been kicked. bail.
- buttonPushed = true;
- TheGameSpyInfo->getCurrentStagingRoom()->reset();
- TheGameSpyInfo->leaveStagingRoom();
- //TheGameSpyInfo->joinBestGroupRoom();
- UnicodeString message = TheGameText->fetch("GUI:GSKicked");
- AsciiString commandMessage = resp.commandOptions.c_str();
- commandMessage.trim();
- DEBUG_LOG(("We were kicked: reason was '%s'\n", resp.commandOptions.c_str()));
- if (commandMessage == "GameStarted")
- {
- message = TheGameText->fetch("GUI:GSKickedGameStarted");
- }
- else if (commandMessage == "GameFull")
- {
- message = TheGameText->fetch("GUI:GSKickedGameFull");
- }
- GSMessageBoxOk(TheGameText->fetch("GUI:GSErrorTitle"), message);
- nextScreen = "Menus/WOLCustomLobby.wnd";
- TheShell->pop();
- }
- }
- else if (slotNum > 0 && TheGameSpyInfo->amIHost())
- {
- if (!strcmp(resp.command.c_str(), "accept"))
- {
- game->getSlot(slotNum)->setAccept();
- TheGameSpyInfo->setGameOptions();
- WOLDisplaySlotList();
- }
- else if (!strcmp(resp.command.c_str(), "MAP"))
- {
- Bool hasMap = atoi(resp.commandOptions.c_str());
- game->getSlot(slotNum)->setMapAvailability(hasMap);
- if (!hasMap)
- {
- // tell the host the user doesn't have the map
- UnicodeString mapDisplayName;
- const MapMetaData *mapData = TheMapCache->findMap( game->getMap() );
- Bool willTransfer = TRUE;
- if (mapData)
- {
- mapDisplayName.format(L"%ls", mapData->m_displayName.str());
- willTransfer = !mapData->m_isOfficial;
- }
- else
- {
- mapDisplayName.format(L"%hs", game->getMap().str());
- willTransfer = WouldMapTransfer(game->getMap());
- }
- UnicodeString text;
- if (willTransfer)
- text.format(TheGameText->fetch("GUI:PlayerNoMapWillTransfer"), game->getSlot(slotNum)->getName().str(), mapDisplayName.str());
- else
- text.format(TheGameText->fetch("GUI:PlayerNoMap"), game->getSlot(slotNum)->getName().str(), mapDisplayName.str());
- TheGameSpyInfo->addText(text, GameSpyColor[GSCOLOR_DEFAULT], listboxGameSetupChat);
- }
- WOLDisplaySlotList();
- }
- else if (!strcmp(resp.command.c_str(), "REQ"))
- {
- AsciiString options = resp.commandOptions.c_str();
- options.trim();
-
- Bool change = false;
- Bool shouldUnaccept = false;
- AsciiString key;
- options.nextToken(&key, "=");
- Int val = atoi(options.str()+1);
- UnsignedInt uVal = atoi(options.str()+1);
- DEBUG_LOG(("GameOpt request: key=%s, val=%s from player %d\n", key.str(), options.str()+1, slotNum));
-
- GameSpyGameSlot *slot = game->getGameSpySlot(slotNum);
- if (!slot)
- break;
-
- if (key == "Color")
- {
- if (val >= -1 && val < TheMultiplayerSettings->getNumColors() && val != slot->getColor() && slot->getPlayerTemplate() != PLAYERTEMPLATE_OBSERVER)
- {
- Bool colorAvailable = TRUE;
- if(val != -1 )
- {
- for(Int i=0; i getSlot(i);
- if(val == checkSlot->getColor() && slot != checkSlot)
- {
- colorAvailable = FALSE;
- break;
- }
- }
- }
- if(colorAvailable)
- slot->setColor(val);
- change = true;
- }
- else
- {
- DEBUG_LOG(("Rejecting invalid color %d\n", val));
- }
- }
- else if (key == "PlayerTemplate")
- {
- if (val >= PLAYERTEMPLATE_MIN && val < ThePlayerTemplateStore->getPlayerTemplateCount() && val != slot->getPlayerTemplate())
- {
- // Validate for LimitArmies checkbox
- if ( game->oldFactionsOnly() )
- {
- const PlayerTemplate *fac = ThePlayerTemplateStore->getNthPlayerTemplate(val);
- if ( fac != NULL && !fac->isOldFaction())
- {
- val = PLAYERTEMPLATE_RANDOM;
- }
- }
-
- slot->setPlayerTemplate(val);
- if (val == PLAYERTEMPLATE_OBSERVER)
- {
- slot->setColor(-1);
- slot->setStartPos(-1);
- slot->setTeamNumber(-1);
- }
- change = true;
- shouldUnaccept = true;
- }
- else
- {
- DEBUG_LOG(("Rejecting invalid PlayerTemplate %d\n", val));
- }
- }
- else if (key == "StartPos")
- {
- if (val >= -1 && val < MAX_SLOTS && val != slot->getStartPos() && slot->getPlayerTemplate() != PLAYERTEMPLATE_OBSERVER)
- {
- Bool startPosAvailable = TRUE;
- if(val != -1)
- {
- for(Int i=0; i getSlot(i);
- if(val == checkSlot->getStartPos() && slot != checkSlot)
- {
- startPosAvailable = FALSE;
- break;
- }
- }
- }
- if(startPosAvailable)
- slot->setStartPos(val);
- change = true;
- shouldUnaccept = true;
- }
- else
- {
- DEBUG_LOG(("Rejecting invalid startPos %d\n", val));
- }
- }
- else if (key == "Team")
- {
- if (val >= -1 && val < MAX_SLOTS/2 && val != slot->getTeamNumber() && slot->getPlayerTemplate() != PLAYERTEMPLATE_OBSERVER)
- {
- slot->setTeamNumber(val);
- change = true;
- shouldUnaccept = true;
- }
- else
- {
- DEBUG_LOG(("Rejecting invalid team %d\n", val));
- }
- }
- else if (key == "IP")
- {
- if (uVal != slot->getIP())
- {
- DEBUG_LOG(("setting IP of player %ls from 0x%08x to be 0x%08x", slot->getName().str(), slot->getIP(), uVal));
- slot->setIP(uVal);
- change = true;
- shouldUnaccept = true;
- }
- else
- {
- DEBUG_LOG(("Rejecting invalid IP %d\n", uVal));
- }
- }
- else if (key == "NAT")
- {
- if ((val >= FirewallHelperClass::FIREWALL_MIN) &&
- (val <= FirewallHelperClass::FIREWALL_MAX))
- {
- slot->setNATBehavior((FirewallHelperClass::FirewallBehaviorType)val);
- DEBUG_LOG(("Setting NAT behavior to %d for player %d\n", val, slotNum));
- change = true;
- }
- else
- {
- DEBUG_LOG(("Rejecting invalid NAT behavior %d from player %d\n", val, slotNum));
- }
- }
- else if (key == "Ping")
- {
- slot->setPingString(options.str()+1);
- TheGameSpyInfo->setGameOptions();
- DEBUG_LOG(("Setting ping string to %s for player %d\n", options.str()+1, slotNum));
- }
-
- if (change)
- {
- if (shouldUnaccept)
- game->resetAccepted();
-
- TheGameSpyInfo->setGameOptions();
-
- WOLDisplaySlotList();
- DEBUG_LOG(("Slot value is color=%d, PlayerTemplate=%d, startPos=%d, team=%d, IP=0x%8.8X\n",
- slot->getColor(), slot->getPlayerTemplate(), slot->getStartPos(), slot->getTeamNumber(), slot->getIP()));
- DEBUG_LOG(("Slot list updated to %s\n", GameInfoToAsciiString(game).str()));
- }
- }
- }
- }
- }
- break;
-
- }
- }
-
-
- }
-}// void WOLGameSetupMenuUpdate( WindowLayout * layout, void *userData)
-
-//-------------------------------------------------------------------------------------------------
-/** Lan Game Options menu input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLGameSetupMenuInput( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- /*
- switch( msg )
- {
-
- //-------------------------------------------------------------------------------------------------
- case GWM_RIGHT_UP:
- {
- if (buttonPushed)
- break;
-
- GameWindow *control = (GameWindow *)mData1;
- NameKeyType controlID = (NameKeyType)control->winGetWindowId();
- DEBUG_LOG(("GWM_RIGHT_UP for control %d(%s)\n", controlID, TheNameKeyGenerator->keyToName(controlID).str()));
- break;
- }
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
- UnsignedByte key = mData1;
- UnsignedByte state = mData2;
- if (buttonPushed)
- break;
-
- switch( key )
- {
- // ----------------------------------------------------------------------------------------
- case KEY_ESC:
- {
- //
- // send a simulated selected event to the parent window of the
- // back/exit button
- //
- if( BitTest( state, KEY_STATE_UP ) )
- {
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)buttonBack, buttonBackID );
- } // end if
- // don't let key fall through anywhere else
- return MSG_HANDLED;
- } // end escape
- } // end switch( key )
- } // end char
- } // end switch( msg )
- */
- return MSG_IGNORED;
-}//WindowMsgHandledType WOLGameSetupMenuInput( GameWindow *window, UnsignedInt msg,
-
-
-// Slash commands -------------------------------------------------------------------------
-//extern "C" {
-//int getQR2HostingStatus(void);
-//}
-extern int isThreadHosting;
-
-Bool handleGameSetupSlashCommands(UnicodeString uText)
-{
- AsciiString message;
- message.translate(uText);
-
- if (message.getCharAt(0) != '/')
- {
- return FALSE; // not a slash command
- }
-
- AsciiString remainder = message.str() + 1;
- AsciiString token;
- remainder.nextToken(&token);
- token.toLower();
-
- if (token == "host")
- {
- UnicodeString s;
- s.format(L"Hosting qr2:%d thread:%d", 0, isThreadHosting);
- TheGameSpyInfo->addText(s, GameSpyColor[GSCOLOR_DEFAULT], NULL);
- return TRUE; // was a slash command
- }
- else if (token == "me" && uText.getLength()>4)
- {
- TheGameSpyInfo->sendChat(UnicodeString(uText.str()+4), TRUE, NULL);
- return TRUE; // was a slash command
- }
-#if defined(_DEBUG) || defined(_INTERNAL)
- else if (token == "slots")
- {
- g_debugSlots = !g_debugSlots;
- TheGameSpyInfo->addText(UnicodeString(L"Toggled SlotList debug"), GameSpyColor[GSCOLOR_DEFAULT], NULL);
- return TRUE; // was a slash command
- }
- else if (token == "discon")
- {
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_LOGOUT;
- TheGameSpyPeerMessageQueue->addRequest( req );
- return TRUE;
- }
-#endif // defined(_DEBUG) || defined(_INTERNAL)
-
- return FALSE; // not a slash command
-}
-
-static Int getNextSelectablePlayer(Int start)
-{
- GameSpyStagingRoom *game = TheGameSpyInfo->getCurrentStagingRoom();
- if (!game->amIHost())
- return -1;
- for (Int j=start; jgetGameSpySlot(j);
- if (slot && slot->getStartPos() == -1 &&
- ( (j==game->getLocalSlotNum() && game->getConstSlot(j)->getPlayerTemplate()!=PLAYERTEMPLATE_OBSERVER)
- || slot->isAI()))
- {
- return j;
- }
- }
- return -1;
-}
-
-static Int getFirstSelectablePlayer(const GameInfo *game)
-{
- const GameSlot *slot = game->getConstSlot(game->getLocalSlotNum());
- if (!game->amIHost() || slot && slot->getPlayerTemplate() != PLAYERTEMPLATE_OBSERVER)
- return game->getLocalSlotNum();
-
- for (Int i=0; igetConstSlot(i);
- if (slot && slot->isAI())
- return i;
- }
-
- return game->getLocalSlotNum();
-}
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Game Options menu window system callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLGameSetupMenuSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- UnicodeString txtInput;
- static buttonCommunicatorID = NAMEKEY_INVALID;
- switch( msg )
- {
- //-------------------------------------------------------------------------------------------------
- case GWM_CREATE:
- {
- buttonCommunicatorID = NAMEKEY("GameSpyGameOptionsMenu.wnd:ButtonCommunicator");
- break;
- } // case GWM_DESTROY:
- //-------------------------------------------------------------------------------------------------
- case GWM_DESTROY:
- {
- break;
- } // case GWM_DESTROY:
- //-------------------------------------------------------------------------------------------------
- case GWM_INPUT_FOCUS:
- {
- // if we're givin the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
-
- return MSG_HANDLED;
- }//case GWM_INPUT_FOCUS:
- //-------------------------------------------------------------------------------------------------
- case GCM_SELECTED:
- {
- if (!initDone)
- break;
- if (buttonPushed)
- break;
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- if ( controlID == comboBoxStartingCashID )
- {
- handleStartingCashSelection();
- }
- else
- {
- GameSpyStagingRoom *myGame = TheGameSpyInfo->getCurrentStagingRoom();
- for (Int i = 0; i < MAX_SLOTS; i++)
- {
- if (controlID == comboBoxColorID[i])
- {
- handleColorSelection(i);
- }
- else if (controlID == comboBoxPlayerTemplateID[i])
- {
- handlePlayerTemplateSelection(i);
- }
- else if (controlID == comboBoxTeamID[i])
- {
- handleTeamSelection(i);
- }
- else if( controlID == comboBoxPlayerID[i] && TheGameSpyInfo->amIHost() )
- {
- // We don't have anything that'll happen if we click on ourselves
- if(i == myGame->getLocalSlotNum())
- break;
- // Get
- Int pos = -1;
- GadgetComboBoxGetSelectedPos(comboBoxPlayer[i], &pos);
- if( pos != SLOT_PLAYER && pos >= 0)
- {
- if( myGame->getSlot(i)->getState() == SLOT_PLAYER )
- {
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMPLAYER;
- req.UTM.isStagingRoom = TRUE;
- AsciiString aName;
- aName.translate(myGame->getSlot(i)->getName());
- req.nick = aName.str();
- req.id = "KICK/";
- req.options = "true";
- TheGameSpyPeerMessageQueue->addRequest(req);
-
- UnicodeString name = myGame->getSlot(i)->getName();
- myGame->getSlot(i)->setState(SlotState(pos));
- myGame->resetAccepted();
- TheGameSpyInfo->setGameOptions();
- WOLDisplaySlotList();
- //TheLAN->OnPlayerLeave(name);
- }
- else if( myGame->getSlot(i)->getState() != pos )
- {
- Bool wasAI = (myGame->getSlot(i)->isAI());
- myGame->getSlot(i)->setState(SlotState(pos));
- Bool isAI = (myGame->getSlot(i)->isAI());
- myGame->resetAccepted();
- if (wasAI ^ isAI)
- PopulatePlayerTemplateComboBox(i, comboBoxPlayerTemplate, myGame, wasAI && myGame->getAllowObservers());
- TheGameSpyInfo->setGameOptions();
- WOLDisplaySlotList();
- }
- }
- break;
- }
- }
- }
- break;
- }// case GCM_SELECTED:
- //-------------------------------------------------------------------------------------------------
- case GBM_SELECTED:
- {
- if (buttonPushed)
- break;
-
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- static buttonCommunicatorID = NAMEKEY("GameSpyGameOptionsMenu.wnd:ButtonCommunicator");
- if ( controlID == buttonBackID )
- {
- savePlayerInfo();
- if( WOLMapSelectLayout )
- {
- WOLMapSelectLayout->destroyWindows();
- WOLMapSelectLayout->deleteInstance();
- WOLMapSelectLayout = NULL;
- }
-
- TheGameSpyInfo->getCurrentStagingRoom()->reset();
- //peerLeaveRoom(TheGameSpyChat->getPeer(), StagingRoom, NULL);
- TheGameSpyInfo->leaveStagingRoom();
- buttonPushed = true;
- nextScreen = "Menus/WOLCustomLobby.wnd";
- TheShell->pop();
-
- } //if ( controlID == buttonBack )
- else if ( controlID == buttonCommunicatorID )
- {
- GameSpyToggleOverlay( GSOVERLAY_BUDDY );
-
- }
- else if ( controlID == buttonEmoteID )
- {
- // read the user's input
- txtInput.set(GadgetTextEntryGetText( textEntryChat ));
- // Clear the text entry line
- GadgetTextEntrySetText(textEntryChat, UnicodeString::TheEmptyString);
- // Clean up the text (remove leading/trailing chars, etc)
- txtInput.trim();
- // Echo the user's input to the chat window
- if (!txtInput.isEmpty())
- TheGameSpyInfo->sendChat(txtInput, FALSE, NULL); // 'emote' button is now carriage-return
- } //if ( controlID == buttonEmote )
- else if ( controlID == buttonSelectMapID )
- {
- WOLMapSelectLayout = TheWindowManager->winCreateLayout( "Menus/WOLMapSelectMenu.wnd" );
- WOLMapSelectLayout->runInit();
- WOLMapSelectLayout->hide( FALSE );
- WOLMapSelectLayout->bringForward();
- }
- else if ( controlID == buttonStartID )
- {
- savePlayerInfo();
- if (TheGameSpyInfo->amIHost())
- {
- StartPressed();
- }
- else
- {
- //I'm the Client... send an accept message to the host.
- GameSlot *localSlot = TheGameSpyInfo->getCurrentStagingRoom()->getSlot(TheGameSpyInfo->getCurrentStagingRoom()->getLocalSlotNum());
- if (localSlot)
- {
- localSlot->setAccept();
- }
- UnicodeString hostName = TheGameSpyInfo->getCurrentStagingRoom()->getSlot(0)->getName();
- AsciiString asciiName;
- asciiName.translate(hostName);
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_UTMPLAYER;
- req.UTM.isStagingRoom = TRUE;
- req.id = "accept";
- req.nick = asciiName.str();
- req.options = "true";
- TheGameSpyPeerMessageQueue->addRequest(req);
- //peerSetReady( PEER, PEERTrue );
- WOLDisplaySlotList();
- }
- }
- else if ( controlID == checkBoxLimitSuperweaponsID )
- {
- handleLimitSuperweaponsClick();
- }
- else
- {
- for (Int i = 0; i < MAX_SLOTS; i++)
- {
- if (controlID == buttonMapStartPositionID[i])
- {
- GameSpyStagingRoom *game = TheGameSpyInfo->getCurrentStagingRoom();
- Int playerIdxInPos = -1;
- for (Int j=0; jgetGameSpySlot(j);
- if (slot && slot->getStartPos() == i)
- {
- playerIdxInPos = j;
- break;
- }
- }
- if (playerIdxInPos >= 0)
- {
- GameSpyGameSlot *slot = game->getGameSpySlot(playerIdxInPos);
- if (playerIdxInPos == game->getLocalSlotNum() || (game->amIHost() && slot && slot->isAI()))
- {
- // it's one of my type. Try to change it.
- Int nextPlayer = getNextSelectablePlayer(playerIdxInPos+1);
- handleStartPositionSelection(playerIdxInPos, -1);
- if (nextPlayer >= 0)
- {
- handleStartPositionSelection(nextPlayer, i);
- }
- }
- }
- else
- {
- // nobody in the slot - put us in
- Int nextPlayer = getNextSelectablePlayer(0);
- if (nextPlayer < 0)
- nextPlayer = getFirstSelectablePlayer(game);
- handleStartPositionSelection(nextPlayer, i);
- }
- }
- }
- }
-
-
- break;
- }// case GBM_SELECTED:
- //-------------------------------------------------------------------------------------------------
- case GBM_SELECTED_RIGHT:
- {
- if (buttonPushed)
- break;
-
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- for (Int i = 0; i < MAX_SLOTS; i++)
- {
- if (controlID == buttonMapStartPositionID[i])
- {
- GameSpyStagingRoom *game = TheGameSpyInfo->getCurrentStagingRoom();
- Int playerIdxInPos = -1;
- for (Int j=0; jgetGameSpySlot(j);
- if (slot && slot->getStartPos() == i)
- {
- playerIdxInPos = j;
- break;
- }
- }
- if (playerIdxInPos >= 0)
- {
- GameSpyGameSlot *slot = game->getGameSpySlot(playerIdxInPos);
- if (playerIdxInPos == game->getLocalSlotNum() || (game->amIHost() && slot && slot->isAI()))
- {
- // it's one of my type. Remove it.
- handleStartPositionSelection(playerIdxInPos, -1);
- }
- }
- }
- }
- break;
- }
-
- //-------------------------------------------------------------------------------------------------
- case GEM_EDIT_DONE:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- // Take the user's input and echo it into the chat window as well as
- // send it to the other clients on the lan
- if ( controlID == textEntryChatID )
- {
-
- // read the user's input
- txtInput.set(GadgetTextEntryGetText( textEntryChat ));
- // Clear the text entry line
- GadgetTextEntrySetText(textEntryChat, UnicodeString::TheEmptyString);
- // Clean up the text (remove leading/trailing chars, etc)
- txtInput.trim();
- // Echo the user's input to the chat window
- if (!txtInput.isEmpty())
- {
- if (!handleGameSetupSlashCommands(txtInput))
- {
- TheGameSpyInfo->sendChat(txtInput, false, NULL);
- }
- }
-
- }// if ( controlID == textEntryChatID )
- break;
- }
- //-------------------------------------------------------------------------------------------------
- default:
- return MSG_IGNORED;
- }//Switch
- return MSG_HANDLED;
-}//WindowMsgHandledType WOLGameSetupMenuSystem( GameWindow *window, UnsignedInt msg,
-
-
diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLadderScreen.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLadderScreen.cpp
deleted file mode 100644
index 95899d4850e..00000000000
--- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLadderScreen.cpp
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: ReplayMenu.cpp /////////////////////////////////////////////////////////////////////
-// Author: Chris The masta Huybregts, December 2001
-// Description: Replay Menus
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/GameEngine.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Shell.h"
-#include "GameClient/KeyDefs.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/MessageBox.h"
-
-// window ids -------------------------------------------------------------------------------------
-static NameKeyType parentWindowID = NAMEKEY_INVALID;
-static NameKeyType buttonBackID = NAMEKEY_INVALID;
-static NameKeyType windowLadderID = NAMEKEY_INVALID;
-
-
-// window pointers --------------------------------------------------------------------------------
-static GameWindow *parentWindow = NULL;
-static GameWindow *buttonBack = NULL;
-static GameWindow *windowLadder = NULL;
-
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the single player menu */
-//-------------------------------------------------------------------------------------------------
-void WOLLadderScreenInit( WindowLayout *layout, void *userData )
-{
- TheShell->showShellMap(TRUE);
-
- // get ids for our children controls
- parentWindowID = TheNameKeyGenerator->nameToKey( AsciiString("WOLLadderScreen.wnd:LadderParent") );
- buttonBackID = TheNameKeyGenerator->nameToKey( AsciiString("WOLLadderScreen.wnd:ButtonBack") );
- windowLadderID = TheNameKeyGenerator->nameToKey( AsciiString("WOLLadderScreen.wnd:WindowLadder") );
-
- parentWindow = TheWindowManager->winGetWindowFromId( NULL, parentWindowID );
- buttonBack = TheWindowManager->winGetWindowFromId( parentWindow, buttonBackID );
- windowLadder = TheWindowManager->winGetWindowFromId( parentWindow, windowLadderID );
-
- //Load the listbox shiznit
-// PopulateReplayFileListbox(listboxReplayFiles);
-
- // show menu
- layout->hide( FALSE );
-
- // set keyboard focus to main parent
- TheWindowManager->winSetFocus( parentWindow );
-
-} // end ReplayMenuInit
-
-//-------------------------------------------------------------------------------------------------
-/** single player menu shutdown method */
-//-------------------------------------------------------------------------------------------------
-void WOLLadderScreenShutdown( WindowLayout *layout, void *userData )
-{
-
- // hide menu
- layout->hide( TRUE );
-
- // our shutdown is complete
- TheShell->shutdownComplete( layout );
-
-} // end ReplayMenuShutdown
-
-//-------------------------------------------------------------------------------------------------
-/** single player menu update method */
-//-------------------------------------------------------------------------------------------------
-void WOLLadderScreenUpdate( WindowLayout *layout, void *userData )
-{
-
-} // end ReplayMenuUpdate
-
-//-------------------------------------------------------------------------------------------------
-/** Replay menu input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLLadderScreenInput( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
-
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
- UnsignedByte key = mData1;
- UnsignedByte state = mData2;
-
- switch( key )
- {
-
- // ----------------------------------------------------------------------------------------
- case KEY_ESC:
- {
-
- //
- // send a simulated selected event to the parent window of the
- // back/exit button
- //
- if( BitTest( state, KEY_STATE_UP ) )
- {
-
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)buttonBack, buttonBackID );
-
- } // end if
-
- // don't let key fall through anywhere else
- return MSG_HANDLED;
-
- } // end escape
-
- } // end switch( key )
-
- } // end char
-
- } // end switch( msg )
-
- return MSG_IGNORED;
-
-} // end ReplayMenuInput
-
-//-------------------------------------------------------------------------------------------------
-/** single player menu window system callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLLadderScreenSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
-
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CREATE:
- {
-
-
- break;
-
- } // end create
-
- //---------------------------------------------------------------------------------------------
- case GWM_DESTROY:
- {
-
- break;
-
- } // end case
-
- // --------------------------------------------------------------------------------------------
- case GWM_INPUT_FOCUS:
- {
-
- // if we're givin the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
-
- return MSG_HANDLED;
-
- } // end input
- //---------------------------------------------------------------------------------------------
- case GBM_SELECTED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if( controlID == buttonBackID )
- {
-
- // thou art directed to return to thy known solar system immediately!
- TheShell->pop();
-
- } // end else if
-
- break;
-
- } // end selected
-
- default:
- return MSG_IGNORED;
- } // end switch
-
- return MSG_HANDLED;
-} // end ReplayMenuSystem
-
diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLobbyMenu.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLobbyMenu.cpp
deleted file mode 100644
index 6d4fb2c52e4..00000000000
--- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLobbyMenu.cpp
+++ /dev/null
@@ -1,1876 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////////////
-// FILE: WOLLobbyMenu.cpp
-// Author: Chris Huybregts, November 2001
-// Description: WOL Lobby Menu
-///////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/GameEngine.h"
-#include "Common/GameState.h"
-#include "Common/MiniLog.h"
-#include "Common/MultiplayerSettings.h"
-#include "Common/PlayerTemplate.h"
-#include "Common/CustomMatchPreferences.h"
-#include "Common/Version.h"
-#include "GameClient/AnimateWindowManager.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/GameClient.h"
-#include "GameClient/Shell.h"
-#include "GameClient/ShellHooks.h"
-#include "GameClient/KeyDefs.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/GadgetComboBox.h"
-#include "GameClient/GadgetListBox.h"
-#include "GameClient/GadgetSlider.h"
-#include "GameClient/GadgetTextEntry.h"
-#include "GameClient/GameText.h"
-#include "GameClient/MessageBox.h"
-#include "GameClient/Mouse.h"
-#include "GameClient/Display.h"
-#include "GameNetwork/GameSpyOverlay.h"
-#include "GameClient/GameWindowTransitions.h"
-
-#include "GameLogic/GameLogic.h"
-
-#include "GameClient/LanguageFilter.h"
-#include "GameNetwork/GameSpy/BuddyDefs.h"
-#include "GameNetwork/GameSpy/GSConfig.h"
-#include "GameNetwork/GameSpy/LadderDefs.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpy/PeerThread.h"
-#include "GameNetwork/GameSpy/PersistentStorageDefs.h"
-#include "GameNetwork/GameSpy/PersistentStorageThread.h"
-#include "GameNetwork/GameSpy/LobbyUtils.h"
-#include "GameNetwork/RankPointValue.h"
-
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-void refreshGameList( Bool forceRefresh = FALSE );
-void refreshPlayerList( Bool forceRefresh = FALSE );
-
-#ifdef DEBUG_LOGGING
-#define PERF_TEST
-static LogClass s_perfLog("Perf.txt");
-#define PERF_LOG(x) s_perfLog.log x
-#else // DEBUG_LOGGING
-#define PERF_LOG(x) {}
-#endif // DEBUG_LOGGING
-
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-static Bool isShuttingDown = false;
-static Bool buttonPushed = false;
-static char *nextScreen = NULL;
-static Bool raiseMessageBoxes = false;
-static time_t gameListRefreshTime = 0;
-static const time_t gameListRefreshInterval = 10000;
-static time_t playerListRefreshTime = 0;
-static const time_t playerListRefreshInterval = 5000;
-
-void setUnignoreText( WindowLayout *layout, AsciiString nick, GPProfile id);
-static void doSliderTrack(GameWindow *control, Int val);
-Bool DontShowMainMenu = FALSE;
-enum { COLUMN_PLAYERNAME = 1 };
-
-// window ids ------------------------------------------------------------------------------
-static NameKeyType parentWOLLobbyID = NAMEKEY_INVALID;
-static NameKeyType buttonBackID = NAMEKEY_INVALID;
-static NameKeyType buttonHostID = NAMEKEY_INVALID;
-static NameKeyType buttonRefreshID = NAMEKEY_INVALID;
-static NameKeyType buttonJoinID = NAMEKEY_INVALID;
-static NameKeyType buttonBuddyID = NAMEKEY_INVALID;
-static NameKeyType buttonEmoteID = NAMEKEY_INVALID;
-static NameKeyType textEntryChatID = NAMEKEY_INVALID;
-static NameKeyType listboxLobbyPlayersID = NAMEKEY_INVALID;
-static NameKeyType listboxLobbyChatID = NAMEKEY_INVALID;
-static NameKeyType comboLobbyGroupRoomsID = NAMEKEY_INVALID;
-//static NameKeyType // sliderChatAdjustID = NAMEKEY_INVALID;
-
-// Window Pointers ------------------------------------------------------------------------
-static GameWindow *parentWOLLobby = NULL;
-static GameWindow *buttonBack = NULL;
-static GameWindow *buttonHost = NULL;
-static GameWindow *buttonRefresh = NULL;
-static GameWindow *buttonJoin = NULL;
-static GameWindow *buttonBuddy = NULL;
-static GameWindow *buttonEmote = NULL;
-static GameWindow *textEntryChat = NULL;
-static GameWindow *listboxLobbyPlayers = NULL;
-static GameWindow *listboxLobbyChat = NULL;
-static GameWindow *comboLobbyGroupRooms = NULL;
-static GameWindow *parent = NULL;
-
-static Int groupRoomToJoin = 0;
-static Int initialGadgetDelay = 2;
-static Bool justEntered = FALSE;
-
-#if defined(_INTERNAL) || defined(_DEBUG)
-Bool g_fakeCRC = FALSE;
-Bool g_debugSlots = FALSE;
-#endif
-
-std::list TheLobbyQueuedUTMs;
-
-// Slash commands -------------------------------------------------------------------------
-//extern "C" {
-//int getQR2HostingStatus(void);
-//}
-extern int isThreadHosting;
-
-Bool handleLobbySlashCommands(UnicodeString uText)
-{
- AsciiString message;
- message.translate(uText);
-
- if (message.getCharAt(0) != '/')
- {
- return FALSE; // not a slash command
- }
-
- AsciiString remainder = message.str() + 1;
- AsciiString token;
- remainder.nextToken(&token);
- token.toLower();
-
- if (token == "host")
- {
- UnicodeString s;
- s.format(L"Hosting qr2:%d thread:%d", 0, isThreadHosting);
- TheGameSpyInfo->addText(s, GameSpyColor[GSCOLOR_DEFAULT], NULL);
- return TRUE; // was a slash command
- }
- else if (token == "me" && uText.getLength()>4)
- {
- TheGameSpyInfo->sendChat(UnicodeString(uText.str()+4), TRUE, listboxLobbyPlayers);
- return TRUE; // was a slash command
- }
- else if (token == "refresh")
- {
- // Added 2/19/03 added the game refresh
- refreshGameList(TRUE);
- refreshPlayerList(TRUE);
- return TRUE; // was a slash command
- }
- /*
- if (token == "togglegamelist")
- {
- NameKeyType buttonID = NAMEKEY("WOLCustomLobby.wnd:ButtonGameListToggle");
- GameWindow *button = TheWindowManager->winGetWindowFromId(parent, buttonID);
- if (button)
- {
- button->winHide(!button->winIsHidden());
- }
- return TRUE; // was a slash command
- }
- else if (token == "adjustchat")
- {
- NameKeyType sliderID = NAMEKEY("WOLCustomLobby.wnd:SliderChatAdjust");
- GameWindow *slider = TheWindowManager->winGetWindowFromId(parent, sliderID);
- if (slider)
- {
- slider->winHide(!slider->winIsHidden());
- }
- return TRUE; // was a slash command
- }
- */
-#if defined(_INTERNAL) || defined(_DEBUG)
- else if (token == "fakecrc")
- {
- g_fakeCRC = !g_fakeCRC;
- TheGameSpyInfo->addText(UnicodeString(L"Toggled CRC fakery"), GameSpyColor[GSCOLOR_DEFAULT], NULL);
- return TRUE; // was a slash command
- }
- else if (token == "slots")
- {
- g_debugSlots = !g_debugSlots;
- TheGameSpyInfo->addText(UnicodeString(L"Toggled SlotList debug"), GameSpyColor[GSCOLOR_DEFAULT], NULL);
- return TRUE; // was a slash command
- }
-#endif
-
- return FALSE; // not a slash command
-}
-
-static Bool s_tryingToHostOrJoin = FALSE;
-void SetLobbyAttemptHostJoin(Bool start)
-{
- s_tryingToHostOrJoin = start;
-}
-
-// Tooltips -------------------------------------------------------------------------------
-
-static void playerTooltip(GameWindow *window,
- WinInstanceData *instData,
- UnsignedInt mouse)
-{
- Int x, y, row, col;
- x = LOLONGTOSHORT(mouse);
- y = HILONGTOSHORT(mouse);
-
- GadgetListBoxGetEntryBasedOnXY(window, x, y, row, col);
-
- if (row == -1 || col == -1)
- {
- TheMouse->setCursorTooltip( UnicodeString::TheEmptyString);//TheGameText->fetch("TOOLTIP:PlayersInLobby") );
- return;
- }
-
- UnicodeString uName = GadgetListBoxGetText(window, row, COLUMN_PLAYERNAME);
- AsciiString aName;
- aName.translate(uName);
-
- PlayerInfoMap::iterator it = TheGameSpyInfo->getPlayerInfoMap()->find(aName);
- PlayerInfo *info = &(it->second);
- Bool isLocalPlayer = (TheGameSpyInfo->getLocalName().compareNoCase(info->m_name) == 0);
-
- if (col == 0)
- {
- if (info->m_preorder)
- {
- TheMouse->setCursorTooltip( TheGameText->fetch("TOOLTIP:LobbyOfficersClub") );
- }
- else
- {
- TheMouse->setCursorTooltip( UnicodeString::TheEmptyString);
- }
- return;
- }
-
- AsciiString playerLocale = info->m_locale;
- AsciiString localeIdentifier;
- localeIdentifier.format("WOL:Locale%2.2d", atoi(playerLocale.str()));
- Int playerWins = info->m_wins;
- Int playerLosses = info->m_losses;
- UnicodeString playerInfo;
- playerInfo.format(TheGameText->fetch("TOOLTIP:PlayerInfo"), TheGameText->fetch(localeIdentifier).str(), playerWins, playerLosses);
-
- UnicodeString tooltip = UnicodeString::TheEmptyString;//TheGameText->fetch("TOOLTIP:PlayersInLobby");
- if (isLocalPlayer)
- {
- tooltip.format(TheGameText->fetch("TOOLTIP:LocalPlayer"), uName.str());
- }
- else
- {
- // not us
- if (TheGameSpyInfo->getBuddyMap()->find(info->m_profileID) != TheGameSpyInfo->getBuddyMap()->end())
- {
- // buddy
- tooltip.format(TheGameText->fetch("TOOLTIP:BuddyPlayer"), uName.str());
- }
- else
- {
- if (info->m_profileID)
- {
- // non-buddy profiled player
- tooltip.format(TheGameText->fetch("TOOLTIP:ProfiledPlayer"), uName.str());
- }
- else
- {
- // non-profiled player
- tooltip.format(TheGameText->fetch("TOOLTIP:GenericPlayer"), uName.str());
- }
- }
- }
-
- if (info->isIgnored())
- {
- tooltip.concat(TheGameText->fetch("TOOLTIP:IgnoredModifier"));
- }
-
- if (info->m_profileID)
- {
- tooltip.concat(playerInfo);
- }
-
- Int rank = 0;
- Int i = 0;
- while( info->m_rankPoints >= TheRankPointValues->m_ranks[i + 1])
- ++i;
- rank = i;
- AsciiString sideName = "GUI:RandomSide";
- if (info->m_side > 0)
- {
- const PlayerTemplate *fac = ThePlayerTemplateStore->getNthPlayerTemplate(info->m_side);
- if (fac)
- {
- sideName.format("SIDE:%s", fac->getSide().str());
- }
- }
- AsciiString rankName;
- rankName.format("GUI:GSRank%d", rank);
- UnicodeString tmp;
- tmp.format(L"\n%ls %ls", TheGameText->fetch(sideName).str(), TheGameText->fetch(rankName).str());
- tooltip.concat(tmp);
-
- TheMouse->setCursorTooltip( tooltip, -1, NULL, 1.5f ); // the text and width are the only params used. the others are the default values.
-}
-
-static void populateGroupRoomListbox(GameWindow *lb)
-{
- if (!lb)
- return;
-
- GadgetComboBoxReset(lb);
- Int indexToSelect = -1;
- GroupRoomMap::iterator iter;
-
- // now populate the combo box
- for (iter = TheGameSpyInfo->getGroupRoomList()->begin(); iter != TheGameSpyInfo->getGroupRoomList()->end(); ++iter)
- {
- GameSpyGroupRoom room = iter->second;
- if (room.m_groupID != TheGameSpyConfig->getQMChannel())
- {
- DEBUG_LOG(("populateGroupRoomListbox(): groupID %d\n", room.m_groupID));
- if (room.m_groupID == TheGameSpyInfo->getCurrentGroupRoom())
- {
- Int selected = GadgetComboBoxAddEntry(lb, room.m_translatedName, GameSpyColor[GSCOLOR_CURRENTROOM]);
- GadgetComboBoxSetItemData(lb, selected, (void *)(room.m_groupID));
- indexToSelect = selected;
- }
- else
- {
- Int selected = GadgetComboBoxAddEntry(lb, room.m_translatedName, GameSpyColor[GSCOLOR_ROOM]);
- GadgetComboBoxSetItemData(lb, selected, (void *)(room.m_groupID));
- }
- }
- else
- {
- DEBUG_LOG(("populateGroupRoomListbox(): skipping QM groupID %d\n", room.m_groupID));
- }
- }
-
- GadgetComboBoxSetSelectedPos(lb, indexToSelect);
-}
-
-static const char *rankNames[] = {
- "Private",
- "Corporal",
- "Sergeant",
- "Lieutenant",
- "Captain",
- "Major",
- "Colonel",
- "General",
- "Brigadier",
- "Commander",
-};
-
-const Image* LookupSmallRankImage(Int side, Int rankPoints)
-{
- if (rankPoints == 0)
- return NULL;
-
- Int rank = 0;
- Int i = 0;
- while( rankPoints >= TheRankPointValues->m_ranks[i + 1])
- ++i;
- rank = i;
-
- if (rank < 0 || rank >= 10)
- return NULL;
-
- AsciiString sideStr = "N";
- switch(side)
- {
- case 2: //USA
- case 5: //Super Weapon
- case 6: //Laser
- case 7: //Air Force
- sideStr = "USA";
- break;
-
- case 3: //China
- case 8: //Tank
- case 9: //Infantry
- case 10: //Nuke
- sideStr = "CHA";
- break;
-
- case 4: //GLA
- case 11: //Toxin
- case 12: //Demolition
- case 13: //Stealth
- sideStr = "GLA";
- break;
- }
-
- AsciiString fullImageName;
- fullImageName.format("%s-%s", rankNames[rank], sideStr.str());
- const Image *img = TheMappedImageCollection->findImageByName(fullImageName);
- DEBUG_ASSERTLOG(img, ("*** Could not load small rank image '%s' from TheMappedImageCollection!\n", fullImageName.str()));
- return img;
-}
-
-static Int insertPlayerInListbox(const PlayerInfo& info, Color color)
-{
- UnicodeString uStr;
- uStr.translate(info.m_name);
-
- Int currentRank = info.m_rankPoints;
- Int currentSide = info.m_side;
- /* since PersistentStorage updates now update PlayerInfo, we don't need this.
- if (info.m_profileID)
- {
- PSPlayerStats psStats = TheGameSpyPSMessageQueue->findPlayerStatsByID(info.m_profileID);
- if (psStats.id)
- {
- currentRank = CalculateRank(psStats);
-
- PerGeneralMap::iterator it;
- Int numGames = 0;
- for(it = psStats.games.begin(); it != psStats.games.end(); ++it)
- {
- if(it->second >= numGames)
- {
- numGames = it->second;
- currentSide = it->first;
- }
- }
- if(numGames == 0 || psStats.gamesAsRandom >= numGames )
- {
- currentSide = 0;
- }
- }
- }
- */
-
- Bool isPreorder = TheGameSpyInfo->didPlayerPreorder(info.m_profileID);
-
- const Image *preorderImg = TheMappedImageCollection->findImageByName("OfficersClubsmall");
- Int w = (preorderImg)?preorderImg->getImageWidth():10;
- //Int h = (preorderImg)?preorderImg->getImageHeight():10;
- w = min(GadgetListBoxGetColumnWidth(listboxLobbyPlayers, 0), w);
- Int h = w;
- if (!isPreorder)
- preorderImg = NULL;
-
- const Image *rankImg = LookupSmallRankImage(currentSide, currentRank);
-
-#if 0 //Officer's Club (preorder image) no longer used in Zero Hour
- Int index = GadgetListBoxAddEntryImage(listboxLobbyPlayers, preorderImg, -1, 0, w, h);
- GadgetListBoxAddEntryImage(listboxLobbyPlayers, rankImg, index, 1, w, h);
- GadgetListBoxAddEntryText(listboxLobbyPlayers, uStr, color, index, 2);
-#else
- Int index = GadgetListBoxAddEntryImage(listboxLobbyPlayers, rankImg, -1, 0, w, h);
- GadgetListBoxAddEntryText(listboxLobbyPlayers, uStr, color, index, 1);
-#endif
- return index;
-}
-
-
-void PopulateLobbyPlayerListbox(void)
-{
-
- if (!listboxLobbyPlayers)
- return;
-
- // Display players
- PlayerInfoMap *players = TheGameSpyInfo->getPlayerInfoMap();
- PlayerInfoMap::iterator it;
- BuddyInfoMap *buddies = TheGameSpyInfo->getBuddyMap();
- BuddyInfoMap::iterator bIt;
- if (listboxLobbyPlayers)
- {
- // save off old selection
- Int maxSelectedItems = GadgetListBoxGetNumEntries(listboxLobbyPlayers);
- Int *selectedIndices;
- GadgetListBoxGetSelected(listboxLobbyPlayers, (Int *)(&selectedIndices));
- std::set selectedNames;
- std::set::const_iterator selIt;
- std::set indicesToSelect;
- UnicodeString uStr;
- Int numSelected = 0;
- for (Int i=0; ibegin(); it != players->end(); ++it)
- {
- PlayerInfo info = it->second;
- if (info.m_flags & PEER_FLAG_OP || TheGameSpyConfig->isPlayerVIP(info.m_profileID))
- {
- Int index = insertPlayerInListbox(info, info.isIgnored()?GameSpyColor[GSCOLOR_PLAYER_IGNORED]:GameSpyColor[GSCOLOR_PLAYER_OWNER]);
-
- selIt = selectedNames.find(info.m_name);
- if (selIt != selectedNames.end())
- {
- DEBUG_LOG(("Marking index %d (%s) to re-select\n", index, info.m_name.str()));
- indicesToSelect.insert(index);
- }
- }
- }
-
- // Buddies
- for (it = players->begin(); it != players->end(); ++it)
- {
- PlayerInfo info = it->second;
- bIt = buddies->find(info.m_profileID);
- if ( !(info.m_flags & PEER_FLAG_OP || TheGameSpyConfig->isPlayerVIP(info.m_profileID)) && bIt != buddies->end() )
- {
- Int index = insertPlayerInListbox(info, info.isIgnored()?GameSpyColor[GSCOLOR_PLAYER_IGNORED]:GameSpyColor[GSCOLOR_PLAYER_BUDDY]);
-
- selIt = selectedNames.find(info.m_name);
- if (selIt != selectedNames.end())
- {
- DEBUG_LOG(("Marking index %d (%s) to re-select\n", index, info.m_name.str()));
- indicesToSelect.insert(index);
- }
- }
- }
-
- // Everyone else
- for (it = players->begin(); it != players->end(); ++it)
- {
- PlayerInfo info = it->second;
- bIt = buddies->find(info.m_profileID);
- if ( !(info.m_flags & PEER_FLAG_OP || TheGameSpyConfig->isPlayerVIP(info.m_profileID)) && bIt == buddies->end() )
- {
- Int index = insertPlayerInListbox(info, info.isIgnored()?GameSpyColor[GSCOLOR_PLAYER_IGNORED]:GameSpyColor[GSCOLOR_PLAYER_NORMAL]);
-
- selIt = selectedNames.find(info.m_name);
- if (selIt != selectedNames.end())
- {
- DEBUG_LOG(("Marking index %d (%s) to re-select\n", index, info.m_name.str()));
- indicesToSelect.insert(index);
- }
- }
- }
-
- // restore selection
- if (indicesToSelect.size())
- {
- std::set::const_iterator indexIt;
- Int *newIndices = NEW Int[indicesToSelect.size()];
- for (i=0, indexIt = indicesToSelect.begin(); indexIt != indicesToSelect.end(); ++i, ++indexIt)
- {
- newIndices[i] = *indexIt;
- DEBUG_LOG(("Queueing up index %d to re-select\n", *indexIt));
- }
- GadgetListBoxSetSelected(listboxLobbyPlayers, newIndices, indicesToSelect.size());
- delete[] newIndices;
- }
-
- if (indicesToSelect.size() != numSelected)
- {
- TheWindowManager->winSetLoneWindow(NULL);
- }
-
- // restore top visible entry
- GadgetListBoxSetTopVisibleEntry(listboxLobbyPlayers, previousTopIndex);
- }
-
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the WOL Lobby Menu */
-//-------------------------------------------------------------------------------------------------
-void WOLLobbyMenuInit( WindowLayout *layout, void *userData )
-{
- nextScreen = NULL;
- buttonPushed = false;
- isShuttingDown = false;
-
- SetLobbyAttemptHostJoin(FALSE); // not trying to host or join
-
- gameListRefreshTime = 0;
- playerListRefreshTime = 0;
-
- parentWOLLobbyID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLCustomLobby.wnd:WOLLobbyMenuParent" ) );
- parent = TheWindowManager->winGetWindowFromId(NULL, parentWOLLobbyID);
-
- buttonBackID = TheNameKeyGenerator->nameToKey(AsciiString("WOLCustomLobby.wnd:ButtonBack"));
- buttonBack = TheWindowManager->winGetWindowFromId(parent, buttonBackID);
-
- buttonHostID = TheNameKeyGenerator->nameToKey(AsciiString("WOLCustomLobby.wnd:ButtonHost"));
- buttonHost = TheWindowManager->winGetWindowFromId(parent, buttonHostID);
-
- buttonRefreshID = TheNameKeyGenerator->nameToKey(AsciiString("WOLCustomLobby.wnd:ButtonRefresh"));
- buttonRefresh = TheWindowManager->winGetWindowFromId(parent, buttonRefreshID);
-
- buttonJoinID = TheNameKeyGenerator->nameToKey(AsciiString("WOLCustomLobby.wnd:ButtonJoin"));
- buttonJoin = TheWindowManager->winGetWindowFromId(parent, buttonJoinID);
- buttonJoin->winEnable(FALSE);
-
- buttonBuddyID = TheNameKeyGenerator->nameToKey(AsciiString("WOLCustomLobby.wnd:ButtonBuddy"));
- buttonBuddy = TheWindowManager->winGetWindowFromId(parent, buttonBuddyID);
-
- buttonEmoteID = TheNameKeyGenerator->nameToKey(AsciiString("WOLCustomLobby.wnd:ButtonEmote"));
- buttonEmote = TheWindowManager->winGetWindowFromId(parent, buttonEmoteID);
-
- textEntryChatID = TheNameKeyGenerator->nameToKey(AsciiString("WOLCustomLobby.wnd:TextEntryChat"));
- textEntryChat = TheWindowManager->winGetWindowFromId(parent, textEntryChatID);
-
- listboxLobbyPlayersID = TheNameKeyGenerator->nameToKey(AsciiString("WOLCustomLobby.wnd:ListboxPlayers"));
- listboxLobbyPlayers = TheWindowManager->winGetWindowFromId(parent, listboxLobbyPlayersID);
- listboxLobbyPlayers->winSetTooltipFunc(playerTooltip);
-
- listboxLobbyChatID = TheNameKeyGenerator->nameToKey(AsciiString("WOLCustomLobby.wnd:ListboxChat"));
- listboxLobbyChat = TheWindowManager->winGetWindowFromId(parent, listboxLobbyChatID);
- TheGameSpyInfo->registerTextWindow(listboxLobbyChat);
-
- comboLobbyGroupRoomsID = TheNameKeyGenerator->nameToKey(AsciiString("WOLCustomLobby.wnd:ComboBoxGroupRooms"));
- comboLobbyGroupRooms = TheWindowManager->winGetWindowFromId(parent, comboLobbyGroupRoomsID);
-
- GadgetTextEntrySetText(textEntryChat, UnicodeString.TheEmptyString);
-
- populateGroupRoomListbox(comboLobbyGroupRooms);
-
- // Show Menu
- layout->hide( FALSE );
-
- // if we're not in a room, this will join the best available one
- if (!TheGameSpyInfo->getCurrentGroupRoom())
- {
- if (groupRoomToJoin)
- {
- DEBUG_LOG(("WOLLobbyMenuInit() - rejoining group room %d\n", groupRoomToJoin));
- TheGameSpyInfo->joinGroupRoom(groupRoomToJoin);
- groupRoomToJoin = 0;
- }
- else
- {
- DEBUG_LOG(("WOLLobbyMenuInit() - joining best group room\n"));
- TheGameSpyInfo->joinBestGroupRoom();
- }
- }
- else
- {
- DEBUG_LOG(("WOLLobbyMenuInit() - not joining group room because we're already in one\n"));
- }
-
- GrabWindowInfo();
-
- TheGameSpyInfo->clearStagingRoomList();
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_STARTGAMELIST;
- req.gameList.restrictGameList = TheGameSpyConfig->restrictGamesToLobby();
- TheGameSpyPeerMessageQueue->addRequest(req);
-
- // animate controls
-// TheShell->registerWithAnimateManager(parent, WIN_ANIMATION_SLIDE_TOP, TRUE);
- TheShell->showShellMap(TRUE);
- TheGameSpyGame->reset();
-
- CustomMatchPreferences pref;
-// GameWindow *slider = TheWindowManager->winGetWindowFromId(parent, sliderChatAdjustID);
-// if (slider)
-// {
-// GadgetSliderSetPosition(slider, pref.getChatSizeSlider());
-// doSliderTrack(slider, pref.getChatSizeSlider());
-// }
-//
- if (pref.usesLongGameList())
- {
- ToggleGameListType();
- }
-
- // Set Keyboard to chat window
- TheWindowManager->winSetFocus( textEntryChat );
- raiseMessageBoxes = true;
-
- TheLobbyQueuedUTMs.clear();
- justEntered = TRUE;
- initialGadgetDelay = 2;
- GameWindow *win = TheWindowManager->winGetWindowFromId(NULL, TheNameKeyGenerator->nameToKey("WOLCustomLobby.wnd:GadgetParent"));
- if(win)
- win->winHide(TRUE);
- DontShowMainMenu = TRUE;
-
-} // WOLLobbyMenuInit
-
-//-------------------------------------------------------------------------------------------------
-/** This is called when a shutdown is complete for this menu */
-//-------------------------------------------------------------------------------------------------
-static void shutdownComplete( WindowLayout *layout )
-{
-
- isShuttingDown = false;
-
- // hide the layout
- layout->hide( TRUE );
-
- // our shutdown is complete
- TheShell->shutdownComplete( layout, (nextScreen != NULL) );
-
- if (nextScreen != NULL)
- {
- TheShell->push(nextScreen);
- }
-
- nextScreen = NULL;
-
-} // end if
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Lobby Menu shutdown method */
-//-------------------------------------------------------------------------------------------------
-void WOLLobbyMenuShutdown( WindowLayout *layout, void *userData )
-{
- CustomMatchPreferences pref;
-// GameWindow *slider = TheWindowManager->winGetWindowFromId(parent, sliderChatAdjustID);
-// if (slider)
-// {
-// pref.setChatSizeSlider(GadgetSliderGetPosition(slider));
-// }
- if (GetGameInfoListBox())
- {
- pref.setUsesLongGameList(FALSE);
- }
- else
- {
- pref.setUsesLongGameList(TRUE);
- }
- pref.write();
-
- ReleaseWindowInfo();
-
- TheGameSpyInfo->unregisterTextWindow(listboxLobbyChat);
-
- //TheGameSpyChat->stopListingGames();
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_STOPGAMELIST;
- TheGameSpyPeerMessageQueue->addRequest(req);
-
- listboxLobbyChat = NULL;
- listboxLobbyPlayers = NULL;
-
- isShuttingDown = true;
-
- // if we are shutting down for an immediate pop, skip the animations
- Bool popImmediate = *(Bool *)userData;
- if( popImmediate )
- {
-
- shutdownComplete( layout );
- return;
-
- } //end if
-
- TheShell->reverseAnimatewindow();
- DontShowMainMenu = FALSE;
-
- RaiseGSMessageBox();
- TheTransitionHandler->reverse("WOLCustomLobbyFade");
-
-} // WOLLobbyMenuShutdown
-
-static void fillPlayerInfo(const PeerResponse *resp, PlayerInfo *info)
-{
- info->m_name = resp->nick.c_str();
- info->m_profileID = resp->player.profileID;
- info->m_flags = resp->player.flags;
- info->m_wins = resp->player.wins;
- info->m_losses = resp->player.losses;
- info->m_locale = resp->locale.c_str();
- info->m_rankPoints= resp->player.rankPoints;
- info->m_side = resp->player.side;
- info->m_preorder = resp->player.preorder;
-}
-
-#ifdef PERF_TEST
-static const char* getMessageString(Int t)
-{
- switch(t)
- {
- case PeerResponse::PEERRESPONSE_LOGIN:
- return "login";
- case PeerResponse::PEERRESPONSE_DISCONNECT:
- return "disconnect";
- case PeerResponse::PEERRESPONSE_MESSAGE:
- return "message";
- case PeerResponse::PEERRESPONSE_GROUPROOM:
- return "group room";
- case PeerResponse::PEERRESPONSE_STAGINGROOM:
- return "staging room";
- case PeerResponse::PEERRESPONSE_STAGINGROOMPLAYERINFO:
- return "staging room player info";
- case PeerResponse::PEERRESPONSE_JOINGROUPROOM:
- return "group room join";
- case PeerResponse::PEERRESPONSE_CREATESTAGINGROOM:
- return "staging room create";
- case PeerResponse::PEERRESPONSE_JOINSTAGINGROOM:
- return "staging room join";
- case PeerResponse::PEERRESPONSE_PLAYERJOIN:
- return "player join";
- case PeerResponse::PEERRESPONSE_PLAYERLEFT:
- return "player part";
- case PeerResponse::PEERRESPONSE_PLAYERCHANGEDNICK:
- return "player nick";
- case PeerResponse::PEERRESPONSE_PLAYERINFO:
- return "player info";
- case PeerResponse::PEERRESPONSE_PLAYERCHANGEDFLAGS:
- return "player flags";
- case PeerResponse::PEERRESPONSE_ROOMUTM:
- return "room UTM";
- case PeerResponse::PEERRESPONSE_PLAYERUTM:
- return "player UTM";
- case PeerResponse::PEERRESPONSE_QUICKMATCHSTATUS:
- return "QM status";
- case PeerResponse::PEERRESPONSE_GAMESTART:
- return "game start";
- case PeerResponse::PEERRESPONSE_FAILEDTOHOST:
- return "host failure";
- }
- return "unknown";
-}
-#endif // PERF_TEST
-
-//-------------------------------------------------------------------------------------------------
-/** refreshGameList
- The Bool is used to force refresh if the refresh button was hit.*/
-//-------------------------------------------------------------------------------------------------
-static void refreshGameList( Bool forceRefresh )
-{
- Int refreshInterval = gameListRefreshInterval;
-
- if (forceRefresh || ((gameListRefreshTime == 0) || ((gameListRefreshTime + refreshInterval) <= timeGetTime())))
- {
- if (TheGameSpyInfo->hasStagingRoomListChanged())
- {
- //DEBUG_LOG(("################### refreshing game list\n"));
- //DEBUG_LOG(("gameRefreshTime=%d, refreshInterval=%d, now=%d\n", gameListRefreshTime, refreshInterval, timeGetTime()));
- RefreshGameListBoxes();
- gameListRefreshTime = timeGetTime();
- } else {
- //DEBUG_LOG(("-"));
- }
- } else {
- //DEBUG_LOG(("gameListRefreshTime: %d refreshInterval: %d\n"));
- }
-}
-//-------------------------------------------------------------------------------------------------
-/** refreshPlayerList
- The Bool is used to force refresh if the refresh button was hit.*/
-//-------------------------------------------------------------------------------------------------
-static void refreshPlayerList( Bool forceRefresh )
-{
- Int refreshInterval = playerListRefreshInterval;
-
- if (forceRefresh ||((playerListRefreshTime == 0) || ((playerListRefreshTime + refreshInterval) <= timeGetTime())))
- {
- PopulateLobbyPlayerListbox();
- playerListRefreshTime = timeGetTime();
- }
-}
-//-------------------------------------------------------------------------------------------------
-/** WOL Lobby Menu update method */
-//-------------------------------------------------------------------------------------------------
-void WOLLobbyMenuUpdate( WindowLayout * layout, void *userData)
-{
- if(justEntered)
- {
- if(initialGadgetDelay == 1)
- {
- TheTransitionHandler->remove("MainMenuDefaultMenuLogoFade");
- TheTransitionHandler->setGroup("WOLCustomLobbyFade");
- initialGadgetDelay = 2;
- justEntered = FALSE;
- }
- else
- initialGadgetDelay--;
- }
- if (TheGameLogic->isInShellGame() && TheGameLogic->getFrame() == 1)
- {
- SignalUIInteraction(SHELL_SCRIPT_HOOK_GENERALS_ONLINE_ENTERED_FROM_GAME);
- }
-
-
- // We'll only be successful if we've requested to
- if(isShuttingDown && TheShell->isAnimFinished() && TheTransitionHandler->isFinished())
- shutdownComplete(layout);
-
- if (raiseMessageBoxes)
- {
- RaiseGSMessageBox();
- raiseMessageBoxes = false;
- }
-
- if (TheShell->isAnimFinished() && TheTransitionHandler->isFinished() && !buttonPushed && TheGameSpyPeerMessageQueue)
- {
- HandleBuddyResponses();
- HandlePersistentStorageResponses();
-
-#ifdef PERF_TEST
- UnsignedInt start = timeGetTime();
- UnsignedInt end = timeGetTime();
- std::list responses;
- Int numMessages = 0;
-#endif // PERF_TEST
-
- Int allowedMessages = TheGameSpyInfo->getMaxMessagesPerUpdate();
- Bool sawImportantMessage = FALSE;
- Bool shouldRepopulatePlayers = FALSE;
- PeerResponse resp;
- while (allowedMessages-- && !sawImportantMessage && TheGameSpyPeerMessageQueue->getResponse( resp ))
- {
-#ifdef PERF_TEST
- ++numMessages;
- responses.push_back(resp.peerResponseType);
-#endif // PERF_TEST
- switch (resp.peerResponseType)
- {
- case PeerResponse::PEERRESPONSE_JOINGROUPROOM:
- sawImportantMessage = TRUE;
- if (resp.joinGroupRoom.ok)
- {
- //buttonPushed = true;
- TheGameSpyInfo->setCurrentGroupRoom(resp.joinGroupRoom.id);
- TheGameSpyInfo->getPlayerInfoMap()->clear();
- GroupRoomMap::iterator iter = TheGameSpyInfo->getGroupRoomList()->find(resp.joinGroupRoom.id);
- if (iter != TheGameSpyInfo->getGroupRoomList()->end())
- {
- GameSpyGroupRoom room = iter->second;
- UnicodeString msg;
- msg.format(TheGameText->fetch("GUI:LobbyJoined"), room.m_translatedName.str());
- TheGameSpyInfo->addText(msg, GameSpyColor[GSCOLOR_DEFAULT], NULL);
- }
- }
- else
- {
- DEBUG_LOG(("WOLLobbyMenuUpdate() - joining best group room\n"));
- TheGameSpyInfo->joinBestGroupRoom();
- }
- populateGroupRoomListbox(comboLobbyGroupRooms);
- shouldRepopulatePlayers = TRUE;
- break;
- case PeerResponse::PEERRESPONSE_PLAYERCHANGEDFLAGS:
- {
- PlayerInfo p;
- fillPlayerInfo(&resp, &p);
- TheGameSpyInfo->updatePlayerInfo(p);
- shouldRepopulatePlayers = TRUE;
- }
- break;
- case PeerResponse::PEERRESPONSE_PLAYERCHANGEDNICK:
- {
- PlayerInfo p;
- fillPlayerInfo(&resp, &p);
- TheGameSpyInfo->updatePlayerInfo(p);
- shouldRepopulatePlayers = TRUE;
- }
- break;
- case PeerResponse::PEERRESPONSE_PLAYERINFO:
- {
- PlayerInfo p;
- fillPlayerInfo(&resp, &p);
- TheGameSpyInfo->updatePlayerInfo(p);
- shouldRepopulatePlayers = TRUE;
- }
- break;
- case PeerResponse::PEERRESPONSE_PLAYERJOIN:
- {
- if (resp.player.roomType == GroupRoom)
- {
- PlayerInfo p;
- fillPlayerInfo(&resp, &p);
- TheGameSpyInfo->updatePlayerInfo(p);
- shouldRepopulatePlayers = TRUE;
- }
- }
- break;
- case PeerResponse::PEERRESPONSE_PLAYERUTM:
- case PeerResponse::PEERRESPONSE_ROOMUTM:
- {
- DEBUG_LOG(("Putting off a UTM in the lobby\n"));
- TheLobbyQueuedUTMs.push_back(resp);
- }
- break;
- case PeerResponse::PEERRESPONSE_PLAYERLEFT:
- {
- PlayerInfo p;
- fillPlayerInfo(&resp, &p);
- TheGameSpyInfo->playerLeftGroupRoom(resp.nick.c_str());
- shouldRepopulatePlayers = TRUE;
- }
- break;
- case PeerResponse::PEERRESPONSE_MESSAGE:
- {
- TheGameSpyInfo->addChat(resp.nick.c_str(), resp.message.profileID,
- UnicodeString(resp.text.c_str()), !resp.message.isPrivate, resp.message.isAction, listboxLobbyChat);
- }
- break;
- case PeerResponse::PEERRESPONSE_DISCONNECT:
- {
- sawImportantMessage = TRUE;
- UnicodeString title, body;
- AsciiString disconMunkee;
- disconMunkee.format("GUI:GSDisconReason%d", resp.discon.reason);
- title = TheGameText->fetch( "GUI:GSErrorTitle" );
- body = TheGameText->fetch( disconMunkee );
- GameSpyCloseAllOverlays();
- GSMessageBoxOk( title, body );
- TheGameSpyInfo->reset();
- TheShell->pop();
- }
- case PeerResponse::PEERRESPONSE_CREATESTAGINGROOM:
- {
- sawImportantMessage = TRUE;
- SetLobbyAttemptHostJoin(FALSE);
- if (resp.createStagingRoom.result == PEERJoinSuccess)
- {
- // Woohoo! On to our next screen!
- buttonPushed = true;
- nextScreen = "Menus/GameSpyGameOptionsMenu.wnd";
- TheShell->pop();
- TheGameSpyInfo->markAsStagingRoomHost();
- TheGameSpyInfo->setGameOptions();
- }
- }
- break;
- case PeerResponse::PEERRESPONSE_JOINSTAGINGROOM:
- {
- sawImportantMessage = TRUE;
- SetLobbyAttemptHostJoin(FALSE);
- Bool isHostPresent = TRUE;
- if (resp.joinStagingRoom.ok == PEERTrue)
- {
- GameSpyStagingRoom *room = TheGameSpyInfo->getCurrentStagingRoom();
- if (!room)
- {
- isHostPresent = FALSE;
- }
- else
- {
- isHostPresent = FALSE;
- for (Int i=0; igetConstSlot(0)->getName());
- const char *firstPlayer = resp.stagingRoomPlayerNames[i].c_str();
- if (!strcmp(hostName.str(), firstPlayer))
- {
- DEBUG_LOG(("Saw host %s == %s in slot %d\n", hostName.str(), firstPlayer, i));
- isHostPresent = TRUE;
- }
- }
- }
- }
- if (resp.joinStagingRoom.ok == PEERTrue && isHostPresent)
- {
- // Woohoo! On to our next screen!
- buttonPushed = true;
- nextScreen = "Menus/GameSpyGameOptionsMenu.wnd";
- TheShell->pop();
- }
- else
- {
- UnicodeString s;
-
- switch(resp.joinStagingRoom.result)
- {
- case PEERFullRoom: // The room is full.
- s = TheGameText->fetch("GUI:JoinFailedRoomFull");
- break;
- case PEERInviteOnlyRoom: // The room is invite only.
- s = TheGameText->fetch("GUI:JoinFailedInviteOnly");
- break;
- case PEERBannedFromRoom: // The local user is banned from the room.
- s = TheGameText->fetch("GUI:JoinFailedBannedFromRoom");
- break;
- case PEERBadPassword: // An incorrect password (or none) was given for a passworded room.
- s = TheGameText->fetch("GUI:JoinFailedBadPassword");
- break;
- case PEERAlreadyInRoom: // The local user is already in or entering a room of the same type.
- s = TheGameText->fetch("GUI:JoinFailedAlreadyInRoom");
- break;
- case PEERNoConnection: // Can't join a room if there's no chat connection.
- s = TheGameText->fetch("GUI:JoinFailedNoConnection");
- break;
- default:
- s = TheGameText->fetch("GUI:JoinFailedDefault");
- break;
- }
- GSMessageBoxOk(TheGameText->fetch("GUI:JoinFailedDefault"), s);
- if (groupRoomToJoin)
- {
- DEBUG_LOG(("WOLLobbyMenuUpdate() - rejoining group room %d\n", groupRoomToJoin));
- TheGameSpyInfo->joinGroupRoom(groupRoomToJoin);
- groupRoomToJoin = 0;
- }
- else
- {
- DEBUG_LOG(("WOLLobbyMenuUpdate() - joining best group room\n"));
- TheGameSpyInfo->joinBestGroupRoom();
- }
- }
- }
- break;
- case PeerResponse::PEERRESPONSE_STAGINGROOMLISTCOMPLETE:
- TheGameSpyInfo->sawFullGameList();
- break;
- case PeerResponse::PEERRESPONSE_STAGINGROOM:
- {
- GameSpyStagingRoom room;
- switch(resp.stagingRoom.action)
- {
- case PEER_CLEAR:
- TheGameSpyInfo->clearStagingRoomList();
- //TheGameSpyInfo->addText( UnicodeString(L"gameList: PEER_CLEAR"), GameSpyColor[GSCOLOR_DEFAULT], listboxLobbyChat );
- break;
- case PEER_ADD:
- case PEER_UPDATE:
- {
- if (resp.stagingRoom.percentComplete == 100)
- {
- TheGameSpyInfo->sawFullGameList();
- }
-
- //if (ParseAsciiStringToGameInfo(&room, resp.stagingRoomMapName.c_str()))
- //if (ParseAsciiStringToGameInfo(&room, resp.stagingServerGameOptions.c_str()))
- Bool serverOk = TRUE;
- if (!resp.stagingRoomMapName.length())
- {
- serverOk = FALSE;
- }
- // fix for ghost game problem - need to iterate over all resp.stagingRoomPlayerNames[i]
- Bool sawSelf = FALSE;
- //for (Int i=0; igetLocalName() == resp.stagingRoomPlayerNames[0].c_str())
- {
- sawSelf = TRUE; // don't show ghost games for myself
- }
- //}
- if (sawSelf)
- serverOk = FALSE;
-
- if (serverOk)
- {
- room.setGameName(UnicodeString(resp.stagingServerName.c_str()));
- room.setID(resp.stagingRoom.id);
- room.setHasPassword(resp.stagingRoom.requiresPassword);
- room.setVersion(resp.stagingRoom.version);
- room.setExeCRC(resp.stagingRoom.exeCRC);
- room.setIniCRC(resp.stagingRoom.iniCRC);
- room.setAllowObservers(resp.stagingRoom.allowObservers);
- room.setUseStats(resp.stagingRoom.useStats);
- room.setPingString(resp.stagingServerPingString.c_str());
- room.setLadderIP(resp.stagingServerLadderIP.c_str());
- room.setLadderPort(resp.stagingRoom.ladderPort);
- room.setReportedNumPlayers(resp.stagingRoom.numPlayers);
- room.setReportedMaxPlayers(resp.stagingRoom.maxPlayers);
- room.setReportedNumObservers(resp.stagingRoom.numObservers);
-
- Int i;
- AsciiString gsMapName = resp.stagingRoomMapName.c_str();
- AsciiString mapName = "";
- for (i=0; iportableMapPathToRealMapPath(mapName));
-
- Int numPlayers = 0;
- for (i=0; isetWins( resp.stagingRoom.wins[i] );
- slot->setLosses( resp.stagingRoom.losses[i] );
- slot->setProfileID( resp.stagingRoom.profileID[i] );
- slot->setPlayerTemplate( resp.stagingRoom.faction[i] );
- slot->setColor( resp.stagingRoom.color[i] );
- if (resp.stagingRoom.profileID[i] == SLOT_EASY_AI)
- {
- slot->setState(SLOT_EASY_AI);
- ++numPlayers;
- }
- else if (resp.stagingRoom.profileID[i] == SLOT_MED_AI)
- {
- slot->setState(SLOT_MED_AI);
- ++numPlayers;
- }
- else if (resp.stagingRoom.profileID[i] == SLOT_BRUTAL_AI)
- {
- slot->setState(SLOT_BRUTAL_AI);
- ++numPlayers;
- }
- else if (resp.stagingRoomPlayerNames[i].length())
- {
- UnicodeString nameUStr;
- nameUStr.translate(resp.stagingRoomPlayerNames[i].c_str());
- slot->setState(SLOT_PLAYER, nameUStr);
- ++numPlayers;
- }
- else
- {
- slot->setState(SLOT_OPEN);
- }
- }
- }
- DEBUG_ASSERTCRASH(numPlayers, ("Game had no players!\n"));
- //DEBUG_LOG(("Saw room: hasPass=%d, allowsObservers=%d\n", room.getHasPassword(), room.getAllowObservers()));
- if (resp.stagingRoom.action == PEER_ADD)
- {
- TheGameSpyInfo->addStagingRoom(room);
- //TheGameSpyInfo->addText( UnicodeString(L"gameList: PEER_ADD"), GameSpyColor[GSCOLOR_DEFAULT], listboxLobbyChat );
- }
- else
- {
- TheGameSpyInfo->updateStagingRoom(room);
- //TheGameSpyInfo->addText( UnicodeString(L"gameList: PEER_UPDATE"), GameSpyColor[GSCOLOR_DEFAULT], listboxLobbyChat );
- }
- }
- else
- {
- room.setID(resp.stagingRoom.id);
- TheGameSpyInfo->removeStagingRoom(room);
- //TheGameSpyInfo->addText( UnicodeString(L"gameList: PEER_UPDATE FAILED"), GameSpyColor[GSCOLOR_DEFAULT], listboxLobbyChat );
- }
- break;
- }
- case PEER_REMOVE:
- room.setID(resp.stagingRoom.id);
- TheGameSpyInfo->removeStagingRoom(room);
- //TheGameSpyInfo->addText( UnicodeString(L"gameList: PEER_REMOVE"), GameSpyColor[GSCOLOR_DEFAULT], listboxLobbyChat );
- break;
- default:
- //TheGameSpyInfo->addText( UnicodeString(L"gameList: Unknown"), GameSpyColor[GSCOLOR_DEFAULT], listboxLobbyChat );
- break;
- }
- }
- break;
- }
- }
-#if 0
- if (shouldRepopulatePlayers)
- {
- PopulateLobbyPlayerListbox();
- }
-#else
- refreshPlayerList();
-#endif
-
-#ifdef PERF_TEST
- // check performance
- end = timeGetTime();
- PERF_LOG(("Frame time was %d ms\n", end-start));
- std::list::const_iterator it;
- for (it = responses.begin(); it != responses.end(); ++it)
- {
- PERF_LOG((" %s\n", getMessageString(*it)));
- }
- PERF_LOG(("\n"));
-#endif // PERF_TEST
-
-#if 0
-// Removed 2-17-03 to pull out into a function so we can do the same checks
- Int refreshInterval = gameListRefreshInterval;
-
- if ((gameListRefreshTime == 0) || ((gameListRefreshTime + refreshInterval) <= timeGetTime()))
- {
- if (TheGameSpyInfo->hasStagingRoomListChanged())
- {
- //DEBUG_LOG(("################### refreshing game list\n"));
- //DEBUG_LOG(("gameRefreshTime=%d, refreshInterval=%d, now=%d\n", gameListRefreshTime, refreshInterval, timeGetTime()));
- RefreshGameListBoxes();
- gameListRefreshTime = timeGetTime();
- } else {
- //DEBUG_LOG(("-"));
- }
- } else {
- //DEBUG_LOG(("gameListRefreshTime: %d refreshInterval: %d\n"));
- }
-#else
- refreshGameList();
-#endif
- }
-}// WOLLobbyMenuUpdate
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Lobby Menu input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLLobbyMenuInput( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
- UnsignedByte key = mData1;
- UnsignedByte state = mData2;
- if (buttonPushed)
- break;
-
- switch( key )
- {
-
- // ----------------------------------------------------------------------------------------
- case KEY_ESC:
- {
-
- //
- // send a simulated selected event to the parent window of the
- // back/exit button
- //
- if( BitTest( state, KEY_STATE_UP ) )
- {
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)buttonBack, buttonBackID );
-
- } // end if
-
- // don't let key fall through anywhere else
- return MSG_HANDLED;
-
- } // end escape
-
- } // end switch( key )
-
- } // end char
-
- } // end switch( msg )
-
- return MSG_IGNORED;
-}// WOLLobbyMenuInput
-
-//static void doSliderTrack(GameWindow *control, Int val)
-//{
-// Int sliderW, sliderH, sliderX, sliderY;
-// control->winGetPosition(&sliderX, &sliderY);
-// control->winGetSize(&sliderW, &sliderH);
-// Real cursorY = sliderY + (100-val)*0.01f*sliderH;
-//
-// extern GameWindow *listboxLobbyGamesSmall;
-// extern GameWindow *listboxLobbyGamesLarge;
-// extern GameWindow *listboxLobbyGameInfo;
-//
-// static Int gwsX = 0, gwsY = 0, gwsW = 0, gwsH = 0;
-// static Int gwlX = 0, gwlY = 0, gwlW = 0, gwlH = 0;
-// static Int gwiX = 0, gwiY = 0, gwiW = 0, gwiH = 0;
-// static Int pwX = 0, pwY = 0, pwW = 0, pwH = 0;
-// static Int chatPosX = 0, chatPosY = 0, chatW = 0, chatH = 0;
-// static Int spacing = 0;
-// if (chatPosX == 0)
-// {
-// listboxLobbyChat->winGetPosition(&chatPosX, &chatPosY);
-// listboxLobbyChat->winGetSize(&chatW, &chatH);
-//
-//// listboxLobbyGamesSmall->winGetPosition(&gwsX, &gwsY);
-//// listboxLobbyGamesSmall->winGetSize(&gwsW, &gwsH);
-//
-// listboxLobbyGamesLarge->winGetPosition(&gwlX, &gwlY);
-// listboxLobbyGamesLarge->winGetSize(&gwlW, &gwlH);
-//
-//// listboxLobbyGameInfo->winGetPosition(&gwiX, &gwiY);
-//// listboxLobbyGameInfo->winGetSize(&gwiW, &gwiH);
-////
-// listboxLobbyPlayers->winGetPosition(&pwX, &pwY);
-// listboxLobbyPlayers->winGetSize(&pwW, &pwH);
-//
-// spacing = chatPosY - pwY - pwH;
-// }
-//
-// Int newChatY = cursorY;
-// Int newChatH = chatH + chatPosY - newChatY;
-// listboxLobbyChat->winSetPosition(chatPosX, newChatY);
-// listboxLobbyChat->winSetSize(chatW, newChatH);
-//
-// Int newH = cursorY - pwY - spacing;
-// listboxLobbyPlayers->winSetSize(pwW, newH);
-//// listboxLobbyGamesSmall->winSetSize(gwsW, newH);
-// listboxLobbyGamesLarge->winSetSize(gwlW, newH);
-//// listboxLobbyGameInfo->winSetSize(gwiW, newH);
-
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Lobby Menu window system callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLLobbyMenuSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- UnicodeString txtInput;
- static NameKeyType buttonGameListTypeToggleID = NAMEKEY_INVALID;
-
- switch( msg )
- {
-
-
- //---------------------------------------------------------------------------------------------
- case GWM_CREATE:
- {
- buttonGameListTypeToggleID = NAMEKEY("WOLCustomLobby.wnd:ButtonGameListToggle");
-// sliderChatAdjustID = NAMEKEY("WOLCustomLobby.wnd:SliderChatAdjust");
-
- break;
- } // case GWM_DESTROY:
-
- //---------------------------------------------------------------------------------------------
- case GWM_DESTROY:
- {
- break;
- } // case GWM_DESTROY:
-
- //---------------------------------------------------------------------------------------------
- case GWM_INPUT_FOCUS:
- {
- // if we're givin the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
-
- return MSG_HANDLED;
- }//case GWM_INPUT_FOCUS:
-
- //---------------------------------------------------------------------------------------------
- case GLM_SELECTED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- if ( controlID == GetGameListBoxID() )
- {
- int rowSelected = mData2;
- if( rowSelected >= 0 )
- {
- buttonJoin->winEnable(TRUE);
- static UnsignedInt lastFrame = 0;
- static Int lastID = -1;
- UnsignedInt now = TheGameClient->getFrame();
-
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_GETEXTENDEDSTAGINGROOMINFO;
- req.stagingRoom.id = (Int)GadgetListBoxGetItemData(control, rowSelected, 0);
-
- if (lastID != req.stagingRoom.id || now > lastFrame + 60)
- {
- TheGameSpyPeerMessageQueue->addRequest(req);
- }
-
- lastID = req.stagingRoom.id;
- lastFrame = now;
- }
- else
- {
- buttonJoin->winEnable(FALSE);
- }
- if (GetGameInfoListBox())
- {
- RefreshGameInfoListBox(GetGameListBox(), GetGameInfoListBox());
- }
- } //if ( controlID == GetGameListBoxID() )
-
- break;
- }
-
- //---------------------------------------------------------------------------------------------
- case GBM_SELECTED:
- {
- if (buttonPushed)
- break;
-
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if (HandleSortButton((NameKeyType)controlID))
- break;
-
- // If we back out, just bail - we haven't gotten far enough to need to log out
- if ( controlID == buttonBackID )
- {
- if (s_tryingToHostOrJoin)
- break;
-
- // Leave any group room, then pop off the screen
- TheGameSpyInfo->leaveGroupRoom();
-
- SetLobbyAttemptHostJoin( TRUE ); // pretend, since we don't want to queue up another action
- buttonPushed = true;
- nextScreen = "Menus/WOLWelcomeMenu.wnd";
- TheShell->pop();
-
- } //if ( controlID == buttonBack )
- else if ( controlID == buttonRefreshID )
- {
- // Added 2/17/03 added the game refresh button
- refreshGameList(TRUE);
- refreshPlayerList(TRUE);
- }
- else if ( controlID == buttonHostID )
- {
- if (s_tryingToHostOrJoin)
- break;
-
- SetLobbyAttemptHostJoin( TRUE );
- TheLobbyQueuedUTMs.clear();
- groupRoomToJoin = TheGameSpyInfo->getCurrentGroupRoom();
- GameSpyOpenOverlay(GSOVERLAY_GAMEOPTIONS);
- }
- else if ( controlID == buttonJoinID )
- {
- if (s_tryingToHostOrJoin)
- break;
-
- TheLobbyQueuedUTMs.clear();
- // Look for a game to join
- groupRoomToJoin = TheGameSpyInfo->getCurrentGroupRoom();
- Int selected;
- GadgetListBoxGetSelected(GetGameListBox(), &selected);
- if (selected >= 0)
- {
- Int selectedID = (Int)GadgetListBoxGetItemData(GetGameListBox(), selected);
- if (selectedID > 0)
- {
- StagingRoomMap *srm = TheGameSpyInfo->getStagingRoomList();
- StagingRoomMap::iterator srmIt = srm->find(selectedID);
- if (srmIt != srm->end())
- {
- GameSpyStagingRoom *roomToJoin = srmIt->second;
- if (!roomToJoin || roomToJoin->getExeCRC() != TheGlobalData->m_exeCRC || roomToJoin->getIniCRC() != TheGlobalData->m_iniCRC)
- {
- // bad crc. don't go.
- DEBUG_LOG(("WOLLobbyMenuSystem - CRC mismatch with the game I'm trying to join. My CRC's - EXE:0x%08X INI:0x%08X Their CRC's - EXE:0x%08x INI:0x%08x\n", TheGlobalData->m_exeCRC, TheGlobalData->m_iniCRC, roomToJoin->getExeCRC(), roomToJoin->getIniCRC()));
-#if defined(_DEBUG) || defined(_INTERNAL)
- if (TheGlobalData->m_netMinPlayers)
- {
- GSMessageBoxOk(TheGameText->fetch("GUI:JoinFailedDefault"), TheGameText->fetch("GUI:JoinFailedCRCMismatch"));
- break;
- }
- else if (g_fakeCRC)
- {
- TheWritableGlobalData->m_exeCRC = roomToJoin->getExeCRC();
- TheWritableGlobalData->m_iniCRC = roomToJoin->getIniCRC();
- }
-#else
- GSMessageBoxOk(TheGameText->fetch("GUI:JoinFailedDefault"), TheGameText->fetch("GUI:JoinFailedCRCMismatch"));
- break;
-#endif
- }
- Bool unknownLadder = (roomToJoin->getLadderPort() && TheLadderList->findLadder(roomToJoin->getLadderIP(), roomToJoin->getLadderPort()) == NULL);
- if (unknownLadder)
- {
- GSMessageBoxOk(TheGameText->fetch("GUI:JoinFailedDefault"), TheGameText->fetch("GUI:JoinFailedUnknownLadder"));
- break;
- }
- if (roomToJoin->getNumPlayers() == MAX_SLOTS)
- {
- GSMessageBoxOk(TheGameText->fetch("GUI:JoinFailedDefault"), TheGameText->fetch("GUI:JoinFailedRoomFull"));
- break;
- }
- TheGameSpyInfo->markAsStagingRoomJoiner(selectedID);
- TheGameSpyGame->setGameName(roomToJoin->getGameName());
- TheGameSpyGame->setLadderIP(roomToJoin->getLadderIP());
- TheGameSpyGame->setLadderPort(roomToJoin->getLadderPort());
- SetLobbyAttemptHostJoin( TRUE );
- if (roomToJoin->getHasPassword())
- {
- GameSpyOpenOverlay(GSOVERLAY_GAMEPASSWORD);
- }
- else
- {
- // no password - just join it
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_JOINSTAGINGROOM;
- req.text = srmIt->second->getGameName().str();
- req.stagingRoom.id = selectedID;
- req.password = "";
- TheGameSpyPeerMessageQueue->addRequest(req);
- }
- }
- }
- else
- {
- GSMessageBoxOk(TheGameText->fetch("GUI:Error"), TheGameText->fetch("GUI:NoGameInfo"), NULL);
- }
- }
- else
- {
- GSMessageBoxOk(TheGameText->fetch("GUI:Error"), TheGameText->fetch("GUI:NoGameSelected"), NULL);
- }
- }
- else if ( controlID == buttonBuddyID )
- {
- GameSpyToggleOverlay( GSOVERLAY_BUDDY );
- }
- else if ( controlID == buttonGameListTypeToggleID )
- {
- ToggleGameListType();
- }
- else if ( controlID == buttonEmoteID )
- {
- // read the user's input and clear the entry box
- UnicodeString txtInput;
- txtInput.set(GadgetTextEntryGetText( textEntryChat ));
- GadgetTextEntrySetText(textEntryChat, UnicodeString::TheEmptyString);
- txtInput.trim();
- if (!txtInput.isEmpty())
- {
- // Send the message
- TheGameSpyInfo->sendChat( txtInput, FALSE, listboxLobbyPlayers ); // 'emote' button now just sends text
- }
- }
-
- break;
- }// case GBM_SELECTED:
-
- //---------------------------------------------------------------------------------------------
- case GCM_SELECTED:
- {
- if (s_tryingToHostOrJoin)
- break;
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- if( controlID == comboLobbyGroupRoomsID )
- {
- int rowSelected = -1;
- GadgetComboBoxGetSelectedPos(control, &rowSelected);
-
- DEBUG_LOG(("Row selected = %d\n", rowSelected));
- if (rowSelected >= 0)
- {
- Int groupID;
- groupID = (Int)GadgetComboBoxGetItemData(comboLobbyGroupRooms, rowSelected);
- DEBUG_LOG(("ItemData was %d, current Group Room is %d\n", groupID, TheGameSpyInfo->getCurrentGroupRoom()));
- if (groupID && groupID != TheGameSpyInfo->getCurrentGroupRoom())
- {
- TheGameSpyInfo->leaveGroupRoom();
- TheGameSpyInfo->joinGroupRoom(groupID);
-
- if (TheGameSpyConfig->restrictGamesToLobby())
- {
- TheGameSpyInfo->clearStagingRoomList();
- RefreshGameListBoxes();
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_STARTGAMELIST;
- req.gameList.restrictGameList = TRUE;
- TheGameSpyPeerMessageQueue->addRequest(req);
- }
- }
- }
- }
- } // case GCM_SELECTED
- break;
-
- //---------------------------------------------------------------------------------------------
- case GLM_DOUBLE_CLICKED:
- {
- if (buttonPushed)
- break;
-
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- if (controlID == GetGameListBoxID())
- {
- int rowSelected = mData2;
-
- if (rowSelected >= 0)
- {
- GadgetListBoxSetSelected( control, rowSelected );
- GameWindow *button = TheWindowManager->winGetWindowFromId( window, buttonJoinID );
-
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)button, buttonJoinID );
- }
- }
- break;
- }// case GLM_DOUBLE_CLICKED:
-
- //---------------------------------------------------------------------------------------------
- case GLM_RIGHT_CLICKED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if( controlID == listboxLobbyPlayersID )
- {
- RightClickStruct *rc = (RightClickStruct *)mData2;
- WindowLayout *rcLayout = NULL;
- GameWindow *rcMenu;
- if(rc->pos < 0)
- {
- GadgetListBoxSetSelected(control, -1);
- break;
- }
-
- GPProfile profileID = 0;
- AsciiString aName;
- aName.translate(GadgetListBoxGetText(control, rc->pos, COLUMN_PLAYERNAME));
- PlayerInfoMap::iterator it = TheGameSpyInfo->getPlayerInfoMap()->find(aName);
- if (it != TheGameSpyInfo->getPlayerInfoMap()->end())
- profileID = it->second.m_profileID;
-
- Bool isBuddy = FALSE;
- if (profileID <= 0)
- rcLayout = TheWindowManager->winCreateLayout(AsciiString("Menus/RCNoProfileMenu.wnd"));
- else
- {
- if (profileID == TheGameSpyInfo->getLocalProfileID())
- {
- rcLayout = TheWindowManager->winCreateLayout(AsciiString("Menus/RCLocalPlayerMenu.wnd"));
- }
- else if(TheGameSpyInfo->isBuddy(profileID))
- {
- rcLayout = TheWindowManager->winCreateLayout(AsciiString("Menus/RCBuddiesMenu.wnd"));
- isBuddy = TRUE;
- }
- else
- rcLayout = TheWindowManager->winCreateLayout(AsciiString("Menus/RCNonBuddiesMenu.wnd"));
- }
- if(!rcLayout)
- break;
-
- GadgetListBoxSetSelected(control, rc->pos);
-
- rcMenu = rcLayout->getFirstWindow();
- rcMenu->winGetLayout()->runInit();
- rcMenu->winBringToTop();
- rcMenu->winHide(FALSE);
- setUnignoreText( rcLayout, aName, profileID);
- ICoord2D rcSize, rcPos;
- rcMenu->winGetSize(&rcSize.x, &rcSize.y);
- rcPos.x = rc->mouseX;
- rcPos.y = rc->mouseY;
- if(rc->mouseX + rcSize.x > TheDisplay->getWidth())
- rcPos.x = TheDisplay->getWidth() - rcSize.x;
- if(rc->mouseY + rcSize.y > TheDisplay->getHeight())
- rcPos.y = TheDisplay->getHeight() - rcSize.y;
- rcMenu->winSetPosition(rcPos.x, rcPos.y);
-
- GameSpyRCMenuData *rcData = NEW GameSpyRCMenuData;
- rcData->m_id = profileID;
- rcData->m_nick = aName;
- rcData->m_itemType = (isBuddy)?ITEM_BUDDY:ITEM_NONBUDDY;
- rcMenu->winSetUserData((void *)rcData);
- TheWindowManager->winSetLoneWindow(rcMenu);
- }
- else if( controlID == GetGameListBoxID() )
- {
- RightClickStruct *rc = (RightClickStruct *)mData2;
- WindowLayout *rcLayout = NULL;
- GameWindow *rcMenu;
- if(rc->pos < 0)
- {
- GadgetListBoxSetSelected(control, -1);
- break;
- }
-
- Int selectedID = (Int)GadgetListBoxGetItemData(control, rc->pos);
- if (selectedID > 0)
- {
- StagingRoomMap *srm = TheGameSpyInfo->getStagingRoomList();
- StagingRoomMap::iterator srmIt = srm->find(selectedID);
- if (srmIt != srm->end())
- {
- GameSpyStagingRoom *theRoom = srmIt->second;
- if (!theRoom)
- break;
- const LadderInfo *linfo = TheLadderList->findLadder(theRoom->getLadderIP(), theRoom->getLadderPort());
- if (linfo)
- {
- rcLayout = TheWindowManager->winCreateLayout(AsciiString("Menus/RCGameDetailsMenu.wnd"));
- if (!rcLayout)
- break;
-
- GadgetListBoxSetSelected(control, rc->pos);
-
- rcMenu = rcLayout->getFirstWindow();
- rcMenu->winGetLayout()->runInit();
- rcMenu->winBringToTop();
- rcMenu->winHide(FALSE);
- rcMenu->winSetPosition(rc->mouseX, rc->mouseY);
-
- rcMenu->winSetUserData((void *)selectedID);
- TheWindowManager->winSetLoneWindow(rcMenu);
- }
- }
- }
- }
- break;
- }
-
-// //---------------------------------------------------------------------------------------------
-// case GSM_SLIDER_TRACK:
-// {
-// if (buttonPushed)
-// break;
-//
-// GameWindow *control = (GameWindow *)mData1;
-// Int val = (Int)mData2;
-// Int controlID = control->winGetWindowId();
-// if (controlID == sliderChatAdjustID)
-// {
-// doSliderTrack(control, val);
-// }
-// break;
-// }
-
- //---------------------------------------------------------------------------------------------
- case GEM_EDIT_DONE:
- {
- if (buttonPushed)
- break;
-
- // read the user's input and clear the entry box
- UnicodeString txtInput;
- txtInput.set(GadgetTextEntryGetText( textEntryChat ));
- GadgetTextEntrySetText(textEntryChat, UnicodeString::TheEmptyString);
- txtInput.trim();
- if (!txtInput.isEmpty())
- {
- // Send the message
- if (!handleLobbySlashCommands(txtInput))
- {
- TheGameSpyInfo->sendChat( txtInput, false, listboxLobbyPlayers );
- }
- }
- break;
- }
-
- //---------------------------------------------------------------------------------------------
- default:
- return MSG_IGNORED;
-
- }//Switch
-
- return MSG_HANDLED;
-}// WOLLobbyMenuSystem
diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLocaleSelectPopup.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLocaleSelectPopup.cpp
deleted file mode 100644
index 5da99177a7d..00000000000
--- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLocaleSelectPopup.cpp
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////////////
-// FILE: WOLLocaleSelectPopup.cpp
-// Author: Matt Campbell, December 2001
-// Description: WOL locale select popup
-///////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "GameClient/GameText.h"
-#include "Common/CustomMatchPreferences.h"
-#include "Common/GameEngine.h"
-#include "Common/GameSpyMiscPreferences.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/Shell.h"
-#include "GameClient/KeyDefs.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/GadgetListBox.h"
-#include "Common/GlobalData.h"
-#include "GameNetwork/GameSpyOverlay.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpy/PeerThread.h"
-#include "GameNetwork/GameSpy/PersistentStorageDefs.h"
-#include "GameNetwork/GameSpy/PersistentStorageThread.h"
-
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-// window ids ------------------------------------------------------------------------------
-static NameKeyType parentLocaleSelectID = NAMEKEY_INVALID;
-static NameKeyType buttonOkID = NAMEKEY_INVALID;
-static NameKeyType listboxLocaleID = NAMEKEY_INVALID;
-
-// Window Pointers ------------------------------------------------------------------------
-static GameWindow *parentLocaleSelect = NULL;
-static GameWindow *buttonOk = NULL;
-static GameWindow *listboxLocale = NULL;
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the WOL Status Menu */
-//-------------------------------------------------------------------------------------------------
-void WOLLocaleSelectInit( WindowLayout *layout, void *userData )
-{
- parentLocaleSelectID = TheNameKeyGenerator->nameToKey( AsciiString( "PopupLocaleSelect.wnd:ParentLocaleSelect" ) );
- buttonOkID = TheNameKeyGenerator->nameToKey( AsciiString( "PopupLocaleSelect.wnd:ButtonOk" ) );
- listboxLocaleID = TheNameKeyGenerator->nameToKey( AsciiString( "PopupLocaleSelect.wnd:ListBoxLocaleSelect" ) );
- parentLocaleSelect = TheWindowManager->winGetWindowFromId( NULL, parentLocaleSelectID );
- buttonOk = TheWindowManager->winGetWindowFromId( NULL, buttonOkID);
- listboxLocale = TheWindowManager->winGetWindowFromId( NULL, listboxLocaleID);
-
- for (int i=LOC_MIN; i<=LOC_MAX; ++i)
- {
- AsciiString id;
- id.format("WOL:Locale%2.2d", i);
- GadgetListBoxAddEntryText(listboxLocale, TheGameText->fetch(id.str()), GameSpyColor[GSCOLOR_DEFAULT], -1, -1);
- }
- GadgetListBoxSetSelected(listboxLocale, 0);
-
- // Show Menu
- layout->hide( FALSE );
-
- // Set Keyboard to Main Parent
- TheWindowManager->winSetFocus( parentLocaleSelect );
- TheWindowManager->winSetModal( parentLocaleSelect );
-} // WOLLocaleSelectInit
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Status Menu shutdown method */
-//-------------------------------------------------------------------------------------------------
-void WOLLocaleSelectShutdown( WindowLayout *layout, void *userData )
-{
-
- // hide menu
- layout->hide( TRUE );
-
- // our shutdown is complete
- TheShell->shutdownComplete( layout );
-
-} // WOLLocaleSelectShutdown
-
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Status Menu update method */
-//-------------------------------------------------------------------------------------------------
-void WOLLocaleSelectUpdate( WindowLayout * layout, void *userData)
-{
-
-}// WOLLocaleSelectUpdate
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Status Menu input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLLocaleSelectInput( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
-// UnsignedByte key = mData1;
-// UnsignedByte state = mData2;
-
- // ----------------------------------------------------------------------------------------
- // don't let key fall through anywhere else
- return MSG_HANDLED;
- } // end char
- } // end switch( msg )
- return MSG_IGNORED;
-}// WOLLocaleSelectInput
-
-//Int getRegistryNicknameOffset(AsciiString nick); /// @todo: mdc remove this once we can save ini pref files
-//-------------------------------------------------------------------------------------------------
-/** WOL Status Menu window system callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLLocaleSelectSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- UnicodeString txtInput;
-
- switch( msg )
- {
-
-
- case GWM_CREATE:
- {
-
- break;
- } // case GWM_DESTROY:
-
- case GWM_DESTROY:
- {
- break;
- } // case GWM_DESTROY:
-
- case GWM_INPUT_FOCUS:
- {
- // if we're givin the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
-
- return MSG_HANDLED;
- }//case GWM_INPUT_FOCUS:
-
- case GBM_SELECTED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if ( controlID == buttonOkID )
- {
- int selected;
- GadgetListBoxGetSelected(listboxLocale, &selected);
- if (selected < 0)
- return MSG_HANDLED; // can't select nothing!
- PSRequest psReq;
- psReq.requestType = PSRequest::PSREQUEST_UPDATEPLAYERLOCALE;
- psReq.player.locale = selected + LOC_MIN;
- psReq.email = TheGameSpyInfo->getLocalEmail().str();
- psReq.nick = TheGameSpyInfo->getLocalBaseName().str();
- psReq.password = TheGameSpyInfo->getLocalPassword().str();
- psReq.player.id = TheGameSpyInfo->getLocalProfileID();
-
- TheGameSpyPSMessageQueue->addRequest(psReq);
- GameSpyCloseOverlay(GSOVERLAY_LOCALESELECT);
-
- GameSpyMiscPreferences cPref;
- cPref.setLocale(psReq.player.locale);
- cPref.write();
-
- PSPlayerStats stats = TheGameSpyPSMessageQueue->findPlayerStatsByID(TheGameSpyInfo->getLocalProfileID());
- stats.locale = psReq.player.locale;
- if (stats.id == TheGameSpyInfo->getLocalProfileID())
- TheGameSpyPSMessageQueue->trackPlayerStats(stats);
-
- if(stats.id == 0)
- {
- stats = TheGameSpyInfo->getCachedLocalPlayerStats();
- stats.locale = psReq.player.locale;
- TheGameSpyInfo->setCachedLocalPlayerStats(stats);
- }
- else
- {
- // force an update of our shtuff
- PSResponse newResp;
- newResp.responseType = PSResponse::PSRESPONSE_PLAYERSTATS;
- newResp.player = TheGameSpyPSMessageQueue->findPlayerStatsByID(TheGameSpyInfo->getLocalProfileID());
- TheGameSpyPSMessageQueue->addResponse(newResp);
- }
- CheckReOpenPlayerInfo();
- } //if ( controlID == buttonDisconnect )
- break;
- }// case GBM_SELECTED:
-
- case GEM_EDIT_DONE:
- {
- break;
- }
- default:
- return MSG_IGNORED;
-
- }//Switch
-
- return MSG_HANDLED;
-}// WOLLocaleSelectSystem
diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLoginMenu.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLoginMenu.cpp
deleted file mode 100644
index 3a4378ebb81..00000000000
--- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLoginMenu.cpp
+++ /dev/null
@@ -1,1511 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////////////
-// FILE: WOLLoginMenu.cpp
-// Author: Chris Huybregts, November 2001
-// Description: Lan Lobby Menu
-///////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/STLTypedefs.h"
-
-#include "Common/File.h"
-#include "Common/FileSystem.h"
-#include "Common/GameEngine.h"
-#include "Common/GameSpyMiscPreferences.h"
-#include "Common/QuotedPrintable.h"
-#include "Common/Registry.h"
-#include "Common/UserPreferences.h"
-#include "GameClient/AnimateWindowManager.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/GameText.h"
-#include "GameClient/Shell.h"
-#include "GameClient/KeyDefs.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/GadgetListBox.h"
-#include "GameClient/GadgetComboBox.h"
-#include "GameClient/GadgetCheckBox.h"
-#include "GameClient/GadgetStaticText.h"
-#include "GameClient/GadgetTextEntry.h"
-#include "GameClient/MessageBox.h"
-#include "GameClient/ShellHooks.h"
-#include "GameClient/GameWindowTransitions.h"
-
-#include "GameNetwork/GameSpy/GSConfig.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpy/PeerThread.h"
-#include "GameNetwork/GameSpy/PingThread.h"
-#include "GameNetwork/GameSpy/BuddyThread.h"
-#include "GameNetwork/GameSpy/ThreadUtils.h"
-#include "GameNetwork/GameSpy/PersistentStorageThread.h"
-
-#include "GameNetwork/GameSpyOverlay.h"
-
-
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-
-#ifdef ALLOW_NON_PROFILED_LOGIN
-Bool GameSpyUseProfiles = false;
-#endif // ALLOW_NON_PROFILED_LOGIN
-
-
-static Bool isShuttingDown = false;
-static Bool buttonPushed = false;
-static char *nextScreen = NULL;
-
-static const UnsignedInt loginTimeoutInMS = 10000;
-static UnsignedInt loginAttemptTime = 0;
-
-class GameSpyLoginPreferences : public UserPreferences
-{
-public:
- GameSpyLoginPreferences() { m_emailPasswordMap.clear(); m_emailNickMap.clear(); }
- virtual ~GameSpyLoginPreferences() { m_emailPasswordMap.clear(); m_emailNickMap.clear(); }
-
- virtual Bool load(AsciiString fname);
- virtual Bool write(void);
-
- AsciiString getPasswordForEmail( AsciiString email );
- AsciiString getDateForEmail( AsciiString email, AsciiString &month, AsciiString &date, AsciiString &year );
- AsciiStringList getNicksForEmail( AsciiString email );
- void addLogin( AsciiString email, AsciiString nick, AsciiString password, AsciiString date );
- void forgetLogin( AsciiString email );
- AsciiStringList getEmails( void );
-
-private:
- typedef std::map PassMap;
- typedef std::map DateMap;
- typedef std::map NickMap;
- PassMap m_emailPasswordMap;
- NickMap m_emailNickMap;
- DateMap m_emailDateMap;
-};
-
-static AsciiString obfuscate( AsciiString in )
-{
- char *buf = NEW char[in.getLength() + 1];
- strcpy(buf, in.str());
- static const char *xor = "1337Munkee";
- char *c = buf;
- const char *c2 = xor;
- while (*c)
- {
- if (!*c2)
- c2 = xor;
- if (*c != *c2)
- *c = *c++ ^ *c2++;
- else
- c++, c2++;
- }
- AsciiString out = buf;
- delete buf;
- return out;
-}
-
-Bool GameSpyLoginPreferences::load( AsciiString fname )
-{
- if (!UserPreferences::load(fname))
- return false;
-
- UserPreferences::iterator upIt = begin();
- while (upIt != end())
- {
- AsciiString key = upIt->first;
- if (key.startsWith("pass_"))
- {
- AsciiString email, pass;
- email = key.str() + 5;
- pass = upIt->second;
-
- AsciiString quoPass = QuotedPrintableToAsciiString(pass);
- pass = obfuscate(quoPass);
-
- m_emailPasswordMap[email] = pass;
- }
- if (key.startsWith("date_"))
- {
- AsciiString email, date;
- email = key.str() + 5;
- date = upIt->second;
-
- date = QuotedPrintableToAsciiString(date);
-
- m_emailDateMap[email] = date;
- }
- else if (key.startsWith("nick_"))
- {
- AsciiString email, nick, nicks;
- email = key.str() + 5;
- nicks = upIt->second;
- while (nicks.nextToken(&nick, ","))
- {
- m_emailNickMap[email].push_back(nick);
- }
- }
- ++upIt;
- }
-
- return true;
-}
-
-Bool GameSpyLoginPreferences::write( void )
-{
- if (m_filename.isEmpty())
- return false;
-
- FILE *fp = fopen(m_filename.str(), "w");
- if (fp)
- {
- fprintf(fp, "lastEmail = %s\n", ((*this)["lastEmail"].str()));
- fprintf(fp, "lastName = %s\n", ((*this)["lastName"].str()));
- fprintf(fp, "useProfiles = %s\n", ((*this)["useProfiles"].str()));
- PassMap::iterator passIt = m_emailPasswordMap.begin();
- while (passIt != m_emailPasswordMap.end())
- {
- AsciiString pass = obfuscate(passIt->second);
- AsciiString quoPass = AsciiStringToQuotedPrintable(pass);
-
- fprintf(fp, "pass_%s = %s\n", passIt->first.str(), quoPass.str());
- ++passIt;
- }
-
- PassMap::iterator dateIt = m_emailDateMap.begin();
- while (dateIt != m_emailDateMap.end())
- {
- AsciiString date = AsciiStringToQuotedPrintable(dateIt->second);
-
- fprintf(fp, "date_%s = %s\n", dateIt->first.str(), date.str());
- ++dateIt;
- }
-
- NickMap::iterator nickIt = m_emailNickMap.begin();
- while (nickIt != m_emailNickMap.end())
- {
- AsciiString nicks;
- AsciiStringListIterator listIt = nickIt->second.begin();
- while (listIt != nickIt->second.end())
- {
- nicks.concat(*listIt);
- nicks.concat(',');
- ++listIt;
- }
- fprintf(fp, "nick_%s = %s\n", nickIt->first.str(), nicks.str());
- ++nickIt;
- }
-
- fclose(fp);
- return true;
- }
- return false;
-}
-AsciiString GameSpyLoginPreferences::getDateForEmail( AsciiString email, AsciiString &month, AsciiString &date, AsciiString &year )
-{
- if ( m_emailDateMap.find(email) == m_emailDateMap.end() )
- return AsciiString::TheEmptyString;
- AsciiString fullDate = m_emailDateMap[email];
- if(fullDate.getLength() != 8)
- return AsciiString::TheEmptyString;
- month.format("%c%c", fullDate.getCharAt(0), fullDate.getCharAt(1));
- date.format("%c%c", fullDate.getCharAt(2), fullDate.getCharAt(3));
- year.format("%c%c%c%c", fullDate.getCharAt(4), fullDate.getCharAt(5), fullDate.getCharAt(6), fullDate.getCharAt(7));
- return m_emailDateMap[email];
-}
-
-AsciiString GameSpyLoginPreferences::getPasswordForEmail( AsciiString email )
-{
- if ( m_emailPasswordMap.find(email) == m_emailPasswordMap.end() )
- return AsciiString::TheEmptyString;
- return m_emailPasswordMap[email];
-}
-
-AsciiStringList GameSpyLoginPreferences::getNicksForEmail( AsciiString email )
-{
- if ( m_emailNickMap.find(email) == m_emailNickMap.end() )
- {
- AsciiStringList empty;
- return empty;
- }
- return m_emailNickMap[email];
-}
-
-void GameSpyLoginPreferences::addLogin( AsciiString email, AsciiString nick, AsciiString password, AsciiString date )
-{
- if ( std::find(m_emailNickMap[email].begin(), m_emailNickMap[email].end(), nick) == m_emailNickMap[email].end() )
- m_emailNickMap[email].push_back(nick);
- m_emailPasswordMap[email] = password;
- m_emailDateMap[email] = date;
-}
-
-void GameSpyLoginPreferences::forgetLogin( AsciiString email )
-{
- m_emailNickMap.erase(email);
- m_emailPasswordMap.erase(email);
- m_emailDateMap.erase(email);
-
-}
-
-AsciiStringList GameSpyLoginPreferences::getEmails( void )
-{
- AsciiStringList theList;
- NickMap::iterator it = m_emailNickMap.begin();
- while (it != m_emailNickMap.end())
- {
- theList.push_back(it->first);
- ++it;
- }
- return theList;
-}
-
-static const char *PREF_FILENAME = "GameSpyLogin.ini";
-static GameSpyLoginPreferences *loginPref = NULL;
-
-static void startPings( void )
-{
- std::list pingServers = TheGameSpyConfig->getPingServers();
- Int timeout = TheGameSpyConfig->getPingTimeoutInMs();
- Int reps = TheGameSpyConfig->getNumPingRepetitions();
-
- for (std::list::const_iterator it = pingServers.begin(); it != pingServers.end(); ++it)
- {
- AsciiString pingServer = *it;
- PingRequest req;
- req.hostname = pingServer.str();
- req.repetitions = reps;
- req.timeout = timeout;
- ThePinger->addRequest(req);
- }
-}
-
-//-------------------------------------------------------------------------------------------------
-/** This is called when a shutdown is complete for this menu */
-//-------------------------------------------------------------------------------------------------
-static void shutdownComplete( WindowLayout *layout )
-{
-
- isShuttingDown = false;
-
- // hide the layout
- layout->hide( TRUE );
-
- // our shutdown is complete
- TheShell->shutdownComplete( layout, (nextScreen != NULL) );
-
- if (nextScreen != NULL)
- {
- if (loginPref)
- {
- loginPref->write();
- delete loginPref;
- loginPref = NULL;
- }
- TheShell->push(nextScreen);
- }
- else
- {
- DEBUG_ASSERTCRASH(loginPref != NULL, ("loginPref == NULL"));
- if (loginPref)
- {
- loginPref->write();
- delete loginPref;
- loginPref = NULL;
- }
- }
-
- nextScreen = NULL;
-
-} // end if
-
-
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-// window ids ------------------------------------------------------------------------------
-static NameKeyType parentWOLLoginID = NAMEKEY_INVALID;
-static NameKeyType buttonBackID = NAMEKEY_INVALID; // profile, quick
-static NameKeyType buttonLoginID = NAMEKEY_INVALID; // profile, quick
-static NameKeyType buttonCreateAccountID = NAMEKEY_INVALID; // profile, quick
-static NameKeyType buttonUseAccountID = NAMEKEY_INVALID; // quick
-static NameKeyType buttonDontUseAccountID = NAMEKEY_INVALID; // profile
-static NameKeyType buttonTOSID = NAMEKEY_INVALID; // TOS
-static NameKeyType parentTOSID = NAMEKEY_INVALID; // TOS Parent
-static NameKeyType buttonTOSOKID = NAMEKEY_INVALID; // TOS
-static NameKeyType listboxTOSID = NAMEKEY_INVALID; // TOS
-static NameKeyType comboBoxEmailID = NAMEKEY_INVALID; // profile
-static NameKeyType comboBoxLoginNameID = NAMEKEY_INVALID; // profile
-static NameKeyType textEntryLoginNameID = NAMEKEY_INVALID; // quick
-static NameKeyType textEntryPasswordID = NAMEKEY_INVALID; // profile
-static NameKeyType checkBoxRememberPasswordID = NAMEKEY_INVALID; // checkbox to remember information or not
-static NameKeyType textEntryMonthID = NAMEKEY_INVALID; // profile
-static NameKeyType textEntryDayID = NAMEKEY_INVALID; // profile
-static NameKeyType textEntryYearID = NAMEKEY_INVALID; // profile
-
-// Window Pointers ------------------------------------------------------------------------
-static GameWindow *parentWOLLogin = NULL;
-static GameWindow *buttonBack = NULL;
-static GameWindow *buttonLogin = NULL;
-static GameWindow *buttonCreateAccount = NULL;
-static GameWindow *buttonUseAccount = NULL;
-static GameWindow *buttonDontUseAccount = NULL;
-static GameWindow *buttonTOS = NULL;
-static GameWindow *parentTOS = NULL;
-static GameWindow *buttonTOSOK = NULL;
-static GameWindow *listboxTOS = NULL;
-static GameWindow *comboBoxEmail = NULL;
-static GameWindow *comboBoxLoginName = NULL;
-static GameWindow *textEntryLoginName = NULL;
-static GameWindow *textEntryPassword = NULL;
-static GameWindow *checkBoxRememberPassword = NULL;
-static GameWindow *textEntryMonth = NULL;
-static GameWindow *textEntryDay = NULL;
-static GameWindow *textEntryYear = NULL;
-
-void EnableLoginControls( Bool state )
-{
- if (buttonLogin)
- buttonLogin->winEnable(state);
- if (buttonCreateAccount)
- buttonCreateAccount->winEnable(state);
- if (buttonUseAccount)
- buttonUseAccount->winEnable(state);
- if (buttonDontUseAccount)
- buttonDontUseAccount->winEnable(state);
- if (comboBoxEmail)
- comboBoxEmail->winEnable(state);
- if (comboBoxLoginName)
- comboBoxLoginName->winEnable(state);
- if (textEntryLoginName)
- textEntryLoginName->winEnable(state);
- if (textEntryPassword)
- textEntryPassword->winEnable(state);
- if (checkBoxRememberPassword)
- checkBoxRememberPassword->winEnable(state);
- if( buttonTOS )
- buttonTOS->winEnable(state);
-
- if (textEntryMonth)
- textEntryMonth->winEnable(state);
- if (textEntryDay)
- textEntryDay->winEnable(state);
- if( textEntryYear )
- textEntryYear->winEnable(state);
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the WOL Login Menu */
-//-------------------------------------------------------------------------------------------------
-void WOLLoginMenuInit( WindowLayout *layout, void *userData )
-{
- nextScreen = NULL;
- buttonPushed = false;
- isShuttingDown = false;
- loginAttemptTime = 0;
-
- if (!loginPref)
- {
- loginPref = NEW GameSpyLoginPreferences;
- loginPref->load(PREF_FILENAME);
- }
-
- // if the ESRB warning is blank (other country) hide the box
- GameWindow *esrbTitle = TheWindowManager->winGetWindowFromId( NULL, NAMEKEY("GameSpyLoginProfile.wnd:StaticTextESRBTop") );
- GameWindow *esrbParent = TheWindowManager->winGetWindowFromId( NULL, NAMEKEY("GameSpyLoginProfile.wnd:ParentESRB") );
- if (esrbTitle && esrbParent)
- {
- if ( GadgetStaticTextGetText( esrbTitle ).getLength() < 2 )
- {
- esrbParent->winHide(TRUE);
- }
- }
-
- parentWOLLoginID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:WOLLoginMenuParent" );
- buttonBackID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:ButtonBack" );
- buttonLoginID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:ButtonLogin" );
- buttonCreateAccountID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:ButtonCreateAccount" );
- buttonUseAccountID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:ButtonUseAccount" );
- buttonDontUseAccountID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:ButtonDontUseAccount" );
- buttonTOSID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:ButtonTOS" );
- parentTOSID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:ParentTOS" );
- buttonTOSOKID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:ButtonTOSOK" );
- listboxTOSID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:ListboxTOS" );
- comboBoxEmailID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:ComboBoxEmail" );
- comboBoxLoginNameID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:ComboBoxLoginName" );
- textEntryLoginNameID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:TextEntryLoginName" );
- textEntryPasswordID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:TextEntryPassword" );
- checkBoxRememberPasswordID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:CheckBoxRememberInfo" );
- textEntryMonthID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:TextEntryMonth" );
- textEntryDayID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:TextEntryDay" );
- textEntryYearID = TheNameKeyGenerator->nameToKey( "GameSpyLoginProfile.wnd:TextEntryYear" );
-
- parentWOLLogin = TheWindowManager->winGetWindowFromId( NULL, parentWOLLoginID );
- buttonBack = TheWindowManager->winGetWindowFromId( NULL, buttonBackID);
- buttonLogin = TheWindowManager->winGetWindowFromId( NULL, buttonLoginID);
- buttonCreateAccount = TheWindowManager->winGetWindowFromId( NULL, buttonCreateAccountID);
- buttonUseAccount = TheWindowManager->winGetWindowFromId( NULL, buttonUseAccountID);
- buttonDontUseAccount = TheWindowManager->winGetWindowFromId( NULL, buttonDontUseAccountID);
- buttonTOS = TheWindowManager->winGetWindowFromId( NULL, buttonTOSID);
- parentTOS = TheWindowManager->winGetWindowFromId( NULL, parentTOSID);
- buttonTOSOK = TheWindowManager->winGetWindowFromId( NULL, buttonTOSOKID);
- listboxTOS = TheWindowManager->winGetWindowFromId( NULL, listboxTOSID);
- comboBoxEmail = TheWindowManager->winGetWindowFromId( NULL, comboBoxEmailID);
- comboBoxLoginName = TheWindowManager->winGetWindowFromId( NULL, comboBoxLoginNameID);
- textEntryLoginName = TheWindowManager->winGetWindowFromId( NULL, textEntryLoginNameID);
- textEntryPassword = TheWindowManager->winGetWindowFromId( NULL, textEntryPasswordID);
- checkBoxRememberPassword = TheWindowManager->winGetWindowFromId( NULL, checkBoxRememberPasswordID);
- textEntryMonth = TheWindowManager->winGetWindowFromId( NULL, textEntryMonthID);
- textEntryDay = TheWindowManager->winGetWindowFromId( NULL, textEntryDayID);
- textEntryYear = TheWindowManager->winGetWindowFromId( NULL, textEntryYearID);
-
- GadgetTextEntrySetText(textEntryMonth, UnicodeString::TheEmptyString);
-
- GadgetTextEntrySetText(textEntryDay, UnicodeString::TheEmptyString);
-
- GadgetTextEntrySetText(textEntryYear, UnicodeString::TheEmptyString);
-
-
-
- GameWindowList tabList;
- tabList.push_front(comboBoxEmail);
- tabList.push_back(comboBoxLoginName);
- tabList.push_back(textEntryPassword);
- tabList.push_back(textEntryMonth);
- tabList.push_back(textEntryDay);
- tabList.push_back(textEntryYear);
- tabList.push_back(checkBoxRememberPassword);
- tabList.push_back(buttonLogin);
- tabList.push_back(buttonCreateAccount);
- tabList.push_back(buttonTOS);
- tabList.push_back(buttonBack);
- TheWindowManager->clearTabList();
- TheWindowManager->registerTabList(tabList);
- TheWindowManager->winSetFocus( comboBoxEmail );
- // short form or long form?
-#ifdef ALLOW_NON_PROFILED_LOGIN
- if (parentWOLLogin)
- {
- GameSpyUseProfiles = true;
-#endif // ALLOW_NON_PROFILED_LOGIN
-
- DEBUG_ASSERTCRASH(buttonBack, ("buttonBack missing!"));
- DEBUG_ASSERTCRASH(buttonLogin, ("buttonLogin missing!"));
- DEBUG_ASSERTCRASH(buttonCreateAccount, ("buttonCreateAccount missing!"));
- //DEBUG_ASSERTCRASH(buttonDontUseAccount, ("buttonDontUseAccount missing!"));
- DEBUG_ASSERTCRASH(comboBoxEmail, ("comboBoxEmail missing!"));
- DEBUG_ASSERTCRASH(comboBoxLoginName, ("comboBoxLoginName missing!"));
- DEBUG_ASSERTCRASH(textEntryPassword, ("textEntryPassword missing!"));
-
- //TheShell->registerWithAnimateManager(parentWOLLogin, WIN_ANIMATION_SLIDE_TOP, TRUE);
- /**/
-// TheShell->registerWithAnimateManager(buttonTOS, WIN_ANIMATION_SLIDE_BOTTOM, TRUE);
- //TheShell->registerWithAnimateManager(buttonCreateAccount, WIN_ANIMATION_SLIDE_LEFT, TRUE);
- //TheShell->registerWithAnimateManager(buttonDontUseAccount, WIN_ANIMATION_SLIDE_LEFT, TRUE);
-// TheShell->registerWithAnimateManager(buttonBack, WIN_ANIMATION_SLIDE_BOTTOM, TRUE);
- /**/
-#ifdef ALLOW_NON_PROFILED_LOGIN
- }
- else
- {
- GameSpyUseProfiles = false;
-
- parentWOLLoginID = TheNameKeyGenerator->nameToKey( "GameSpyLoginQuick.wnd:WOLLoginMenuParent" );
- buttonBackID = TheNameKeyGenerator->nameToKey( "GameSpyLoginQuick.wnd:ButtonBack" );
- buttonLoginID = TheNameKeyGenerator->nameToKey( "GameSpyLoginQuick.wnd:ButtonLogin" );
- buttonCreateAccountID = TheNameKeyGenerator->nameToKey( "GameSpyLoginQuick.wnd:ButtonCreateAccount" );
- buttonUseAccountID = TheNameKeyGenerator->nameToKey( "GameSpyLoginQuick.wnd:ButtonUseAccount" );
- buttonDontUseAccountID = TheNameKeyGenerator->nameToKey( "GameSpyLoginQuick.wnd:ButtonDontUseAccount" );
- buttonTOSID = TheNameKeyGenerator->nameToKey( "GameSpyLoginQuick.wnd:ButtonTOS" );
- parentTOSID = TheNameKeyGenerator->nameToKey( "GameSpyLoginQuick.wnd:ParentTOS" );
- buttonTOSOKID = TheNameKeyGenerator->nameToKey( "GameSpyLoginQuick.wnd:ButtonTOSOK" );
- listboxTOSID = TheNameKeyGenerator->nameToKey( "GameSpyLoginQuick.wnd:ListboxTOS" );
- comboBoxEmailID = TheNameKeyGenerator->nameToKey( "GameSpyLoginQuick.wnd:ComboBoxEmail" );
- textEntryLoginNameID = TheNameKeyGenerator->nameToKey( "GameSpyLoginQuick.wnd:TextEntryLoginName" );
- textEntryPasswordID = TheNameKeyGenerator->nameToKey( "GameSpyLoginQuick.wnd:TextEntryPassword" );
- checkBoxRememberPasswordID = TheNameKeyGenerator->nameToKey( "GameSpyLoginQuick.wnd:CheckBoxRememberPassword" );
-
- parentWOLLogin = TheWindowManager->winGetWindowFromId( NULL, parentWOLLoginID );
- buttonBack = TheWindowManager->winGetWindowFromId( NULL, buttonBackID);
- buttonLogin = TheWindowManager->winGetWindowFromId( NULL, buttonLoginID);
- buttonCreateAccount = TheWindowManager->winGetWindowFromId( NULL, buttonCreateAccountID);
- buttonUseAccount = TheWindowManager->winGetWindowFromId( NULL, buttonUseAccountID);
- buttonDontUseAccount = TheWindowManager->winGetWindowFromId( NULL, buttonDontUseAccountID);
- comboBoxEmail = TheWindowManager->winGetWindowFromId( NULL, comboBoxEmailID);
- buttonTOS = TheWindowManager->winGetWindowFromId( NULL, buttonTOSID);
- parentTOS = TheWindowManager->winGetWindowFromId( NULL, parentTOSID);
- buttonTOSOK = TheWindowManager->winGetWindowFromId( NULL, buttonTOSOKID);
- listboxTOS = TheWindowManager->winGetWindowFromId( NULL, listboxTOSID);
- textEntryLoginName = TheWindowManager->winGetWindowFromId( NULL, textEntryLoginNameID);
- textEntryPassword = TheWindowManager->winGetWindowFromId( NULL, textEntryPasswordID);
- checkBoxRememberPassword = TheWindowManager->winGetWindowFromId( NULL, checkBoxRememberPasswordID);
-
- DEBUG_ASSERTCRASH(buttonBack, ("buttonBack missing!"));
- DEBUG_ASSERTCRASH(buttonLogin, ("buttonLogin missing!"));
- DEBUG_ASSERTCRASH(buttonCreateAccount, ("buttonCreateAccount missing!"));
- DEBUG_ASSERTCRASH(buttonUseAccount, ("buttonUseAccount missing!"));
- DEBUG_ASSERTCRASH(textEntryLoginName, ("textEntryLoginName missing!"));
- TheWindowManager->winSetFocus( textEntryLoginName );
- //TheShell->registerWithAnimateManager(parentWOLLogin, WIN_ANIMATION_SLIDE_TOP, TRUE);
-
-// TheShell->registerWithAnimateManager(buttonTOS, WIN_ANIMATION_SLIDE_LEFT, TRUE);
-// TheShell->registerWithAnimateManager(buttonCreateAccount, WIN_ANIMATION_SLIDE_LEFT, TRUE);
-// TheShell->registerWithAnimateManager(buttonUseAccount, WIN_ANIMATION_SLIDE_LEFT, TRUE);
-// TheShell->registerWithAnimateManager(buttonBack, WIN_ANIMATION_SLIDE_RIGHT, TRUE);
-
- }
-#endif // ALLOW_NON_PROFILED_LOGIN
-
-
-#ifdef ALLOW_NON_PROFILED_LOGIN
- if (GameSpyUseProfiles)
- {
-#endif // ALLOW_NON_PROFILED_LOGIN
- // Read login names from registry...
- GadgetComboBoxReset(comboBoxEmail);
- GadgetTextEntrySetText(textEntryPassword, UnicodeString.TheEmptyString);
-
- // look for cached nicks to add
- AsciiString lastName;
- AsciiString lastEmail;
- Bool markCheckBox = FALSE;
- UserPreferences::const_iterator it = loginPref->find("lastName");
- if (it != loginPref->end())
- {
- lastName = it->second;
- }
- it = loginPref->find("lastEmail");
- if (it != loginPref->end())
- {
- lastEmail = it->second;
- }
-
- // fill in list of Emails, and select the most recent
- AsciiStringList cachedEmails = loginPref->getEmails();
- AsciiStringListIterator eIt = cachedEmails.begin();
- Int selectedPos = -1;
- while (eIt != cachedEmails.end())
- {
- UnicodeString uniEmail;
- uniEmail.translate(*eIt);
- Int pos = GadgetComboBoxAddEntry(comboBoxEmail, uniEmail, GameSpyColor[GSCOLOR_DEFAULT]);
- if (*eIt == lastEmail)
- selectedPos = pos;
-
- ++eIt;
- }
- if (selectedPos >= 0)
- {
- GadgetComboBoxSetSelectedPos(comboBoxEmail, selectedPos);
-
- // fill in the password for the selected email
- UnicodeString pass;
- pass.translate(loginPref->getPasswordForEmail(lastEmail));
- GadgetTextEntrySetText(textEntryPassword, pass);
-
- AsciiString month,day,year;
- loginPref->getDateForEmail(lastEmail, month, day, year);
- pass.translate(month);
- GadgetTextEntrySetText(textEntryMonth, pass);
- pass.translate(day);
- GadgetTextEntrySetText(textEntryDay, pass);
- pass.translate(year);
- GadgetTextEntrySetText(textEntryYear, pass);
-
- markCheckBox = TRUE;
- }
-
- // fill in list of nicks for selected email, selecting the most recent
- GadgetComboBoxReset(comboBoxLoginName);
- AsciiStringList cachedNicks = loginPref->getNicksForEmail(lastEmail);
- AsciiStringListIterator nIt = cachedNicks.begin();
- selectedPos = -1;
- while (nIt != cachedNicks.end())
- {
- UnicodeString uniNick;
- uniNick.translate(*nIt);
- Int pos = GadgetComboBoxAddEntry(comboBoxLoginName, uniNick, GameSpyColor[GSCOLOR_DEFAULT]);
- if (*nIt == lastName)
- selectedPos = pos;
-
- ++nIt;
- }
- if (selectedPos >= 0)
- {
- GadgetComboBoxSetSelectedPos(comboBoxLoginName, selectedPos);
- markCheckBox = TRUE;
- }
- // always start with not storing information
- if( markCheckBox)
- GadgetCheckBoxSetChecked(checkBoxRememberPassword, TRUE);
- else
- GadgetCheckBoxSetChecked(checkBoxRememberPassword, FALSE);
-#ifdef ALLOW_NON_PROFILED_LOGIN
- }
- else
- {
- // Read login names from registry...
- GadgetComboBoxReset(comboBoxLoginName);
- UnicodeString nick;
-
- UserPreferences::const_iterator it = loginPref->find("lastName");
- if (it != loginPref->end())
- {
- nick.translate(it->second);
- }
- else
- {
- char userBuf[32] = "";
- unsigned long bufSize = 32;
- GetUserName(userBuf, &bufSize);
- nick.translate(userBuf);
- }
-
- GadgetTextEntrySetText(textEntryLoginName, nick);
- }
-#endif // ALLOW_NON_PROFILED_LOGIN
-
- EnableLoginControls(TRUE);
-
- // Show Menu
- layout->hide( FALSE );
-
- // Set Keyboard to Main Parent
-
- RaiseGSMessageBox();
-
- OptionPreferences optionPref;
- if (!optionPref.getBool("SawTOS", TRUE))
- {
- TheWindowManager->winSendSystemMsg( parentWOLLogin, GBM_SELECTED,
- (WindowMsgData)buttonTOS, buttonTOSID );
- }
- TheTransitionHandler->setGroup("GameSpyLoginProfileFade");
-
-} // WOLLoginMenuInit
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Login Menu shutdown method */
-//-------------------------------------------------------------------------------------------------
-static Bool loggedInOK = false;
-void WOLLoginMenuShutdown( WindowLayout *layout, void *userData )
-{
- isShuttingDown = true;
- loggedInOK = false;
- TheWindowManager->clearTabList();
-
- // if we are shutting down for an immediate pop, skip the animations
- Bool popImmediate = *(Bool *)userData;
- if( popImmediate )
- {
-
- shutdownComplete( layout );
- return;
-
- } //end if
-
- TheShell->reverseAnimatewindow();
- TheTransitionHandler->reverse("GameSpyLoginProfileFade");
-
-} // WOLLoginMenuShutdown
-
-
-// this is used to check if we've got all the pings
-static void checkLogin( void )
-{
- if (loggedInOK && ThePinger && !ThePinger->arePingsInProgress())
- {
- // save off our ping string, and end those threads
- AsciiString pingStr = ThePinger->getPingString( 1000 );
- DEBUG_LOG(("Ping string is %s\n", pingStr.str()));
- TheGameSpyInfo->setPingString(pingStr);
- //delete ThePinger;
- //ThePinger = NULL;
-
- buttonPushed = true;
- loggedInOK = false; // don't try this again
-
- loginAttemptTime = 0;
-
- // start looking for group rooms
- TheGameSpyInfo->clearGroupRoomList();
-
- SignalUIInteraction(SHELL_SCRIPT_HOOK_GENERALS_ONLINE_LOGIN);
- nextScreen = "Menus/WOLWelcomeMenu.wnd";
- TheShell->pop();
-
- // read in some cached data
- GameSpyMiscPreferences mPref;
- PSPlayerStats localPSStats = GameSpyPSMessageQueueInterface::parsePlayerKVPairs(mPref.getCachedStats().str());
- localPSStats.id = TheGameSpyInfo->getLocalProfileID();
- TheGameSpyInfo->setCachedLocalPlayerStats(localPSStats);
-// TheGameSpyPSMessageQueue->trackPlayerStats(localPSStats);
-
- // and push the info around to other players
-// PSResponse newResp;
-// newResp.responseType = PSResponse::PSRESPONSE_PLAYERSTATS;
-// newResp.player = localPSStats;
-// TheGameSpyPSMessageQueue->addResponse(newResp);
- }
-}
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Login Menu update method */
-//-------------------------------------------------------------------------------------------------
-void WOLLoginMenuUpdate( WindowLayout * layout, void *userData)
-{
-
- // We'll only be successful if we've requested to
- if(isShuttingDown && TheShell->isAnimFinished() && TheTransitionHandler->isFinished())
- shutdownComplete(layout);
-
- if (TheShell->isAnimFinished() && !buttonPushed && TheGameSpyPeerMessageQueue)
- {
- PingResponse pingResp;
- if (ThePinger && ThePinger->getResponse(pingResp))
- {
- checkLogin();
- }
-
- PeerResponse resp;
- if (!loggedInOK && TheGameSpyPeerMessageQueue->getResponse( resp ))
- {
- switch (resp.peerResponseType)
- {
- case PeerResponse::PEERRESPONSE_GROUPROOM:
- {
- GameSpyGroupRoom room;
- room.m_groupID = resp.groupRoom.id;
- room.m_maxWaiting = resp.groupRoom.maxWaiting;
- room.m_name = resp.groupRoomName.c_str();
- room.m_translatedName = UnicodeString(L"TEST");
- room.m_numGames = resp.groupRoom.numGames;
- room.m_numPlaying = resp.groupRoom.numPlaying;
- room.m_numWaiting = resp.groupRoom.numWaiting;
- TheGameSpyInfo->addGroupRoom( room );
- }
- break;
- case PeerResponse::PEERRESPONSE_LOGIN:
- {
- loggedInOK = true;
-
- // fetch our player info
- TheGameSpyInfo->setLocalName( resp.nick.c_str() );
- TheGameSpyInfo->setLocalProfileID( resp.player.profileID );
- TheGameSpyInfo->loadSavedIgnoreList();
- TheGameSpyInfo->setLocalIPs(resp.player.internalIP, resp.player.externalIP);
- TheGameSpyInfo->readAdditionalDisconnects();
- //TheGameSpyInfo->setLocalEmail( resp.player.email );
- //TheGameSpyInfo->setLocalPassword( resp)
-
- GameSpyMiscPreferences miscPref;
- TheGameSpyInfo->setMaxMessagesPerUpdate(miscPref.getMaxMessagesPerUpdate());
- }
- break;
- case PeerResponse::PEERRESPONSE_DISCONNECT:
- {
- loginAttemptTime = 0;
- UnicodeString title, body;
- AsciiString disconMunkee;
- disconMunkee.format("GUI:GSDisconReason%d", resp.discon.reason);
- title = TheGameText->fetch( "GUI:GSErrorTitle" );
- body = TheGameText->fetch( disconMunkee );
- GSMessageBoxOk( title, body );
- EnableLoginControls( TRUE );
-
- // kill & restart the threads
- AsciiString motd = TheGameSpyInfo->getMOTD();
- AsciiString config = TheGameSpyInfo->getConfig();
- DEBUG_LOG(("Tearing down GameSpy from WOLLoginMenuUpdate(PEERRESPONSE_DISCONNECT)\n"));
- TearDownGameSpy();
- SetUpGameSpy( motd.str(), config.str() );
- }
- break;
- }
- }
-
- checkLogin();
- }
-
- if (TheGameSpyInfo && !buttonPushed && loginAttemptTime && (loginAttemptTime + loginTimeoutInMS < timeGetTime()))
- {
- // timed out a login attempt, so say so
- loginAttemptTime = 0;
- UnicodeString title, body;
- AsciiString disconMunkee;
- disconMunkee.format("GUI:GSDisconReason4"); // ("could not connect to server")
- title = TheGameText->fetch( "GUI:GSErrorTitle" );
- body = TheGameText->fetch( disconMunkee );
- GSMessageBoxOk( title, body );
- EnableLoginControls( TRUE );
-
- // kill & restart the threads
- AsciiString motd = TheGameSpyInfo->getMOTD();
- AsciiString config = TheGameSpyInfo->getConfig();
- DEBUG_LOG(("Tearing down GameSpy from WOLLoginMenuUpdate(login timeout)\n"));
- TearDownGameSpy();
- SetUpGameSpy( motd.str(), config.str() );
- }
-
-}// WOLLoginMenuUpdate
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Login Menu input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLLoginMenuInput( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
- UnsignedByte key = mData1;
- UnsignedByte state = mData2;
- if (buttonPushed)
- break;
-
- switch( key )
- {
-
- // ----------------------------------------------------------------------------------------
- case KEY_ESC:
- {
-
- //
- // send a simulated selected event to the parent window of the
- // back/exit button
- //
- if( BitTest( state, KEY_STATE_UP ) )
- {
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)buttonBack, buttonBackID );
-
- } // end if
-
- // don't let key fall through anywhere else
- return MSG_HANDLED;
-
- } // end escape
-
- } // end switch( key )
-
- } // end char
-
- } // end switch( msg )
-
- return MSG_IGNORED;
-}// WOLLoginMenuInput
-
-static Bool isNickOkay(UnicodeString nick)
-{
- static const WideChar * legalIRCChars = L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789[]`_^{|}-";
-
- Int len = nick.getLength();
- if (len == 0)
- return TRUE;
-
- if (len == 1 && nick.getCharAt(0) == L'-')
- return FALSE;
-
- WideChar newChar = nick.getCharAt(len-1);
- if (wcschr(legalIRCChars, newChar) == NULL)
- return FALSE;
-
- return TRUE;
-}
-
-static Bool isAgeOkay(AsciiString &month, AsciiString &day, AsciiString year)
-{
- if(month.isEmpty() || day.isEmpty() || year.isEmpty() || year.getLength() != 4)
- return FALSE;
-
- Int monthInt = atoi(month.str());
- Int dayInt = atoi(day.str());
-
- if(monthInt > 12 || dayInt > 31)
- return FALSE;
- // setup date buffer for local region date format
- month.format("%02.2d",monthInt);
- day.format("%02.2d",dayInt);
-
- // test the year first
- #define DATE_BUFFER_SIZE 256
- char dateBuffer[ DATE_BUFFER_SIZE ];
- GetDateFormat( LOCALE_SYSTEM_DEFAULT,
- 0, NULL,
- "yyyy",
- dateBuffer, DATE_BUFFER_SIZE );
- Int sysVal = atoi(dateBuffer);
- Int userVal = atoi(year.str());
- if(sysVal - userVal >= 14)
- return TRUE;
- else if( sysVal - userVal <= 12)
- return FALSE;
-
- GetDateFormat( LOCALE_SYSTEM_DEFAULT,
- 0, NULL,
- "MM",
- dateBuffer, DATE_BUFFER_SIZE );
- sysVal = atoi(dateBuffer);
- userVal = atoi(month.str());
- if(sysVal - userVal >0 )
- return TRUE;
- else if( sysVal -userVal < 0 )
- return FALSE;
-// month.format("%02.2d",userVal);
- GetDateFormat( LOCALE_SYSTEM_DEFAULT,
- 0, NULL,
- "dd",
- dateBuffer, DATE_BUFFER_SIZE );
- sysVal = atoi(dateBuffer);
- userVal = atoi(day.str());
- if(sysVal - userVal< 0)
- return FALSE;
-// day.format("%02.2d",userVal);
- return TRUE;
-}
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Login Menu window system callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLLoginMenuSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- UnicodeString txtInput;
-
- switch( msg )
- {
-
-
- case GWM_CREATE:
- {
- break;
- } // case GWM_DESTROY:
-
- case GWM_DESTROY:
- {
- break;
- } // case GWM_DESTROY:
-
- case GWM_INPUT_FOCUS:
- {
- // if we're givin the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
-
- return MSG_HANDLED;
- }//case GWM_INPUT_FOCUS:
-
- // someone typed in a combo box. Clear password (or fill it in if the typed name matches a known login name)
- case GCM_UPDATE_TEXT:
- {
- UnicodeString uNick = GadgetComboBoxGetText(comboBoxLoginName);
- UnicodeString uEmail = GadgetComboBoxGetText(comboBoxEmail);
- AsciiString nick, email;
- nick.translate(uNick);
- email.translate(uEmail);
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- UnicodeString trimmedNick = uNick, trimmedEmail = uEmail;
- trimmedNick.trim();
- trimmedEmail.trim();
- if (!trimmedNick.isEmpty())
- {
- if (trimmedNick.getCharAt(trimmedNick.getLength()-1) == L'\\')
- trimmedNick.removeLastChar();
- if (trimmedNick.getCharAt(trimmedNick.getLength()-1) == L'/')
- trimmedNick.removeLastChar();
- }
- if (!trimmedEmail.isEmpty())
- {
- if (trimmedEmail.getCharAt(trimmedEmail.getLength()-1) == L'\\')
- trimmedEmail.removeLastChar();
- if (trimmedEmail.getCharAt(trimmedEmail.getLength()-1) == L'/')
- trimmedEmail.removeLastChar();
- }
- if (trimmedEmail.getLength() != uEmail.getLength())
- {
- // we just trimmed a space. set the text back and bail
- GadgetComboBoxSetText(comboBoxEmail, trimmedEmail);
- break;
- }
- if (trimmedNick.getLength() != nick.getLength())
- {
- // we just trimmed a space. set the text back and bail
- GadgetComboBoxSetText(comboBoxLoginName, trimmedNick);
- break;
- }
-
- if (controlID == comboBoxEmailID)
- {
- // email changed. look up password, and choose new login names
-
- // fill in the password for the selected email
- UnicodeString pass;
- pass.translate(loginPref->getPasswordForEmail(email));
- GadgetTextEntrySetText(textEntryPassword, pass);
-
- // fill in list of nicks for selected email, selecting the first
- AsciiStringList cachedNicks = loginPref->getNicksForEmail(email);
- AsciiStringListIterator nIt = cachedNicks.begin();
- Int selectedPos = -1;
- GadgetComboBoxReset(comboBoxLoginName);
- while (nIt != cachedNicks.end())
- {
- UnicodeString uniNick;
- uniNick.translate(*nIt);
- GadgetComboBoxAddEntry(comboBoxLoginName, uniNick, GameSpyColor[GSCOLOR_DEFAULT]);
- selectedPos = 0;
- ++nIt;
- }
- if (selectedPos >= 0)
- {
- GadgetComboBoxSetSelectedPos(comboBoxLoginName, selectedPos);
- GadgetCheckBoxSetChecked(checkBoxRememberPassword, true);
- AsciiString month,day,year;
- loginPref->getDateForEmail(email, month, day, year);
- pass.translate(month);
- GadgetTextEntrySetText(textEntryMonth, pass);
- pass.translate(day);
- GadgetTextEntrySetText(textEntryDay, pass);
- pass.translate(year);
- GadgetTextEntrySetText(textEntryYear, pass);
-
- }
- else
- {
- GadgetCheckBoxSetChecked(checkBoxRememberPassword, false);
- GadgetTextEntrySetText(textEntryMonth, UnicodeString::TheEmptyString);
- GadgetTextEntrySetText(textEntryDay, UnicodeString::TheEmptyString);
- GadgetTextEntrySetText(textEntryYear, UnicodeString::TheEmptyString);
-
- }
- }
- else if (controlID == comboBoxLoginNameID)
- {
- // they typed a new login name. Email & pass shouldn't change
- }
-
- break;
- }
-
- case GCM_SELECTED:
- {
- if (buttonPushed)
- break;
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if (controlID == comboBoxEmailID)
- {
- // email changed. look up password, and choose new login names
- UnicodeString uEmail = GadgetComboBoxGetText(comboBoxEmail);
- AsciiString email;
- email.translate(uEmail);
-
- // fill in the password for the selected email
- UnicodeString pass;
- pass.translate(loginPref->getPasswordForEmail(email));
- GadgetTextEntrySetText(textEntryPassword, pass);
-
- // fill in list of nicks for selected email, selecting the first
- AsciiStringList cachedNicks = loginPref->getNicksForEmail(email);
- AsciiStringListIterator nIt = cachedNicks.begin();
- Int selectedPos = -1;
- GadgetComboBoxReset(comboBoxLoginName);
- while (nIt != cachedNicks.end())
- {
- UnicodeString uniNick;
- uniNick.translate(*nIt);
- GadgetComboBoxAddEntry(comboBoxLoginName, uniNick, GameSpyColor[GSCOLOR_DEFAULT]);
- selectedPos = 0;
- ++nIt;
- }
- if (selectedPos >= 0)
- {
- GadgetComboBoxSetSelectedPos(comboBoxLoginName, selectedPos);
- GadgetCheckBoxSetChecked(checkBoxRememberPassword, true);
- AsciiString month,day,year;
- loginPref->getDateForEmail(email, month, day, year);
- pass.translate(month);
- GadgetTextEntrySetText(textEntryMonth, pass);
- pass.translate(day);
- GadgetTextEntrySetText(textEntryDay, pass);
- pass.translate(year);
- GadgetTextEntrySetText(textEntryYear, pass);
-
- }
- else
- {
- GadgetCheckBoxSetChecked(checkBoxRememberPassword, false);
- GadgetTextEntrySetText(textEntryMonth, UnicodeString::TheEmptyString);
- GadgetTextEntrySetText(textEntryDay, UnicodeString::TheEmptyString);
- GadgetTextEntrySetText(textEntryYear, UnicodeString::TheEmptyString);
- }
-
- }
- else if (controlID == comboBoxLoginNameID)
- {
- // they typed a new login name. Email & pass shouldn't change
- }
- break;
- }
-
- case GBM_SELECTED:
- {
- if (buttonPushed)
- break;
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- // If we back out, just bail - we haven't gotten far enough to need to log out
- if ( controlID == buttonBackID )
- {
- buttonPushed = true;
- TearDownGameSpy();
- TheShell->pop();
- } //if ( controlID == buttonBack )
-#ifdef ALLOW_NON_PROFILED_LOGIN
- else if ( controlID == buttonUseAccountID )
- {
- buttonPushed = true;
- nextScreen = "Menus/GameSpyLoginProfile.wnd";
- TheShell->pop();
- //TheShell->push( "Menus/GameSpyLoginProfile.wnd" );
- } //if ( controlID == buttonUseAccount )
- else if ( controlID == buttonDontUseAccountID )
- {
- buttonPushed = true;
- nextScreen = "Menus/GameSpyLoginQuick.wnd";
- TheShell->pop();
- //TheShell->push( "Menus/GameSpyLoginQuick.wnd" );
- } //if ( controlID == buttonDontUseAccount )
-#endif // ALLOW_NON_PROFILED_LOGIN
- else if ( controlID == buttonCreateAccountID )
- {
-#ifdef ALLOW_NON_PROFILED_LOGIN
- if (GameSpyUseProfiles)
- {
-#endif // ALLOW_NON_PROFILED_LOGIN
- // actually attempt to create an account based on info entered
- AsciiString month, day, year;
- month.translate( GadgetTextEntryGetText(textEntryMonth) );
- day.translate( GadgetTextEntryGetText(textEntryDay) );
- year.translate( GadgetTextEntryGetText(textEntryYear) );
-
- if(!isAgeOkay(month, day, year))
- {
- GSMessageBoxOk(TheGameText->fetch("GUI:AgeFailedTitle"), TheGameText->fetch("GUI:AgeFailed"));
- break;
- }
-
- AsciiString login, password, email;
- email.translate( GadgetComboBoxGetText(comboBoxEmail) );
- login.translate( GadgetComboBoxGetText(comboBoxLoginName) );
- password.translate( GadgetTextEntryGetText(textEntryPassword) );
-
- if ( !email.isEmpty() && !login.isEmpty() && !password.isEmpty() )
- {
- loginAttemptTime = timeGetTime();
- BuddyRequest req;
- req.buddyRequestType = BuddyRequest::BUDDYREQUEST_LOGINNEW;
- strcpy(req.arg.login.nick, login.str());
- strcpy(req.arg.login.email, email.str());
- strcpy(req.arg.login.password, password.str());
- req.arg.login.hasFirewall = TRUE;
-
- TheGameSpyInfo->setLocalBaseName( login );
- //TheGameSpyInfo->setLocalProfileID( resp.player.profileID );
- TheGameSpyInfo->setLocalEmail( email );
- TheGameSpyInfo->setLocalPassword( password );
- DEBUG_LOG(("before create: TheGameSpyInfo->stuff(%s/%s/%s)\n", TheGameSpyInfo->getLocalBaseName().str(), TheGameSpyInfo->getLocalEmail().str(), TheGameSpyInfo->getLocalPassword().str()));
-
- TheGameSpyBuddyMessageQueue->addRequest( req );
- if(checkBoxRememberPassword && GadgetCheckBoxIsChecked(checkBoxRememberPassword))
- {
- (*loginPref)["lastName"] = login;
- (*loginPref)["lastEmail"] = email;
- (*loginPref)["useProfiles"] = "yes";
- AsciiString date;
- date = month;
- date.concat(day);
- date.concat(year);
-
- loginPref->addLogin(email, login, password, date);
- }
-
- EnableLoginControls( FALSE );
-
- // fire off some pings
- startPings();
- }
- else
- {
- // user didn't fill in all info. prompt him.
- if(email.isEmpty() && login.isEmpty() && password.isEmpty())
- GSMessageBoxOk(TheGameText->fetch("GUI:Error"), TheGameText->fetch("GUI:GSNoLoginInfoAll"));
- else if( email.isEmpty() && login.isEmpty())
- GSMessageBoxOk(TheGameText->fetch("GUI:Error"), TheGameText->fetch("GUI:GSNoLoginInfoEmailNickname"));
- else if( email.isEmpty() && password.isEmpty())
- GSMessageBoxOk(TheGameText->fetch("GUI:Error"), TheGameText->fetch("GUI:GSNoLoginInfoEmailPassword"));
- else if( login.isEmpty() && password.isEmpty())
- GSMessageBoxOk(TheGameText->fetch("GUI:Error"), TheGameText->fetch("GUI:GSNoLoginInfoNicknamePassword"));
- else if( email.isEmpty())
- GSMessageBoxOk(TheGameText->fetch("GUI:Error"), TheGameText->fetch("GUI:GSNoLoginInfoEmail"));
- else if( password.isEmpty())
- GSMessageBoxOk(TheGameText->fetch("GUI:Error"), TheGameText->fetch("GUI:GSNoLoginInfoPassword"));
- else if( login.isEmpty() )
- GSMessageBoxOk(TheGameText->fetch("GUI:Error"), TheGameText->fetch("GUI:GSNoLoginInfoNickname"));
- else
- GSMessageBoxOk(TheGameText->fetch("GUI:Error"), TheGameText->fetch("GUI:GSNoLoginInfoAll"));
- }
-#ifdef ALLOW_NON_PROFILED_LOGIN
- }
- else
- {
- // not the profile screen - switch to it
- buttonPushed = TRUE;
- nextScreen = "Menus/GameSpyLoginProfile.wnd";
- TheShell->pop();
- }
-#endif // ALLOW_NON_PROFILED_LOGIN
- } //if ( controlID == buttonCreateAccount )
- else if ( controlID == buttonLoginID )
- {
- AsciiString login, password, email;
-
-#ifdef ALLOW_NON_PROFILED_LOGIN
- if (GameSpyUseProfiles)
- {
-#endif // ALLOW_NON_PROFILED_LOGIN
- AsciiString month, day, year;
- month.translate( GadgetTextEntryGetText(textEntryMonth) );
- day.translate( GadgetTextEntryGetText(textEntryDay) );
- year.translate( GadgetTextEntryGetText(textEntryYear) );
-
- if(!isAgeOkay(month, day, year))
- {
- GSMessageBoxOk(TheGameText->fetch("GUI:AgeFailedTitle"), TheGameText->fetch("GUI:AgeFailed"));
- break;
- }
-
- email.translate( GadgetComboBoxGetText(comboBoxEmail) );
- login.translate( GadgetComboBoxGetText(comboBoxLoginName) );
- password.translate( GadgetTextEntryGetText(textEntryPassword) );
-
- if ( !email.isEmpty() && !login.isEmpty() && !password.isEmpty() )
- {
- loginAttemptTime = timeGetTime();
- BuddyRequest req;
- req.buddyRequestType = BuddyRequest::BUDDYREQUEST_LOGIN;
- strcpy(req.arg.login.nick, login.str());
- strcpy(req.arg.login.email, email.str());
- strcpy(req.arg.login.password, password.str());
- req.arg.login.hasFirewall = true;
-
- TheGameSpyInfo->setLocalBaseName( login );
- //TheGameSpyInfo->setLocalProfileID( resp.player.profileID );
- TheGameSpyInfo->setLocalEmail( email );
- TheGameSpyInfo->setLocalPassword( password );
- DEBUG_LOG(("before login: TheGameSpyInfo->stuff(%s/%s/%s)\n", TheGameSpyInfo->getLocalBaseName().str(), TheGameSpyInfo->getLocalEmail().str(), TheGameSpyInfo->getLocalPassword().str()));
-
- TheGameSpyBuddyMessageQueue->addRequest( req );
- if(checkBoxRememberPassword && GadgetCheckBoxIsChecked(checkBoxRememberPassword))
- {
- (*loginPref)["lastName"] = login;
- (*loginPref)["lastEmail"] = email;
- (*loginPref)["useProfiles"] = "yes";
- AsciiString date;
- date = month;
- date.concat(day);
- date.concat(year);
-
- loginPref->addLogin(email, login, password,date);
- }
- else
- {
- loginPref->forgetLogin(email);
- }
- EnableLoginControls( FALSE );
-
- // fire off some pings
- startPings();
- }
- else
- {
- // user didn't fill in all info. prompt him.
- if(email.isEmpty() && login.isEmpty() && password.isEmpty())
- GSMessageBoxOk(TheGameText->fetch("GUI:GSErrorTitle"), TheGameText->fetch("GUI:GSNoLoginInfoAll"));
- else if( email.isEmpty() && login.isEmpty())
- GSMessageBoxOk(TheGameText->fetch("GUI:GSErrorTitle"), TheGameText->fetch("GUI:GSNoLoginInfoEmailNickname"));
- else if( email.isEmpty() && password.isEmpty())
- GSMessageBoxOk(TheGameText->fetch("GUI:GSErrorTitle"), TheGameText->fetch("GUI:GSNoLoginInfoEmailPassword"));
- else if( login.isEmpty() && password.isEmpty())
- GSMessageBoxOk(TheGameText->fetch("GUI:GSErrorTitle"), TheGameText->fetch("GUI:GSNoLoginInfoNicknamePassword"));
- else if( email.isEmpty())
- GSMessageBoxOk(TheGameText->fetch("GUI:GSErrorTitle"), TheGameText->fetch("GUI:GSNoLoginInfoEmail"));
- else if( password.isEmpty())
- GSMessageBoxOk(TheGameText->fetch("GUI:GSErrorTitle"), TheGameText->fetch("GUI:GSNoLoginInfoPassword"));
- else if( login.isEmpty() )
- GSMessageBoxOk(TheGameText->fetch("GUI:GSErrorTitle"), TheGameText->fetch("GUI:GSNoLoginInfoNickname"));
- else
- GSMessageBoxOk(TheGameText->fetch("GUI:GSErrorTitle"), TheGameText->fetch("GUI:GSNoLoginInfoAll"));
- }
-#ifdef ALLOW_NON_PROFILED_LOGIN
- }
- else
- {
- login.translate( GadgetTextEntryGetText(textEntryLoginName) );
-
- if ( !login.isEmpty() )
- {
- loginAttemptTime = timeGetTime();
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_LOGIN;
- req.nick = login.str();
- req.login.profileID = 0;
- TheGameSpyPeerMessageQueue->addRequest( req );
-
- (*loginPref)["lastName"] = login;
- loginPref->erase("lastEmail");
- (*loginPref)["useProfiles"] = "no";
- EnableLoginControls( FALSE );
-
- // fire off some pings
- startPings();
- }
- }
-#endif // ALLOW_NON_PROFILED_LOGIN
-
- } //if ( controlID == buttonLogin )
- else if ( controlID == buttonTOSID )
- {
- parentTOS->winHide(FALSE);
-
- if (1)
- {
- // Okay, no web browser. This means we're looking at a UTF-8 text file.
- GadgetListBoxReset(listboxTOS);
- AsciiString fileName;
- fileName.format("Data\\%s\\TOS.txt", GetRegistryLanguage().str());
- File *theFile = TheFileSystem->openFile(fileName.str(), File::READ);
- if (theFile)
- {
- Int size = theFile->size();
-
- char *fileBuf = new char[size];
- Color tosColor = GameMakeColor(255, 255, 255, 255);
-
- Int bytesRead = theFile->read(fileBuf, size);
- if (bytesRead == size && size > 2)
- {
- fileBuf[size-1] = 0; // just to be safe
- AsciiString asciiBuf = fileBuf+2;
- AsciiString asciiLine;
- while (asciiBuf.nextToken(&asciiLine, "\r\n"))
- {
- UnicodeString uniLine;
- uniLine = UnicodeString(MultiByteToWideCharSingleLine(asciiLine.str()).c_str());
- int len = uniLine.getLength();
- for (int index = len-1; index >= 0; index--)
- {
- if (iswspace(uniLine.getCharAt(index)))
- {
- uniLine.removeLastChar();
- }
- else
- {
- break;
- }
- }
- //uniLine.trim();
- DEBUG_LOG(("adding TOS line: [%ls]\n", uniLine.str()));
- GadgetListBoxAddEntryText(listboxTOS, uniLine, tosColor, -1);
- }
-
- }
-
- delete fileBuf;
- fileBuf = NULL;
-
- theFile->close();
- theFile = NULL;
- }
- }
- EnableLoginControls( FALSE );
- buttonBack->winEnable(FALSE);
-
- }
- else if ( controlID == buttonTOSOKID )
- {
- EnableLoginControls( TRUE );
-
- parentTOS->winHide(TRUE);
-
- OptionPreferences optionPref;
- optionPref["SawTOS"] = "yes";
- optionPref.write();
- buttonBack->winEnable(TRUE);
- }
- break;
- }// case GBM_SELECTED:
-
- case GEM_EDIT_DONE:
- {
- break;
- }
- /*
- case GEM_UPDATE_TEXT:
- {
- if (buttonPushed)
- break;
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if ( controlID == textEntryLoginNameID )
- {
- UnicodeString munkee = GadgetTextEntryGetText( textEntryLoginName );
- if ( !isNickOkay( munkee ) )
- {
- munkee.removeLastChar();
- GadgetTextEntrySetText( textEntryLoginName, munkee );
- }
- }// if ( controlID == textEntryLoginNameID )
- break;
- }//case GEM_UPDATE_TEXT:
- */
- default:
- return MSG_IGNORED;
-
- }//Switch
-
- return MSG_HANDLED;
-}// WOLLoginMenuSystem
-
-
diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLMapSelectMenu.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLMapSelectMenu.cpp
deleted file mode 100644
index 7e140bbace7..00000000000
--- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLMapSelectMenu.cpp
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: WOLMapSelectMenu.cpp ////////////////////////////////////////////////////////////////////////
-// Author: Matt Campbell, December 2001
-// Description: MapSelect menu window callbacks
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/CustomMatchPreferences.h"
-#include "Common/GameEngine.h"
-#include "Common/MessageStream.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/GadgetRadioButton.h"
-#include "GameClient/Shell.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/GadgetListBox.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpyOverlay.h"
-#include "GameClient/MapUtil.h"
-#include "GameNetwork/GUIUtil.h"
-
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-static NameKeyType buttonBack = NAMEKEY_INVALID;
-static NameKeyType buttonOK = NAMEKEY_INVALID;
-static NameKeyType listboxMap = NAMEKEY_INVALID;
-static GameWindow *parent = NULL;
-static Bool raiseMessageBoxes = FALSE;
-static GameWindow *winMapPreview = NULL;
-static NameKeyType winMapPreviewID = NAMEKEY_INVALID;
-
-static NameKeyType radioButtonSystemMapsID = NAMEKEY_INVALID;
-static NameKeyType radioButtonUserMapsID = NAMEKEY_INVALID;
-
-extern WindowLayout *WOLMapSelectLayout; ///< Map selection overlay
-static GameWindow *mapList = NULL;
-
-static GameWindow *buttonMapStartPosition[MAX_SLOTS] = {NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL };
-static NameKeyType buttonMapStartPositionID[MAX_SLOTS] = { NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID,
- NAMEKEY_INVALID,NAMEKEY_INVALID };
-
-static GameWindow *winMapWindow = NULL;
-
-static void NullifyControls(void)
-{
- parent = NULL;
- winMapPreview = NULL;
- mapList = NULL;
- for (Int i=0; iwinGetWindowFromId( NULL, TheNameKeyGenerator->nameToKey("GameSpyGameOptionsMenu.wnd:ButtonBack") );
- if(win)
- win->winEnable( show );
-}
-
-// PUBLIC FUNCTIONS ///////////////////////////////////////////////////////////////////////////////
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the MapSelect menu */
-//-------------------------------------------------------------------------------------------------
-void WOLMapSelectMenuInit( WindowLayout *layout, void *userData )
-{
-
- // set keyboard focus to main parent
- AsciiString parentName( "WOLMapSelectMenu.wnd:WOLMapSelectMenuParent" );
- NameKeyType parentID = TheNameKeyGenerator->nameToKey( parentName );
- parent = TheWindowManager->winGetWindowFromId( NULL, parentID );
-
- TheWindowManager->winSetFocus( parent );
-
- CustomMatchPreferences pref;
- Bool usesSystemMapDir = pref.usesSystemMapDir();
- winMapPreviewID = TheNameKeyGenerator->nameToKey( AsciiString("WOLMapSelectMenu.wnd:WinMapPreview") );
- winMapPreview = TheWindowManager->winGetWindowFromId(parent, winMapPreviewID);
-
- const MapMetaData *mmd = TheMapCache->findMap(TheGameSpyGame->getMap());
- if (mmd)
- {
- usesSystemMapDir = mmd->m_isOfficial;
- }
-
- //if stats are enabled, only official maps can be used
- if( TheGameSpyInfo->getCurrentStagingRoom()->getUseStats() )
- usesSystemMapDir = true;
-
- buttonBack = TheNameKeyGenerator->nameToKey( AsciiString("WOLMapSelectMenu.wnd:ButtonBack") );
- buttonOK = TheNameKeyGenerator->nameToKey( AsciiString("WOLMapSelectMenu.wnd:ButtonOK") );
- listboxMap = TheNameKeyGenerator->nameToKey( AsciiString("WOLMapSelectMenu.wnd:ListboxMap") );
- radioButtonSystemMapsID = TheNameKeyGenerator->nameToKey( "WOLMapSelectMenu.wnd:RadioButtonSystemMaps" );
- radioButtonUserMapsID = TheNameKeyGenerator->nameToKey( "WOLMapSelectMenu.wnd:RadioButtonUserMaps" );
- winMapWindow = TheWindowManager->winGetWindowFromId( parent, listboxMap );
-
- GameWindow *radioButtonSystemMaps = TheWindowManager->winGetWindowFromId( parent, radioButtonSystemMapsID );
- GameWindow *radioButtonUserMaps = TheWindowManager->winGetWindowFromId( parent, radioButtonUserMapsID );
- if( TheGameSpyInfo->getCurrentStagingRoom()->getUseStats() )
- { //disable unofficial maps if stats are being recorded
- GadgetRadioSetSelection( radioButtonSystemMaps, FALSE );
- radioButtonUserMaps->winEnable( FALSE );
- }
- else if (usesSystemMapDir)
- GadgetRadioSetSelection( radioButtonSystemMaps, FALSE );
- else
- GadgetRadioSetSelection( radioButtonUserMaps, FALSE );
-
- AsciiString tmpString;
- for (Int i = 0; i < MAX_SLOTS; i++)
- {
- tmpString.format("WOLMapSelectMenu.wnd:ButtonMapStartPosition%d", i);
- buttonMapStartPositionID[i] = TheNameKeyGenerator->nameToKey( tmpString );
- buttonMapStartPosition[i] = TheWindowManager->winGetWindowFromId( winMapPreview, buttonMapStartPositionID[i] );
- DEBUG_ASSERTCRASH(buttonMapStartPosition[i], ("Could not find the ButtonMapStartPosition[%d]",i ));
- buttonMapStartPosition[i]->winHide(TRUE);
- buttonMapStartPosition[i]->winEnable(FALSE);
- }
-
- raiseMessageBoxes = TRUE;
- showGameSpyGameOptionsUnderlyingGUIElements( FALSE );
-
- // get the listbox window
- AsciiString listString( "WOLMapSelectMenu.wnd:ListboxMap" );
- NameKeyType mapListID = TheNameKeyGenerator->nameToKey( listString );
- mapList = TheWindowManager->winGetWindowFromId( parent, mapListID );
- if( mapList )
- {
- if (TheMapCache)
- TheMapCache->updateCache();
- populateMapListbox( mapList, usesSystemMapDir, TRUE, TheGameSpyGame->getMap() );
- }
-
-} // end WOLMapSelectMenuInit
-
-//-------------------------------------------------------------------------------------------------
-/** MapSelect menu shutdown method */
-//-------------------------------------------------------------------------------------------------
-void WOLMapSelectMenuShutdown( WindowLayout *layout, void *userData )
-{
- NullifyControls();
-
- // hide menu
- layout->hide( TRUE );
-
- // our shutdown is complete
- TheShell->shutdownComplete( layout );
-
-} // end WOLMapSelectMenuShutdown
-
-//-------------------------------------------------------------------------------------------------
-/** MapSelect menu update method */
-//-------------------------------------------------------------------------------------------------
-void WOLMapSelectMenuUpdate( WindowLayout *layout, void *userData )
-{
-
- if (raiseMessageBoxes)
- {
- RaiseGSMessageBox();
- raiseMessageBoxes = false;
- }
-
- // No update because the game setup screen is up at the same
- // time and it does the update for us...
-} // end WOLMapSelectMenuUpdate
-
-//-------------------------------------------------------------------------------------------------
-/** Map select menu input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLMapSelectMenuInput( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
-
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
- UnsignedByte key = mData1;
- UnsignedByte state = mData2;
-
- switch( key )
- {
-
- // ----------------------------------------------------------------------------------------
- case KEY_ESC:
- {
-
- //
- // send a simulated selected event to the parent window of the
- // back/exit button
- //
- if( BitTest( state, KEY_STATE_UP ) )
- {
- AsciiString buttonName( "WOLMapSelectMenu.wnd:ButtonBack" );
- NameKeyType buttonID = TheNameKeyGenerator->nameToKey( buttonName );
- GameWindow *button = TheWindowManager->winGetWindowFromId( window, buttonID );
-
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)button, buttonID );
-
- } // end if
-
- // don't let key fall through anywhere else
- return MSG_HANDLED;
-
- } // end escape
-
- } // end switch( key )
-
- } // end char
-
- } // end switch( msg )
-
- return MSG_IGNORED;
-
-} // end WOLMapSelectMenuInput
-void WOLPositionStartSpots( void );
-
-//-------------------------------------------------------------------------------------------------
-/** MapSelect menu window system callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLMapSelectMenuSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
-
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CREATE:
- {
- break;
-
- } // end create
-
- //---------------------------------------------------------------------------------------------
- case GWM_DESTROY:
- {
- NullifyControls();
- break;
-
- } // end case
-
- // --------------------------------------------------------------------------------------------
- case GWM_INPUT_FOCUS:
- {
-
- // if we're givin the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
-
- return MSG_HANDLED;
-
- } // end input
-
- //---------------------------------------------------------------------------------------------
- case GLM_DOUBLE_CLICKED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- if( controlID == listboxMap )
- {
- int rowSelected = mData2;
-
- if (rowSelected >= 0)
- {
- GadgetListBoxSetSelected( control, rowSelected );
- GameWindow *button = TheWindowManager->winGetWindowFromId( window, buttonOK );
-
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)button, buttonOK );
- }
- }
- break;
- }
- //---------------------------------------------------------------------------------------------
-
-
-
- case GLM_SELECTED:
- {
-
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- if( controlID == listboxMap )
- {
- int rowSelected = mData2;
- if( rowSelected < 0 )
- {
- positionStartSpots( AsciiString::TheEmptyString, buttonMapStartPosition, winMapPreview);
-// winMapPreview->winClearStatus(WIN_STATUS_IMAGE);
- break;
- }
- winMapPreview->winSetStatus(WIN_STATUS_IMAGE);
- UnicodeString map;
- // get text of the map to load
- map = GadgetListBoxGetText( winMapWindow, rowSelected, 0 );
-
- // set the map name in the global data map name
- AsciiString asciiMap;
- const char *mapFname = (const char *)GadgetListBoxGetItemData( winMapWindow, rowSelected );
- DEBUG_ASSERTCRASH(mapFname, ("No map item data"));
- if (mapFname)
- asciiMap = mapFname;
- else
- asciiMap.translate( map );
- asciiMap.toLower();
- Image *image = getMapPreviewImage(asciiMap);
- winMapPreview->winSetUserData((void *)TheMapCache->findMap(asciiMap));
- if(image)
- {
- winMapPreview->winSetEnabledImage(0, image);
- }
- else
- {
- winMapPreview->winClearStatus(WIN_STATUS_IMAGE);
- }
- positionStartSpots( asciiMap, buttonMapStartPosition, winMapPreview);
- }
- break;
- }
- //---------------------------------------------------------------------------------------------
- case GBM_SELECTED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if( controlID == buttonBack )
- {
- showGameSpyGameOptionsUnderlyingGUIElements( TRUE );
-
- WOLMapSelectLayout->destroyWindows();
- WOLMapSelectLayout->deleteInstance();
- WOLMapSelectLayout = NULL;
- WOLPositionStartSpots();
- } // end if
- else if ( controlID == radioButtonSystemMapsID )
- {
- if (TheMapCache)
- TheMapCache->updateCache();
- populateMapListbox( mapList, TRUE, TRUE, TheGameSpyGame->getMap() );
- CustomMatchPreferences pref;
- pref.setUsesSystemMapDir(TRUE);
- pref.write();
- }
- else if ( controlID == radioButtonUserMapsID )
- {
- if (TheMapCache)
- TheMapCache->updateCache();
- populateMapListbox( mapList, FALSE, TRUE, TheGameSpyGame->getMap() );
- CustomMatchPreferences pref;
- pref.setUsesSystemMapDir(FALSE);
- pref.write();
- }
- else if( controlID == buttonOK )
- {
- Int selected;
- UnicodeString map;
-
- // get the selected index
- GadgetListBoxGetSelected( winMapWindow, &selected );
-
- if( selected != -1 )
- {
-
- // get text of the map to load
- map = GadgetListBoxGetText( winMapWindow, selected, 0 );
-
-
- // set the map name in the global data map name
- AsciiString asciiMap;
- const char *mapFname = (const char *)GadgetListBoxGetItemData( winMapWindow, selected );
- DEBUG_ASSERTCRASH(mapFname, ("No map item data"));
- if (mapFname)
- asciiMap = mapFname;
- else
- asciiMap.translate( map );
- TheGameSpyGame->setMap(asciiMap);
- asciiMap.toLower();
- std::map::iterator it = TheMapCache->find(asciiMap);
- if (it != TheMapCache->end())
- {
- TheGameSpyGame->getGameSpySlot(0)->setMapAvailability(TRUE);
- TheGameSpyGame->setMapCRC( it->second.m_CRC );
- TheGameSpyGame->setMapSize( it->second.m_filesize );
- }
-
- TheGameSpyGame->adjustSlotsForMap(); // BGC- adjust the slots for the new map.
- TheGameSpyGame->resetAccepted();
- TheGameSpyGame->resetStartSpots();
- TheGameSpyInfo->setGameOptions();
-
- WOLDisplaySlotList();
- WOLDisplayGameOptions();
-
- WOLMapSelectLayout->destroyWindows();
- WOLMapSelectLayout->deleteInstance();
- WOLMapSelectLayout = NULL;
-
- showGameSpyGameOptionsUnderlyingGUIElements( TRUE );
-
- WOLPositionStartSpots();
-
- } // end if
-
- } // end else if
-
- break;
-
- } // end selected
-
- default:
- return MSG_IGNORED;
-
- } // end switch
-
- return MSG_HANDLED;
-
-} // end WOLMapSelectMenuSystem
diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLMessageWindow.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLMessageWindow.cpp
deleted file mode 100644
index 5f93a32d7cd..00000000000
--- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLMessageWindow.cpp
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////////////
-// FILE: WOLMessageWindow.cpp
-// Author: Chris Huybregts, November 2001
-// Description: Lan Lobby Menu
-///////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/GameEngine.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/Shell.h"
-#include "GameClient/KeyDefs.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/GadgetListBox.h"
-#include "GameClient/GadgetTextEntry.h"
-#include "GameNetwork/IPEnumeration.h"
-//#include "GameNetwork/WOL.h"
-
-
-
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-// window ids ------------------------------------------------------------------------------
-static NameKeyType parentWOLMessageWindowID = NAMEKEY_INVALID;
-static NameKeyType buttonCancelID = NAMEKEY_INVALID;
-
-// Window Pointers ------------------------------------------------------------------------
-static GameWindow *parentWOLMessageWindow = NULL;
-static GameWindow *buttonCancel = NULL;
-
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the WOLMessage Window */
-//-------------------------------------------------------------------------------------------------
-void WOLMessageWindowInit( WindowLayout *layout, void *userData )
-{
- parentWOLMessageWindowID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLMessageWindow.wnd:WOLMessageWindowParent" ) );
- buttonCancelID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLMessageWindow.wnd:ButtonCancel" ) );
- parentWOLMessageWindow = TheWindowManager->winGetWindowFromId( NULL, parentWOLMessageWindowID );
- buttonCancel = TheWindowManager->winGetWindowFromId( NULL, buttonCancelID);
-
-
- // Show Menu
- layout->hide( FALSE );
-
- // Set Keyboard to Main Parent
- TheWindowManager->winSetFocus( parentWOLMessageWindow );
-
-} // WOLMessageWindowInit
-
-//-------------------------------------------------------------------------------------------------
-/** WOLMessage Window shutdown method */
-//-------------------------------------------------------------------------------------------------
-void WOLMessageWindowShutdown( WindowLayout *layout, void *userData )
-{
-
- // hide menu
- layout->hide( TRUE );
-
- // our shutdown is complete
- TheShell->shutdownComplete( layout );
-} // WOLMessageWindowShutdown
-
-
-//-------------------------------------------------------------------------------------------------
-/** WOLMessage Window update method */
-//-------------------------------------------------------------------------------------------------
-void WOLMessageWindowUpdate( WindowLayout * layout, void *userData)
-{
- /*
- if (WOL::TheWOL)
- WOL::TheWOL->update();
- */
-
-}// WOLMessageWindowUpdate
-
-//-------------------------------------------------------------------------------------------------
-/** WOLMessage Window input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLMessageWindowInput( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
- UnsignedByte key = mData1;
- UnsignedByte state = mData2;
-
- switch( key )
- {
-
- // ----------------------------------------------------------------------------------------
- case KEY_ESC:
- {
-
- //
- // send a simulated selected event to the parent window of the
- // back/exit button
- //
- if( BitTest( state, KEY_STATE_UP ) )
- {
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)buttonCancel, buttonCancelID );
-
- } // end if
-
- // don't let key fall through anywhere else
- return MSG_HANDLED;
-
- } // end escape
-
- } // end switch( key )
-
- } // end char
-
- } // end switch( msg )
-
- return MSG_IGNORED;
-}// WOLMessageWindowInput
-
-//-------------------------------------------------------------------------------------------------
-/** WOLMessage Window window system callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLMessageWindowSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- UnicodeString txtInput;
-
- switch( msg )
- {
-
-
- case GWM_CREATE:
- {
-
- break;
- } // case GWM_DESTROY:
-
- case GWM_DESTROY:
- {
- break;
- } // case GWM_DESTROY:
-
- case GWM_INPUT_FOCUS:
- {
- // if we're givin the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
-
- return MSG_HANDLED;
- }//case GWM_INPUT_FOCUS:
-
- case GBM_SELECTED:
- {
- break;
- }// case GBM_SELECTED:
-
- case GEM_EDIT_DONE:
- {
- break;
- }
- default:
- return MSG_IGNORED;
-
- }//Switch
-
- return MSG_HANDLED;
-}// WOLMessageWindowSystem
diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQMScoreScreen.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQMScoreScreen.cpp
deleted file mode 100644
index 80ecc295549..00000000000
--- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQMScoreScreen.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////////////
-// FILE: WOLQMScoreScreen.cpp
-// Author: Matt Campbell, November 2001
-// Description: QuickMatch score screen (different from normal screen in that it has 'QM' and 'Discon' buttons)
-///////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/GameEngine.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/Shell.h"
-#include "GameClient/KeyDefs.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/GadgetListBox.h"
-#include "GameClient/GadgetTextEntry.h"
-//#include "GameNetwork/WOL.h"
-//#include "GameNetwork/WOLmenus.h"
-
-
-
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-// window ids ------------------------------------------------------------------------------
-static NameKeyType parentWOLQMScoreID = NAMEKEY_INVALID;
-static NameKeyType buttonDisconnectID = NAMEKEY_INVALID;
-static NameKeyType buttonQuickmatchID = NAMEKEY_INVALID;
-
-// Window Pointers ------------------------------------------------------------------------
-static GameWindow *parentWOLQMScore = NULL;
-static GameWindow *buttonDisconnect = NULL;
-static GameWindow *buttonQuickmatch = NULL;
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the WOL Status Menu */
-//-------------------------------------------------------------------------------------------------
-void WOLQMScoreScreenInit( WindowLayout *layout, void *userData )
-{
- parentWOLQMScoreID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLQMScoreScreen.wnd:WOLQMScoreScreenParent" ) );
- buttonDisconnectID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLQMScoreScreen.wnd:ButtonDisconnect" ) );
- buttonQuickmatchID = TheNameKeyGenerator->nameToKey( AsciiString( "WOLQMScoreScreen.wnd:ButtonQuickMatch" ) );
- parentWOLQMScore = TheWindowManager->winGetWindowFromId( NULL, parentWOLQMScoreID );
- buttonDisconnect = TheWindowManager->winGetWindowFromId( NULL, buttonDisconnectID);
- buttonQuickmatch = TheWindowManager->winGetWindowFromId( NULL, buttonQuickmatchID);
-
- /*
- if (WOL::TheWOL->getState() == WOL::WOLAPI_FATAL_ERROR)
- {
- // We can get to the score screen even though we've been disconnected. Just hide
- // any buttons that lead back into WOL.
-
- buttonQuickmatch->winHide( TRUE );
- }
- */
-
- // Show Menu
- layout->hide( FALSE );
-
- // Set Keyboard to Main Parent
- TheWindowManager->winSetFocus( parentWOLQMScore );
-
- //progressLayout = TheShell->top();
-
-} // WOLQMScoreScreenInit
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Status Menu shutdown method */
-//-------------------------------------------------------------------------------------------------
-void WOLQMScoreScreenShutdown( WindowLayout *layout, void *userData )
-{
-
- // hide menu
- layout->hide( TRUE );
-
- // our shutdown is complete
- TheShell->shutdownComplete( layout );
-
- //progressLayout = NULL;
-
-} // WOLQMScoreScreenShutdown
-
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Status Menu update method */
-//-------------------------------------------------------------------------------------------------
-void WOLQMScoreScreenUpdate( WindowLayout * layout, void *userData)
-{
- /*
- if (WOL::TheWOL)
- WOL::TheWOL->update();
- */
-}// WOLQMScoreScreenUpdate
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Status Menu input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLQMScoreScreenInput( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
- UnsignedByte key = mData1;
- UnsignedByte state = mData2;
-
- switch( key )
- {
-
- // ----------------------------------------------------------------------------------------
- case KEY_ESC:
- {
-
- //
- // send a simulated selected event to the parent window of the
- // back/exit button
- //
- if( BitTest( state, KEY_STATE_UP ) )
- {
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)buttonDisconnect, buttonDisconnectID );
-
- } // end if
-
- // don't let key fall through anywhere else
- return MSG_HANDLED;
-
- } // end escape
-
- } // end switch( key )
-
- } // end char
-
- } // end switch( msg )
-
- return MSG_IGNORED;
-}// WOLQMScoreScreenInput
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Status Menu window system callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLQMScoreScreenSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- UnicodeString txtInput;
-
- switch( msg )
- {
-
-
- case GWM_CREATE:
- {
-
- break;
- } // case GWM_DESTROY:
-
- case GWM_DESTROY:
- {
- break;
- } // case GWM_DESTROY:
-
- case GWM_INPUT_FOCUS:
- {
- // if we're given the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
-
- return MSG_HANDLED;
- }//case GWM_INPUT_FOCUS:
-
- case GBM_SELECTED:
- {
- /*
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
-
- if ( controlID == buttonDisconnectID )
- {
- //TheShell->pop();
- if (WOL::TheWOL->setState( WOL::WOLAPI_FATAL_ERROR ))
- {
- WOL::TheWOL->addCommand( WOL::WOLCOMMAND_RESET ); // don't display an error, log out, or anything
- }
-
- } //if ( controlID == buttonDisconnect )
- else if ( controlID == buttonQuickmatchID )
- {
- //TheShell->pop();
- if (WOL::TheWOL->getState() != WOL::WOLAPI_FATAL_ERROR)
- {
- if (WOL::TheWOL->setState( WOL::WOLAPI_TOURNAMENT ))
- {
- WOL::TheWOL->setScreen( WOL::WOLAPI_MENU_QUICKMATCH );
- WOL::TheWOL->addCommand( WOL::WOLCOMMAND_FIND_MATCH_CHANNEL );
- }
- }
-
- } //if ( controlID == buttonDisconnect )
- */
- break;
- }// case GBM_SELECTED:
-
- case GEM_EDIT_DONE:
- {
- break;
- }
- default:
- return MSG_IGNORED;
-
- }//Switch
-
- return MSG_HANDLED;
-}// WOLQMScoreScreenSystem
diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQuickMatchMenu.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQuickMatchMenu.cpp
deleted file mode 100644
index d119217f1f2..00000000000
--- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQuickMatchMenu.cpp
+++ /dev/null
@@ -1,1897 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////////////////////////
-// FILE: WOLQuickMatchMenu.cpp
-// Author: Chris Huybregts, November 2001
-// Description: Lan Lobby Menu
-///////////////////////////////////////////////////////////////////////////////////////
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
-
-#include "Common/GameEngine.h"
-#include "Common/QuickmatchPreferences.h"
-#include "Common/LadderPreferences.h"
-#include "Common/MultiplayerSettings.h"
-#include "Common/PlayerTemplate.h"
-#include "GameClient/AnimateWindowManager.h"
-#include "GameClient/WindowLayout.h"
-#include "GameClient/Gadget.h"
-#include "GameClient/GameText.h"
-#include "GameClient/InGameUI.h"
-#include "GameClient/Shell.h"
-#include "GameClient/ShellHooks.h"
-#include "GameClient/KeyDefs.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/GadgetComboBox.h"
-#include "GameClient/GadgetPushButton.h"
-#include "GameClient/GadgetListBox.h"
-#include "GameClient/GadgetTextEntry.h"
-#include "GameClient/GadgetStaticText.h"
-#include "GameClient/MapUtil.h"
-#include "GameClient/GameWindowTransitions.h"
-#include "GameClient/ChallengeGenerals.h"
-
-#include "GameLogic/GameLogic.h"
-
-#include "GameNetwork/NAT.h"
-#include "GameNetwork/GameSpyOverlay.h"
-#include "GameNetwork/GameSpy/BuddyDefs.h"
-#include "GameNetwork/GameSpy/GSConfig.h"
-#include "GameNetwork/GameSpy/PeerDefs.h"
-#include "GameNetwork/GameSpy/PeerThread.h"
-#include "GameNetwork/GameSpy/PersistentStorageDefs.h"
-#include "GameNetwork/GameSpy/PersistentStorageThread.h"
-#include "GameNetwork/RankPointValue.h"
-#include "GameNetwork/GameSpy/LadderDefs.h"
-#ifdef _INTERNAL
-// for occasional debugging...
-//#pragma optimize("", off)
-//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
-#endif
-
-#ifdef DEBUG_LOGGING
-#include "Common/MiniLog.h"
-//#define PERF_TEST
-static LogClass s_perfLog("QMPerf.txt");
-static Bool s_inQM = FALSE;
-#define PERF_LOG(x) s_perfLog.log x
-#else // DEBUG_LOGGING
-#define PERF_LOG(x) {}
-#endif // DEBUG_LOGGING
-
-// PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
-// window ids ------------------------------------------------------------------------------
-static NameKeyType parentWOLQuickMatchID = NAMEKEY_INVALID;
-static NameKeyType buttonBackID = NAMEKEY_INVALID;
-static NameKeyType buttonStartID = NAMEKEY_INVALID;
-static NameKeyType buttonStopID = NAMEKEY_INVALID;
-static NameKeyType buttonWidenID = NAMEKEY_INVALID;
-static NameKeyType buttonBuddiesID = NAMEKEY_INVALID;
-static NameKeyType listboxQuickMatchID = NAMEKEY_INVALID;
-static NameKeyType listboxMapSelectID = NAMEKEY_INVALID;
-static NameKeyType buttonSelectAllMapsID = NAMEKEY_INVALID;
-static NameKeyType buttonSelectNoMapsID = NAMEKEY_INVALID;
-//static NameKeyType textEntryMaxDisconnectsID = NAMEKEY_INVALID;
-//static NameKeyType textEntryMaxPointsID = NAMEKEY_INVALID;
-//static NameKeyType textEntryMinPointsID = NAMEKEY_INVALID;
-static NameKeyType textEntryWaitTimeID = NAMEKEY_INVALID;
-static NameKeyType comboBoxNumPlayersID = NAMEKEY_INVALID;
-static NameKeyType comboBoxMaxPingID = NAMEKEY_INVALID;
-static NameKeyType comboBoxLadderID = NAMEKEY_INVALID;
-static NameKeyType comboBoxMaxDisconnectsID = NAMEKEY_INVALID;
-static NameKeyType staticTextNumPlayersID = NAMEKEY_INVALID;
-static NameKeyType comboBoxSideID = NAMEKEY_INVALID;
-static NameKeyType comboBoxColorID = NAMEKEY_INVALID;
-
-
-// Window Pointers ------------------------------------------------------------------------
-static GameWindow *parentWOLQuickMatch = NULL;
-static GameWindow *buttonBack = NULL;
-static GameWindow *buttonStart = NULL;
-static GameWindow *buttonStop = NULL;
-static GameWindow *buttonWiden = NULL;
-GameWindow *quickmatchTextWindow = NULL;
-static GameWindow *listboxMapSelect = NULL;
-//static GameWindow *textEntryMaxDisconnects = NULL;
-//static GameWindow *textEntryMaxPoints = NULL;
-//static GameWindow *textEntryMinPoints = NULL;
-static GameWindow *textEntryWaitTime = NULL;
-static GameWindow *comboBoxNumPlayers = NULL;
-static GameWindow *comboBoxMaxPing = NULL;
-static GameWindow *comboBoxLadder = NULL;
-static GameWindow *comboBoxDisabledLadder = NULL; // enable and disable this, but never use it. it is a stand-in for comboBoxLadder for when there are no ladders
-static GameWindow *comboBoxMaxDisconnects = NULL;
-static GameWindow *staticTextNumPlayers = NULL;
-static GameWindow *comboBoxSide = NULL;
-static GameWindow *comboBoxColor = NULL;
-
-static Bool isShuttingDown = false;
-static Bool buttonPushed = false;
-static char *nextScreen = NULL;
-static Bool raiseMessageBoxes = false;
-static Bool isInInit = FALSE;
-static const Image *selectedImage = NULL;
-static const Image *unselectedImage = NULL;
-
-static bool isPopulatingLadderBox = false;
-static Int maxPingEntries = 0;
-static Int maxPoints= 100;
-static Int minPoints = 0;
-
-static const LadderInfo * getLadderInfo( void );
-
-static Bool isInfoShown(void)
-{
- static NameKeyType parentStatsID = NAMEKEY("WOLQuickMatchMenu.wnd:ParentStats");
- GameWindow *parentStats = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, parentStatsID );
- if (parentStats)
- return !parentStats->winIsHidden();
- return FALSE;
-}
-
-static void hideInfoGadgets(Bool doIt)
-{
- static NameKeyType parentStatsID = NAMEKEY("WOLQuickMatchMenu.wnd:ParentStats");
- GameWindow *parentStats = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, parentStatsID );
- if (parentStats)
- {
- parentStats->winHide(doIt);
- }
-}
-
-static void hideOptionsGadgets(Bool doIt)
-{
- static NameKeyType parentOptionsID = NAMEKEY("WOLQuickMatchMenu.wnd:ParentOptions");
- GameWindow *parentOptions = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, parentOptionsID );
- if (parentOptions)
- {
- parentOptions->winHide(doIt);
- if (comboBoxSide)
- comboBoxSide->winHide(doIt);
- if (comboBoxColor)
- comboBoxColor->winHide(doIt);
- if (comboBoxNumPlayers)
- comboBoxNumPlayers->winHide(doIt);
- if (comboBoxLadder)
- comboBoxLadder->winHide(doIt);
- if (comboBoxDisabledLadder)
- comboBoxDisabledLadder->winHide(doIt);
- if (comboBoxMaxPing)
- comboBoxMaxPing->winHide(doIt);
- if (comboBoxMaxDisconnects)
- comboBoxMaxDisconnects->winHide(doIt);
- }
-}
-
-static void enableOptionsGadgets(Bool doIt)
-{
-#ifdef PERF_TEST
- s_inQM = !doIt;
-#endif // PERF_TEST
- static NameKeyType parentOptionsID = NAMEKEY("WOLQuickMatchMenu.wnd:ParentOptions");
- GameWindow *parentOptions = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, parentOptionsID );
- const LadderInfo *li = getLadderInfo();
- if (parentOptions)
- {
- parentOptions->winEnable(doIt);
- if (comboBoxSide)
- comboBoxSide->winEnable(doIt && (!li || !li->randomFactions));
- if (comboBoxColor)
- comboBoxColor->winEnable(doIt);
- if (comboBoxNumPlayers)
- comboBoxNumPlayers->winEnable(doIt);
- if (comboBoxLadder)
- comboBoxLadder->winEnable(doIt);
- if (comboBoxDisabledLadder)
- comboBoxDisabledLadder->winEnable(FALSE);
- if (comboBoxMaxPing)
- comboBoxMaxPing->winEnable(doIt);
- if (comboBoxMaxDisconnects)
- comboBoxMaxDisconnects->winEnable(doIt);
- }
-}
-
-enum
-{
- MAX_DISCONNECTS_ANY = 0,
- MAX_DISCONNECTS_5 = 5,
- MAX_DISCONNECTS_10 = 10,
- MAX_DISCONNECTS_25 = 25,
- MAX_DISCONNECTS_50 = 50,
-};
-enum{ MAX_DISCONNECTS_COUNT = 5 };
-
-static Int MAX_DISCONNECTS[MAX_DISCONNECTS_COUNT] = {MAX_DISCONNECTS_ANY, MAX_DISCONNECTS_5,
- MAX_DISCONNECTS_10, MAX_DISCONNECTS_25,
- MAX_DISCONNECTS_50};
-
-
-void UpdateStartButton(void)
-{
- if (!comboBoxLadder || !buttonStart || !listboxMapSelect)
- return;
-
- Int index;
- Int selected;
- GadgetComboBoxGetSelectedPos( comboBoxLadder, &selected );
- index = (Int)GadgetComboBoxGetItemData( comboBoxLadder, selected );
- const LadderInfo *li = TheLadderList->findLadderByIndex( index );
- if (li)
- {
- buttonStart->winEnable(TRUE);
- return;
- }
-
- Int numMaps = GadgetListBoxGetNumEntries(listboxMapSelect);
- for ( Int i=0; iwinEnable(TRUE);
- return;
- }
- }
- buttonStart->winEnable(FALSE);
-}
-
-// -----------------------------------------------------------------------------
-
-static void populateQMColorComboBox(QuickMatchPreferences& pref)
-{
- Int numColors = TheMultiplayerSettings->getNumColors();
- UnicodeString colorName;
-
- GadgetComboBoxReset(comboBoxColor);
-
- MultiplayerColorDefinition *def = TheMultiplayerSettings->getColor(PLAYERTEMPLATE_RANDOM);
- Int newIndex = GadgetComboBoxAddEntry(comboBoxColor, TheGameText->fetch("GUI:???"), def->getColor());
- GadgetComboBoxSetItemData(comboBoxColor, newIndex, (void *)-1);
-
- for (Int c=0; cgetColor(c);
- if (!def)
- continue;
-
- colorName = TheGameText->fetch(def->getTooltipName().str());
- newIndex = GadgetComboBoxAddEntry(comboBoxColor, colorName, def->getColor());
- GadgetComboBoxSetItemData(comboBoxColor, newIndex, (void *)c);
- }
- GadgetComboBoxSetSelectedPos(comboBoxColor, pref.getColor());
-}
-
-// -----------------------------------------------------------------------------
-
-static void populateQMSideComboBox(Int favSide, const LadderInfo *li = NULL)
-{
- Int numPlayerTemplates = ThePlayerTemplateStore->getPlayerTemplateCount();
- UnicodeString playerTemplateName;
-
- GadgetComboBoxReset(comboBoxSide);
-
- MultiplayerColorDefinition *def = TheMultiplayerSettings->getColor(PLAYERTEMPLATE_RANDOM);
- Int newIndex = GadgetComboBoxAddEntry(comboBoxSide, TheGameText->fetch("GUI:Random"), def->getColor());
- GadgetComboBoxSetItemData(comboBoxSide, newIndex, (void *)PLAYERTEMPLATE_RANDOM);
-
- std::set seenSides;
-
- Int entryToSelect = 0; // select Random by default
-
- for (Int c=0; cgetNthPlayerTemplate(c);
- if (!fac)
- continue;
-
- if (fac->getStartingBuilding().isEmpty())
- continue;
-
- AsciiString side;
- side.format("SIDE:%s", fac->getSide().str());
- if (seenSides.find(side) != seenSides.end())
- continue;
-
- if (li)
- {
- if (std::find(li->validFactions.begin(), li->validFactions.end(), fac->getSide()) == li->validFactions.end())
- continue; // ladder doesn't allow it.
- }
-
- // Remove disallowed generals from the choice list.
- // This is also enforced at GUI setup (GUIUtil.cpp and UserPreferences.cpp).
- // @todo: unlock these when something rad happens
- Bool disallowLockedGenerals = TRUE;
- const GeneralPersona *general = TheChallengeGenerals->getGeneralByTemplateName(fac->getName());
- Bool startsLocked = general ? !general->isStartingEnabled() : FALSE;
- if (disallowLockedGenerals && startsLocked)
- continue;
-
- seenSides.insert(side);
-
- newIndex = GadgetComboBoxAddEntry(comboBoxSide, TheGameText->fetch(side), def->getColor());
- GadgetComboBoxSetItemData(comboBoxSide, newIndex, (void *)c);
-
- if (c == favSide)
- entryToSelect = newIndex;
- }
- seenSides.clear();
-
- GadgetComboBoxSetSelectedPos(comboBoxSide, entryToSelect);
- if (li && li->randomFactions)
- comboBoxSide->winEnable(FALSE);
- else
- comboBoxSide->winEnable(TRUE);
-}
-
-void HandleQMLadderSelection(Int ladderID)
-{
- if (!parentWOLQuickMatch)
- return;
-
- QuickMatchPreferences pref;
-
- if (ladderID < 1)
- {
- pref.setLastLadder(AsciiString::TheEmptyString, 0);
- pref.write();
- return;
- }
-
- const LadderInfo *info = TheLadderList->findLadderByIndex(ladderID);
- if (!info)
- {
- pref.setLastLadder(AsciiString::TheEmptyString, 0);
- }
- else
- {
- pref.setLastLadder(info->address, info->port);
- }
-
- pref.write();
-}
-
-static inline Bool isValidLadder( const LadderInfo *lad )
-{
- if (lad && lad->index > 0 && lad->validQM)
- {
- PSPlayerStats stats = TheGameSpyPSMessageQueue->findPlayerStatsByID(TheGameSpyInfo->getLocalProfileID());
- Int numWins = 0;
- PerGeneralMap::iterator it;
- for (it = stats.wins.begin(); it != stats.wins.end(); ++it)
- {
- numWins += it->second;
- }
- if (!lad->maxWins || lad->maxWins >=numWins)
- {
- if (!lad->minWins || lad->minWins<=numWins)
- {
- return TRUE;
- }
- }
- }
- return FALSE;
-}
-
-void PopulateQMLadderListBox( GameWindow *win )
-{
- if (!parentWOLQuickMatch || !comboBoxLadder)
- return;
-
- isPopulatingLadderBox = true;
-
- QuickMatchPreferences pref;
- AsciiString userPrefFilename;
- Int localProfile = TheGameSpyInfo->getLocalProfileID();
-
- Color specialColor = GameSpyColor[GSCOLOR_MAP_SELECTED];
- Color normalColor = GameSpyColor[GSCOLOR_MAP_UNSELECTED];
- Color favoriteColor = GameSpyColor[GSCOLOR_MAP_UNSELECTED];
- Int index;
- GadgetListBoxReset( win );
-
- std::set usedLadders;
-
- // start with "No Ladder"
- index = GadgetListBoxAddEntryText( win, TheGameText->fetch("GUI:NoLadder"), normalColor, -1 );
- GadgetListBoxSetItemData( win, 0, index );
-
- // add the last ladder
- Int selectedPos = 0;
- AsciiString lastLadderAddr = pref.getLastLadderAddr();
- UnsignedShort lastLadderPort = pref.getLastLadderPort();
- const LadderInfo *info = TheLadderList->findLadder( lastLadderAddr, lastLadderPort );
- if (isValidLadder(info))
- {
- usedLadders.insert(info);
- index = GadgetListBoxAddEntryText( win, info->name, favoriteColor, -1 );
- GadgetListBoxSetItemData( win, (void *)(info->index), index );
- selectedPos = index;
- }
-
- // our recent ladders
- LadderPreferences ladPref;
- ladPref.loadProfile( localProfile );
- const LadderPrefMap recentLadders = ladPref.getRecentLadders();
- for (LadderPrefMap::const_iterator cit = recentLadders.begin(); cit != recentLadders.end(); ++cit)
- {
- AsciiString addr = cit->second.address;
- UnsignedShort port = cit->second.port;
- if (addr == lastLadderAddr && port == lastLadderPort)
- continue;
- const LadderInfo *info = TheLadderList->findLadder( addr, port );
- if (isValidLadder(info) && usedLadders.find(info) == usedLadders.end())
- {
- usedLadders.insert(info);
- index = GadgetListBoxAddEntryText( win, info->name, favoriteColor, -1 );
- GadgetListBoxSetItemData( win, (void *)(info->index), index );
- }
- }
-
- // special ladders
- const LadderInfoList *lil = TheLadderList->getSpecialLadders();
- LadderInfoList::const_iterator lit;
- for (lit = lil->begin(); lit != lil->end(); ++lit)
- {
- const LadderInfo *info = *lit;
- if (isValidLadder(info) && usedLadders.find(info) == usedLadders.end())
- {
- usedLadders.insert(info);
- index = GadgetListBoxAddEntryText( win, info->name, specialColor, -1 );
- GadgetListBoxSetItemData( win, (void *)(info->index), index );
- }
- }
-
- // standard ladders
- lil = TheLadderList->getStandardLadders();
- for (lit = lil->begin(); lit != lil->end(); ++lit)
- {
- const LadderInfo *info = *lit;
- if (isValidLadder(info) && usedLadders.find(info) == usedLadders.end())
- {
- usedLadders.insert(info);
- index = GadgetListBoxAddEntryText( win, info->name, normalColor, -1 );
- GadgetListBoxSetItemData( win, (void *)(info->index), index );
- }
- }
-
- GadgetListBoxSetSelected( win, selectedPos );
- isPopulatingLadderBox = false;
-}
-
-static const LadderInfo * getLadderInfo( void )
-{
- Int index;
- Int selected;
- GadgetComboBoxGetSelectedPos( comboBoxLadder, &selected );
- index = (Int)GadgetComboBoxGetItemData( comboBoxLadder, selected );
- const LadderInfo *li = TheLadderList->findLadderByIndex( index );
- return li;
-}
-
-void PopulateQMLadderComboBox( void )
-{
- if (!parentWOLQuickMatch || !comboBoxLadder)
- return;
-
- isPopulatingLadderBox = true;
-
- QuickMatchPreferences pref;
- Int localProfile = TheGameSpyInfo->getLocalProfileID();
-
- Color specialColor = GameSpyColor[GSCOLOR_MAP_SELECTED];
- Color normalColor = GameSpyColor[GSCOLOR_MAP_UNSELECTED];
- Int index;
- GadgetComboBoxReset( comboBoxLadder );
- index = GadgetComboBoxAddEntry( comboBoxLadder, TheGameText->fetch("GUI:NoLadder"), normalColor );
- GadgetComboBoxSetItemData( comboBoxLadder, index, 0 );
-
- std::set usedLadders;
-
- Int selectedPos = 0;
- AsciiString lastLadderAddr = pref.getLastLadderAddr();
- UnsignedShort lastLadderPort = pref.getLastLadderPort();
- const LadderInfo *info = TheLadderList->findLadder( lastLadderAddr, lastLadderPort );
- if (isValidLadder(info))
- {
- usedLadders.insert(info);
- index = GadgetComboBoxAddEntry( comboBoxLadder, info->name, specialColor );
- GadgetComboBoxSetItemData( comboBoxLadder, index, (void *)(info->index) );
- selectedPos = index;
-
- // we selected a ladder? No game size choice for us...
- GadgetComboBoxSetSelectedPos(comboBoxNumPlayers, info->playersPerTeam-1);
- comboBoxNumPlayers->winEnable( FALSE );
- }
- else
- {
- comboBoxNumPlayers->winEnable( TRUE );
- }
-
- LadderPreferences ladPref;
- ladPref.loadProfile( localProfile );
- const LadderPrefMap recentLadders = ladPref.getRecentLadders();
- for (LadderPrefMap::const_iterator cit = recentLadders.begin(); cit != recentLadders.end(); ++cit)
- {
- AsciiString addr = cit->second.address;
- UnsignedShort port = cit->second.port;
- if (addr == lastLadderAddr && port == lastLadderPort)
- continue;
- const LadderInfo *info = TheLadderList->findLadder( addr, port );
- if (isValidLadder(info) && usedLadders.find(info) == usedLadders.end())
- {
- usedLadders.insert(info);
- index = GadgetComboBoxAddEntry( comboBoxLadder, info->name, normalColor );
- GadgetComboBoxSetItemData( comboBoxLadder, index, (void *)(info->index) );
- }
- }
-
- index = GadgetComboBoxAddEntry( comboBoxLadder, TheGameText->fetch("GUI:ChooseLadder"), normalColor );
- GadgetComboBoxSetItemData( comboBoxLadder, index, (void *)-1 );
-
- GadgetComboBoxSetSelectedPos( comboBoxLadder, selectedPos );
- isPopulatingLadderBox = false;
-
- populateQMSideComboBox(pref.getSide(), getLadderInfo()); // this will set side to random and disable if necessary
-}
-
-static void populateQuickMatchMapSelectListbox( QuickMatchPreferences& pref )
-{
- std::list maps = TheGameSpyConfig->getQMMaps();
-
- // enable/disable box based on ladder status
- Int index;
- Int selected;
- GadgetComboBoxGetSelectedPos( comboBoxLadder, &selected );
- index = (Int)GadgetComboBoxGetItemData( comboBoxLadder, selected );
- const LadderInfo *li = TheLadderList->findLadderByIndex( index );
- //listboxMapSelect->winEnable( li == NULL || li->randomMaps == FALSE );
-
- Int numPlayers = 0;
- if (li)
- {
- numPlayers = li->playersPerTeam*2;
-
- maps = li->validMaps;
- }
- else
- {
- GadgetComboBoxGetSelectedPos(comboBoxNumPlayers, &selected);
- if (selected < 0)
- selected = 0;
- numPlayers = (selected+1)*2;
- }
-
-
- GadgetListBoxReset(listboxMapSelect);
- for (std::list::const_iterator it = maps.begin(); it != maps.end(); ++it)
- {
- AsciiString theMap = *it;
- const MapMetaData *md = TheMapCache->findMap(theMap);
- if (md && md->m_numPlayers >= numPlayers)
- {
- UnicodeString displayName;
- displayName = md->m_displayName;
- Bool isSelected = pref.isMapSelected(theMap);
- if (li && li->randomMaps)
- isSelected = TRUE;
- Int width = 10;
- Int height = 10;
- const Image *img = (isSelected)?selectedImage:unselectedImage;
- if ( img )
- {
- width = min(GadgetListBoxGetColumnWidth(listboxMapSelect, 0), img->getImageWidth());
- height = width;
- }
- Int index = GadgetListBoxAddEntryImage(listboxMapSelect, img, -1, 0, height, width);
- GadgetListBoxAddEntryText(listboxMapSelect, displayName, GameSpyColor[(isSelected)?GSCOLOR_MAP_SELECTED:GSCOLOR_MAP_UNSELECTED], index, 1);
- GadgetListBoxSetItemData(listboxMapSelect, (void *)isSelected, index);
- GadgetListBoxSetItemData(listboxMapSelect, (void *)md, index, 1);
- }
- }
-}
-
-static void saveQuickMatchOptions( void )
-{
- if(isInInit)
- return;
- QuickMatchPreferences pref;
-
- std::list maps = TheGameSpyConfig->getQMMaps();
-
- Int index;
- Int selected;
- GadgetComboBoxGetSelectedPos( comboBoxLadder, &selected );
- index = (Int)GadgetComboBoxGetItemData( comboBoxLadder, selected );
- const LadderInfo *li = TheLadderList->findLadderByIndex( index );
- Int numPlayers = 0;
-
- if (li)
- {
- pref.setLastLadder( li->address, li->port );
- numPlayers = li->playersPerTeam*2;
-
- pref.write();
- //return; // don't save our defaults based on the tournament's defaults
- }
- else
- {
- pref.setLastLadder( AsciiString::TheEmptyString, 0 );
- GadgetComboBoxGetSelectedPos(comboBoxNumPlayers, &selected);
- if (selected < 0)
- selected = 0;
- numPlayers = (selected+1)*2;
- }
-
- if (!li || !li->randomMaps) // don't save the map as selected if we couldn't choose
- {
- Int row = 0;
- Int entries = GadgetListBoxGetNumEntries(listboxMapSelect);
- while ( row < entries)
- {
- const MapMetaData *md = (const MapMetaData *)GadgetListBoxGetItemData(listboxMapSelect, row, 1);
- if(md)
- pref.setMapSelected(md->m_fileName, (Bool)GadgetListBoxGetItemData(listboxMapSelect, row));
- row++;
- }
- }
-
- UnicodeString u;
- AsciiString a;
-// u = GadgetTextEntryGetText(textEntryMaxDisconnects);
-// a.translate(u);
-// pref.setMaxDisconnects(atoi(a.str()));
-// u = GadgetTextEntryGetText(textEntryMaxPoints);
-// a.translate(u);
-// pref.setMaxPoints(max(100, atoi(a.str())));
-// u = GadgetTextEntryGetText(textEntryMinPoints);
-// a.translate(u);
-// pref.setMinPoints(min(100, atoi(a.str())));
- //u = GadgetTextEntryGetText(textEntryWaitTime);
- //a.translate(u);
- //pref.setWaitTime(atoi(a.str()));
-
- GadgetComboBoxGetSelectedPos(comboBoxNumPlayers, &selected);
- pref.setNumPlayers(selected);
- GadgetComboBoxGetSelectedPos(comboBoxMaxPing, &selected);
- pref.setMaxPing(selected);
-
- Int item;
- GadgetComboBoxGetSelectedPos(comboBoxSide, &selected);
- item = (Int)GadgetComboBoxGetItemData(comboBoxSide, selected);
- pref.setSide(max(0, item));
- GadgetComboBoxGetSelectedPos(comboBoxColor, &selected);
- pref.setColor(max(0, selected));
-
- GadgetComboBoxGetSelectedPos(comboBoxMaxDisconnects, &selected);
- pref.setMaxDisconnects(selected);
-
-
- pref.write();
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Initialize the WOL Quick Match Menu */
-//-------------------------------------------------------------------------------------------------
-void WOLQuickMatchMenuInit( WindowLayout *layout, void *userData )
-{
- isInInit = TRUE;
- if (TheGameSpyGame && TheGameSpyGame->isGameInProgress())
- {
- TheGameSpyGame->setGameInProgress(FALSE);
-
- // check if we were disconnected
- Int disconReason;
- if (TheGameSpyInfo->isDisconnectedAfterGameStart(&disconReason))
- {
- AsciiString disconMunkee;
- disconMunkee.format("GUI:GSDisconReason%d", disconReason);
- UnicodeString title, body;
- title = TheGameText->fetch( "GUI:GSErrorTitle" );
- body = TheGameText->fetch( disconMunkee );
- GameSpyCloseAllOverlays();
- GSMessageBoxOk( title, body );
- TheGameSpyInfo->reset();
- DEBUG_LOG(("WOLQuickMatchMenuInit() - game was in progress, and we were disconnected, so pop immediate back to main menu\n"));
- TheShell->popImmediate();
- return;
- }
- }
-
- nextScreen = NULL;
- buttonPushed = false;
- isShuttingDown = false;
- raiseMessageBoxes = true;
-
- if (TheNAT != NULL) {
- delete TheNAT;
- TheNAT = NULL;
- }
-
- parentWOLQuickMatchID = NAMEKEY( "WOLQuickMatchMenu.wnd:WOLQuickMatchMenuParent" );
- buttonBackID = NAMEKEY( "WOLQuickMatchMenu.wnd:ButtonBack" );
- buttonBuddiesID = NAMEKEY( "WOLQuickMatchMenu.wnd:ButtonBuddies" );
- buttonStartID = NAMEKEY( "WOLQuickMatchMenu.wnd:ButtonStart" );
- buttonStopID = NAMEKEY( "WOLQuickMatchMenu.wnd:ButtonStop" );
- buttonWidenID = NAMEKEY( "WOLQuickMatchMenu.wnd:ButtonWiden" );
- listboxQuickMatchID = NAMEKEY( "WOLQuickMatchMenu.wnd:ListboxQuickMatch" );
- listboxMapSelectID = NAMEKEY( "WOLQuickMatchMenu.wnd:ListBoxMapSelect" );
- buttonSelectAllMapsID = NAMEKEY( "WOLQuickMatchMenu.wnd:ButtonSelectAllMaps" );
- buttonSelectNoMapsID = NAMEKEY( "WOLQuickMatchMenu.wnd:ButtonSelectNoMaps" );
- //textEntryMaxDisconnectsID = NAMEKEY( "WOLQuickMatchMenu.wnd:TextEntryMaxDisconnects" );
- //textEntryMaxPointsID = NAMEKEY( "WOLQuickMatchMenu.wnd:TextEntryMaxPointPercent" );
- //textEntryMinPointsID = NAMEKEY( "WOLQuickMatchMenu.wnd:TextEntryMinPointPercent" );
- textEntryWaitTimeID = NAMEKEY( "WOLQuickMatchMenu.wnd:TextEntryWaitTime" );
- comboBoxMaxPingID = NAMEKEY( "WOLQuickMatchMenu.wnd:ComboBoxMaxPing" );
- comboBoxNumPlayersID = NAMEKEY( "WOLQuickMatchMenu.wnd:ComboBoxNumPlayers" );
- comboBoxLadderID = NAMEKEY( "WOLQuickMatchMenu.wnd:ComboBoxLadder" );
- comboBoxMaxDisconnectsID = NAMEKEY( "WOLQuickMatchMenu.wnd:ComboBoxMaxDisconnects" );
- staticTextNumPlayersID = NAMEKEY( "WOLQuickMatchMenu.wnd:StaticTextNumPlayers" );
- comboBoxSideID = NAMEKEY( "WOLQuickMatchMenu.wnd:ComboBoxSide" );
- comboBoxColorID = NAMEKEY( "WOLQuickMatchMenu.wnd:ComboBoxColor" );
-
- parentWOLQuickMatch = TheWindowManager->winGetWindowFromId( NULL, parentWOLQuickMatchID );
- buttonBack = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, buttonBackID);
- buttonStart = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, buttonStartID);
- buttonStop = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, buttonStopID);
- buttonWiden = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, buttonWidenID);
- quickmatchTextWindow = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, listboxQuickMatchID);
- listboxMapSelect = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, listboxMapSelectID);
- //textEntryMaxDisconnects = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, textEntryMaxDisconnectsID );
- //textEntryMaxPoints = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, textEntryMaxPointsID );
- //textEntryMinPoints = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, textEntryMinPointsID );
- textEntryWaitTime = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, textEntryWaitTimeID );
- comboBoxMaxPing = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, comboBoxMaxPingID );
- comboBoxNumPlayers = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, comboBoxNumPlayersID );
- comboBoxLadder = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, comboBoxLadderID );
- comboBoxMaxDisconnects = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, comboBoxMaxDisconnectsID );
- TheGameSpyInfo->registerTextWindow(quickmatchTextWindow);
- staticTextNumPlayers = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, staticTextNumPlayersID );
- comboBoxSide = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, comboBoxSideID );
- comboBoxColor = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, comboBoxColorID );
-
- if (TheLadderList->getStandardLadders()->size() == 0
- && TheLadderList->getSpecialLadders()->size() == 0
- && TheLadderList->getLocalLadders()->size() == 0)
- {
- // no ladders, so just disable them
- comboBoxDisabledLadder = comboBoxLadder;
- comboBoxLadder = NULL;
-
- isPopulatingLadderBox = TRUE;
-
- Color normalColor = GameSpyColor[GSCOLOR_MAP_UNSELECTED];
- Int index;
- GadgetComboBoxReset( comboBoxDisabledLadder );
- index = GadgetComboBoxAddEntry( comboBoxDisabledLadder, TheGameText->fetch("GUI:NoLadder"), normalColor );
- GadgetComboBoxSetItemData( comboBoxDisabledLadder, index, 0 );
- GadgetComboBoxSetSelectedPos( comboBoxDisabledLadder, index );
-
- isPopulatingLadderBox = FALSE;
-
- /** This code would actually *hide* the combo box, but it doesn't look as good. Left here since someone will want to
- ** see it at some point. :P
- if (comboBoxLadder)
- {
- comboBoxLadder->winHide(TRUE);
- comboBoxLadder->winEnable(FALSE);
- }
- comboBoxLadder = NULL;
- GameWindow *staticTextLadder = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch,
- NAMEKEY("WOLQuickMatchMenu.wnd:StaticTextLadder") );
- if (staticTextLadder)
- staticTextLadder->winHide(TRUE);
- */
- }
-
- GameWindow *buttonBuddies = TheWindowManager->winGetWindowFromId(NULL, buttonBuddiesID);
- if (buttonBuddies)
- buttonBuddies->winEnable(TRUE);
-
- GameWindow *staticTextTitle = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch,
- NAMEKEY("WOLQuickMatchMenu.wnd:StaticTextTitle") );
- if (staticTextTitle)
- {
- UnicodeString tmp;
- tmp.format(TheGameText->fetch("GUI:QuickMatchTitle"), TheGameSpyInfo->getLocalName().str());
- GadgetStaticTextSetText(staticTextTitle, tmp);
- }
-
- // QM is not going yet, so disable the Widen Search button
- buttonWiden->winEnable( FALSE );
- buttonStop->winHide( TRUE );
- buttonStart->winHide( FALSE );
- GadgetListBoxReset(quickmatchTextWindow);
- enableOptionsGadgets(TRUE);
-
- // Show Menu
- layout->hide( FALSE );
-
- // Set Keyboard to Main Parent
- TheWindowManager->winSetFocus( parentWOLQuickMatch );
-
- // fill in preferences
- selectedImage = TheMappedImageCollection->findImageByName("CustomMatch_selected");
- unselectedImage = TheMappedImageCollection->findImageByName("CustomMatch_deselected");
- QuickMatchPreferences pref;
-
-
- UnicodeString s;
-// s.format(L"%d", pref.getMaxDisconnects());
-// GadgetTextEntrySetText(textEntryMaxDisconnects, s);
-// s.format(L"%d", pref.getMaxPoints());
-// GadgetTextEntrySetText(textEntryMaxPoints, s);
-// s.format(L"%d", pref.getMinPoints());
-// GadgetTextEntrySetText(textEntryMinPoints, s);
- //s.format(L"%d", pref.getWaitTime());
- //GadgetTextEntrySetText(textEntryWaitTime, s);
- maxPoints= pref.getMaxPoints();
- minPoints = pref.getMinPoints();
-
- Color c = GameSpyColor[GSCOLOR_DEFAULT];
- GadgetComboBoxReset( comboBoxNumPlayers );
- Int i;
- for (i=1; i<5; ++i)
- {
- s.format(TheGameText->fetch("GUI:PlayersVersusPlayers"), i, i);
- GadgetComboBoxAddEntry( comboBoxNumPlayers, s, c );
- }
- GadgetComboBoxSetSelectedPos( comboBoxNumPlayers, max(0, pref.getNumPlayers()) );
-
- GadgetComboBoxReset(comboBoxMaxDisconnects);
- GadgetComboBoxAddEntry( comboBoxMaxDisconnects, TheGameText->fetch("GUI:Any"), c);
- for( i = 1; i < MAX_DISCONNECTS_COUNT; ++i )
- {
- s.format(L"%d", MAX_DISCONNECTS[i]);
- GadgetComboBoxAddEntry( comboBoxMaxDisconnects, s, c );
- }
- Int maxDisconIndex = max(0, pref.getMaxDisconnects());
- GadgetComboBoxSetSelectedPos(comboBoxMaxDisconnects, maxDisconIndex);
-
- GadgetComboBoxReset( comboBoxMaxPing );
- maxPingEntries = (TheGameSpyConfig->getPingTimeoutInMs() - 1) / 100;
- maxPingEntries++; // need to add the entry for the actual timeout
- for (i=1; i fetch("GUI:TimeInMilliseconds"), i*100);
- GadgetComboBoxAddEntry( comboBoxMaxPing, s, c );
- }
- GadgetComboBoxAddEntry( comboBoxMaxPing, TheGameText->fetch("GUI:ANY"), c );
- i = pref.getMaxPing();
- if( i < 0 )
- i = 0;
- if( i >= maxPingEntries )
- i = maxPingEntries - 1;
- GadgetComboBoxSetSelectedPos( comboBoxMaxPing, i );
-
- populateQMColorComboBox(pref);
- populateQMSideComboBox(pref.getSide(), getLadderInfo());
-
- PopulateQMLadderComboBox();
- TheShell->showShellMap(TRUE);
- TheGameSpyGame->reset();
-
- GadgetListBoxReset(listboxMapSelect);
- populateQuickMatchMapSelectListbox(pref);
-
- UpdateLocalPlayerStats();
- UpdateStartButton();
- TheTransitionHandler->setGroup("WOLQuickMatchMenuFade");
- isInInit= FALSE;
-} // WOLQuickMatchMenuInit
-
-//-------------------------------------------------------------------------------------------------
-/** This is called when a shutdown is complete for this menu */
-//-------------------------------------------------------------------------------------------------
-static void shutdownComplete( WindowLayout *layout )
-{
-
- isShuttingDown = false;
-
- // hide the layout
- layout->hide( TRUE );
-
- // our shutdown is complete
- TheShell->shutdownComplete( layout, (nextScreen != NULL) );
-
- if (nextScreen != NULL)
- {
- TheShell->push(nextScreen);
- }
-
- nextScreen = NULL;
-
-} // end if
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Quick Match Menu shutdown method */
-//-------------------------------------------------------------------------------------------------
-void WOLQuickMatchMenuShutdown( WindowLayout *layout, void *userData )
-{
- TheGameSpyInfo->unregisterTextWindow(quickmatchTextWindow);
-
- if (!TheGameEngine->getQuitting())
- saveQuickMatchOptions();
-
- parentWOLQuickMatch = NULL;
- buttonBack = NULL;
- quickmatchTextWindow = NULL;
- selectedImage = unselectedImage = NULL;
-
- isShuttingDown = true;
-
- // if we are shutting down for an immediate pop, skip the animations
- Bool popImmediate = *(Bool *)userData;
- if( popImmediate )
- {
-
- shutdownComplete( layout );
- return;
-
- } //end if
-
- TheShell->reverseAnimatewindow();
- TheTransitionHandler->reverse("WOLQuickMatchMenuFade");
-
- RaiseGSMessageBox();
-} // WOLQuickMatchMenuShutdown
-
-
-#ifdef PERF_TEST
-static const char* getMessageString(Int t)
-{
- switch(t)
- {
- case PeerResponse::PEERRESPONSE_LOGIN:
- return "login";
- case PeerResponse::PEERRESPONSE_DISCONNECT:
- return "disconnect";
- case PeerResponse::PEERRESPONSE_MESSAGE:
- return "message";
- case PeerResponse::PEERRESPONSE_GROUPROOM:
- return "group room";
- case PeerResponse::PEERRESPONSE_STAGINGROOM:
- return "staging room";
- case PeerResponse::PEERRESPONSE_STAGINGROOMPLAYERINFO:
- return "staging room player info";
- case PeerResponse::PEERRESPONSE_JOINGROUPROOM:
- return "group room join";
- case PeerResponse::PEERRESPONSE_CREATESTAGINGROOM:
- return "staging room create";
- case PeerResponse::PEERRESPONSE_JOINSTAGINGROOM:
- return "staging room join";
- case PeerResponse::PEERRESPONSE_PLAYERJOIN:
- return "player join";
- case PeerResponse::PEERRESPONSE_PLAYERLEFT:
- return "player part";
- case PeerResponse::PEERRESPONSE_PLAYERCHANGEDNICK:
- return "player nick";
- case PeerResponse::PEERRESPONSE_PLAYERINFO:
- return "player info";
- case PeerResponse::PEERRESPONSE_PLAYERCHANGEDFLAGS:
- return "player flags";
- case PeerResponse::PEERRESPONSE_ROOMUTM:
- return "room UTM";
- case PeerResponse::PEERRESPONSE_PLAYERUTM:
- return "player UTM";
- case PeerResponse::PEERRESPONSE_QUICKMATCHSTATUS:
- return "QM status";
- case PeerResponse::PEERRESPONSE_GAMESTART:
- return "game start";
- case PeerResponse::PEERRESPONSE_FAILEDTOHOST:
- return "host failure";
- }
- return "unknown";
-}
-#endif // PERF_TEST
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Quick Match Menu update method */
-//-------------------------------------------------------------------------------------------------
-void WOLQuickMatchMenuUpdate( WindowLayout * layout, void *userData)
-{
- if (TheGameLogic->isInShellGame() && TheGameLogic->getFrame() == 1)
- {
- SignalUIInteraction(SHELL_SCRIPT_HOOK_GENERALS_ONLINE_ENTERED_FROM_GAME);
- }
-
- // We'll only be successful if we've requested to
- if(isShuttingDown && TheShell->isAnimFinished()&& TheTransitionHandler->isFinished())
- shutdownComplete(layout);
-
- if (raiseMessageBoxes)
- {
- RaiseGSMessageBox();
- raiseMessageBoxes = false;
- }
-
- /// @todo: MDC handle disconnects in-game the same way as Custom Match!
-
- if (TheShell->isAnimFinished() && !buttonPushed && TheGameSpyPeerMessageQueue)
- {
- HandleBuddyResponses();
- HandlePersistentStorageResponses();
-
- if (TheGameSpyGame && TheGameSpyGame->isGameInProgress())
- {
- if (TheGameSpyInfo->isDisconnectedAfterGameStart(NULL))
- {
- return; // already been disconnected, so don't worry.
- }
-
- Int allowedMessages = TheGameSpyInfo->getMaxMessagesPerUpdate();
- Bool sawImportantMessage = FALSE;
- PeerResponse resp;
- while (allowedMessages-- && !sawImportantMessage && TheGameSpyPeerMessageQueue->getResponse( resp ))
- {
- switch (resp.peerResponseType)
- {
- case PeerResponse::PEERRESPONSE_DISCONNECT:
- {
- sawImportantMessage = TRUE;
- AsciiString disconMunkee;
- disconMunkee.format("GUI:GSDisconReason%d", resp.discon.reason);
-
- // check for scorescreen
- NameKeyType listboxChatWindowScoreScreenID = NAMEKEY("ScoreScreen.wnd:ListboxChatWindowScoreScreen");
- GameWindow *listboxChatWindowScoreScreen = TheWindowManager->winGetWindowFromId( NULL, listboxChatWindowScoreScreenID );
- if (listboxChatWindowScoreScreen)
- {
- GadgetListBoxAddEntryText(listboxChatWindowScoreScreen, TheGameText->fetch(disconMunkee),
- GameSpyColor[GSCOLOR_DEFAULT], -1);
- }
- else
- {
- // still ingame
- TheInGameUI->message(disconMunkee);
- }
- TheGameSpyInfo->markAsDisconnectedAfterGameStart(resp.discon.reason);
- }
- }
- }
-
- return; // if we're in game, all we care about is if we've been disconnected from the chat server
- }
-
- if (TheNAT != NULL) {
- NATStateType NATState = TheNAT->update();
- if (NATState == NATSTATE_DONE)
- {
- TheGameSpyGame->launchGame();
- if (TheGameSpyInfo) // this can be blown away by a disconnect on the map transfer screen
- TheGameSpyInfo->leaveStagingRoom();
- return; // don't do any more processing this frame, in case the screen goes away
- }
- else if (NATState == NATSTATE_FAILED)
- {
- // delete TheNAT, its no good for us anymore.
- delete TheNAT;
- TheNAT = NULL;
-
- // Just back out. This cleans up some slot list problems
- buttonPushed = true;
- GSMessageBoxOk(TheGameText->fetch("GUI:Error"), TheGameText->fetch("GUI:NATNegotiationFailed"));
- nextScreen = "Menus/WOLWelcomeMenu.wnd";
- TheShell->pop();
- return; // don't do any more processing this frame, in case the screen goes away
- }
- }
-
-#ifdef PERF_TEST
- UnsignedInt start = timeGetTime();
- UnsignedInt end = timeGetTime();
- std::list responses;
- Int numMessages = 0;
-#endif // PERF_TEST
-
- Int allowedMessages = TheGameSpyInfo->getMaxMessagesPerUpdate();
- Bool sawImportantMessage = FALSE;
- PeerResponse resp;
- while (allowedMessages-- && !sawImportantMessage && TheGameSpyPeerMessageQueue->getResponse( resp ))
- {
-#ifdef PERF_TEST
- ++numMessages;
- responses.push_back(resp.peerResponseType);
-#endif // PERF_TEST
- switch (resp.peerResponseType)
- {
- case PeerResponse::PEERRESPONSE_PLAYERUTM:
- {
- if (!stricmp(resp.command.c_str(), "STATS"))
- {
- DEBUG_LOG(("Saw STATS from %s, data was '%s'\n", resp.nick.c_str(), resp.commandOptions.c_str()));
- AsciiString data = resp.commandOptions.c_str();
- AsciiString idStr;
- data.nextToken(&idStr, " ");
- Int id = atoi(idStr.str());
- DEBUG_LOG(("data: %d(%s) - '%s'\n", id, idStr.str(), data.str()));
-
- PSPlayerStats stats = TheGameSpyPSMessageQueue->parsePlayerKVPairs(data.str());
- PSPlayerStats oldStats = TheGameSpyPSMessageQueue->findPlayerStatsByID(id);
- stats.id = id;
- DEBUG_LOG(("Parsed ID is %d, old ID is %d\n", stats.id, oldStats.id));
- if (stats.id && (oldStats.id == 0))
- TheGameSpyPSMessageQueue->trackPlayerStats(stats);
-
- // now fill in the profileID in the game slot
- AsciiString nick = resp.nick.c_str();
- for (Int i=0; igetGameSpySlot(i);
- if (slot && slot->isHuman() && (slot->getLoginName().compareNoCase(nick) == 0))
- {
- slot->setProfileID(id);
- break;
- }
- }
- }
- Int slotNum = TheGameSpyGame->getSlotNum(resp.nick.c_str());
- if ((slotNum >= 0) && (slotNum < MAX_SLOTS) && (!stricmp(resp.command.c_str(), "NAT"))) {
- // this is a command for NAT negotiations, pass if off to TheNAT
- sawImportantMessage = TRUE;
- if (TheNAT != NULL) {
- TheNAT->processGlobalMessage(slotNum, resp.commandOptions.c_str());
- }
- }
- /*
- else if (key == "NAT")
- {
- if ((val >= FirewallHelperClass::FIREWALL_TYPE_SIMPLE) &&
- (val <= FirewallHelperClass::FIREWALL_TYPE_DESTINATION_PORT_DELTA))
- {
- slot->setNATBehavior((FirewallHelperClass::FirewallBehaviorType)val);
- DEBUG_LOG(("Setting NAT behavior to %d for player %d\n", val, slotNum));
- change = true;
- }
- else
- {
- DEBUG_LOG(("Rejecting invalid NAT behavior %d from player %d\n", val, slotNum));
- }
- }
- */
- }
- break;
-
- case PeerResponse::PEERRESPONSE_DISCONNECT:
- {
- sawImportantMessage = TRUE;
- UnicodeString title, body;
- AsciiString disconMunkee;
- disconMunkee.format("GUI:GSDisconReason%d", resp.discon.reason);
- title = TheGameText->fetch( "GUI:GSErrorTitle" );
- body = TheGameText->fetch( disconMunkee );
- GameSpyCloseAllOverlays();
- GSMessageBoxOk( title, body );
- TheGameSpyInfo->reset();
- TheShell->pop();
- }
- break; // LORENZEN ADDED. SORRY IF THIS "BREAKS" IT...
-
-
- case PeerResponse::PEERRESPONSE_JOINGROUPROOM:
- /*
- if (resp.joinGroupRoom.ok)
- {
- TheGameSpyInfo->addText(UnicodeString(L"Joined group room"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- }
- else
- {
- TheGameSpyInfo->addText(UnicodeString(L"Didn't join group room"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- }
- */
- break;
- case PeerResponse::PEERRESPONSE_PLAYERJOIN:
- {
- //UnicodeString str;
- //str.format(L"Player %hs joined the room", resp.nick.c_str());
- //TheGameSpyInfo->addText(str, GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- }
- break;
- case PeerResponse::PEERRESPONSE_PLAYERLEFT:
- {
- //UnicodeString str;
- //str.format(L"Player %hs left the room", resp.nick.c_str());
- //TheGameSpyInfo->addText(str, GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- }
- break;
- case PeerResponse::PEERRESPONSE_MESSAGE:
- {
- //UnicodeString m;
- //m.format(L"[%hs]: %ls", resp.nick.c_str(), resp.text.c_str());
- //TheGameSpyInfo->addText(m, GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- }
- break;
-
-
-// LORENZEN EXPRESSES DOUBT ABOUT THIS ONE, AS IT MAY HAVE SUFFERED MERGE MANGLING... SORRY
- // I THINK THIS IS THE OBSOLETE VERSION... SEE THE NEWER LOOKING ONE ABOVE
-/*
- case PeerResponse::PEERRESPONSE_DISCONNECT:
- {
- UnicodeString title, body;
- AsciiString disconMunkee;
- disconMunkee.format("GUI:GSDisconReason%d", resp.discon.reason);
- title = TheGameText->fetch( "GUI:GSErrorTitle" );
- body = TheGameText->fetch( disconMunkee );
- GameSpyCloseAllOverlays();
- GSMessageBoxOk( title, body );
- TheGameSpyInfo->reset();
- TheShell->pop();
- }
-*/
-
-
-
- case PeerResponse::PEERRESPONSE_CREATESTAGINGROOM:
- {
- if (resp.createStagingRoom.result == PEERJoinSuccess)
- {
- // Woohoo! On to our next screen!
- UnicodeString str;
- str.format(L"Created staging room");
- TheGameSpyInfo->addText(str, GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- }
- else
- {
- UnicodeString s;
- s.format(L"createStagingRoom result: %d", resp.createStagingRoom.result);
- TheGameSpyInfo->addText( s, GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow );
- }
- }
- break;
- case PeerResponse::PEERRESPONSE_JOINSTAGINGROOM:
- {
- if (resp.joinStagingRoom.ok == PEERTrue)
- {
- // Woohoo! On to our next screen!
- UnicodeString s;
- s.format(L"joinStagingRoom result: %d", resp.joinStagingRoom.ok);
- TheGameSpyInfo->addText( s, GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow );
- }
- else
- {
- UnicodeString s;
- s.format(L"joinStagingRoom result: %d", resp.joinStagingRoom.ok);
- TheGameSpyInfo->addText( s, GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow );
- }
- }
- break;
- case PeerResponse::PEERRESPONSE_STAGINGROOM:
- {
- UnicodeString str;
- str.format(L"Staging room list callback", resp.nick.c_str());
- TheGameSpyInfo->addText(str, GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- }
- break;
- case PeerResponse::PEERRESPONSE_QUICKMATCHSTATUS:
- {
- sawImportantMessage = TRUE;
- switch( resp.qmStatus.status )
- {
- case QM_IDLE:
- //TheGameSpyInfo->addText(UnicodeString(L"Status: QM_IDLE"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- break;
- case QM_JOININGQMCHANNEL:
- TheGameSpyInfo->addText(TheGameText->fetch("QM:JOININGQMCHANNEL"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- break;
- case QM_LOOKINGFORBOT:
- TheGameSpyInfo->addText(TheGameText->fetch("QM:LOOKINGFORBOT"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- break;
- case QM_SENTINFO:
- TheGameSpyInfo->addText(TheGameText->fetch("QM:SENTINFO"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- break;
- case QM_WORKING:
- {
- UnicodeString s;
- s.format(TheGameText->fetch("QM:WORKING"), resp.qmStatus.poolSize);
- TheGameSpyInfo->addText(s, GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- }
- buttonWiden->winEnable( TRUE );
- break;
- case QM_POOLSIZE:
- {
- UnicodeString s;
- s.format(TheGameText->fetch("QM:POOLSIZE"), resp.qmStatus.poolSize);
- TheGameSpyInfo->addText(s, GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- }
- break;
- case QM_WIDENINGSEARCH:
- TheGameSpyInfo->addText(TheGameText->fetch("QM:WIDENINGSEARCH"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- buttonWiden->winEnable( FALSE );
- break;
- case QM_MATCHED:
- {
- TheGameSpyInfo->addText(TheGameText->fetch("QM:MATCHED"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- buttonWiden->winEnable( FALSE );
-
- TheGameSpyGame->enterGame();
- TheGameSpyGame->setSeed(resp.qmStatus.seed);
-
- TheGameSpyGame->markGameAsQM();
-
- const LadderInfo *info = getLadderInfo();
- if (!info)
- {
- TheGameSpyGame->setLadderIP("localhost");
- TheGameSpyGame->setLadderPort(0);
- }
- else
- {
- TheGameSpyGame->setLadderIP(info->address);
- TheGameSpyGame->setLadderPort(info->port);
- }
-
- Int i;
- Int numPlayers = 0;
- for (i=0; i maps = TheGameSpyConfig->getQMMaps();
- for (std::list::const_iterator it = maps.begin(); it != maps.end(); ++it)
- {
- AsciiString theMap = *it;
- theMap.toLower();
- const MapMetaData *md = TheMapCache->findMap(theMap);
- if (md && md->m_numPlayers >= numPlayers)
- {
- TheGameSpyGame->setMap(*it);
- if (resp.qmStatus.mapIdx-- == 0)
- break;
- }
- }
-
- Int numPlayersPerTeam = numPlayers/2;
- DEBUG_ASSERTCRASH(numPlayersPerTeam, ("0 players per team???"));
- if (!numPlayersPerTeam)
- numPlayersPerTeam = 1;
-
- for (i=0; igetGameSpySlot(i);
- if (resp.stagingRoomPlayerNames[i].empty())
- {
- slot->setState(SLOT_CLOSED);
- }
- else
- {
- AsciiString aName = resp.stagingRoomPlayerNames[i].c_str();
- UnicodeString uName;
- uName.translate(aName);
- slot->setState(SLOT_PLAYER, uName, resp.qmStatus.IP[i]);
- slot->setColor(resp.qmStatus.color[i]);
- slot->setPlayerTemplate(resp.qmStatus.side[i]);
- //slot->setProfileID(0);
- slot->setNATBehavior((FirewallHelperClass::FirewallBehaviorType)resp.qmStatus.nat[i]);
- slot->setLocale("");
- slot->setTeamNumber( i/numPlayersPerTeam );
- if (i==0)
- TheGameSpyGame->setGameName(uName);
- }
- }
-
- DEBUG_LOG(("Starting a QM game: options=[%s]\n", GameInfoToAsciiString(TheGameSpyGame).str()));
- SendStatsToOtherPlayers(TheGameSpyGame);
- TheGameSpyGame->startGame(0);
- GameWindow *buttonBuddies = TheWindowManager->winGetWindowFromId(NULL, buttonBuddiesID);
- if (buttonBuddies)
- buttonBuddies->winEnable(FALSE);
- GameSpyCloseOverlay(GSOVERLAY_BUDDY);
- }
- break;
- case QM_INCHANNEL:
- TheGameSpyInfo->addText(TheGameText->fetch("QM:INCHANNEL"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- break;
- case QM_NEGOTIATINGFIREWALLS:
- TheGameSpyInfo->addText(TheGameText->fetch("QM:NEGOTIATINGFIREWALLS"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- break;
- case QM_STARTINGGAME:
- TheGameSpyInfo->addText(TheGameText->fetch("QM:STARTINGGAME"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- break;
- case QM_COULDNOTFINDBOT:
- TheGameSpyInfo->addText(TheGameText->fetch("QM:COULDNOTFINDBOT"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- buttonWiden->winEnable( FALSE );
- buttonStart->winHide( FALSE );
- buttonStop->winHide( TRUE );
- enableOptionsGadgets(TRUE);
- break;
- case QM_COULDNOTFINDCHANNEL:
- TheGameSpyInfo->addText(TheGameText->fetch("QM:COULDNOTFINDCHANNEL"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- buttonWiden->winEnable( FALSE );
- buttonStart->winHide( FALSE );
- buttonStop->winHide( TRUE );
- enableOptionsGadgets(TRUE);
- break;
- case QM_COULDNOTNEGOTIATEFIREWALLS:
- TheGameSpyInfo->addText(TheGameText->fetch("QM:COULDNOTNEGOTIATEFIREWALLS"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- buttonWiden->winEnable( FALSE );
- buttonStart->winHide( FALSE );
- buttonStop->winHide( TRUE );
- enableOptionsGadgets(TRUE);
- break;
- case QM_STOPPED:
- TheGameSpyInfo->addText(TheGameText->fetch("QM:STOPPED"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- buttonWiden->winEnable( FALSE );
- buttonStart->winHide( FALSE );
- buttonStop->winHide( TRUE );
- enableOptionsGadgets(TRUE);
- break;
- }
- }
- break;
- }
- }
-#ifdef PERF_TEST
- // check performance
- end = timeGetTime();
- UnsignedInt frameTime = end-start;
- if (frameTime > 100 || responses.size() > 20)
- {
- UnicodeString munkee;
- munkee.format(L"inQM:%d %d ms, %d messages", s_inQM, frameTime, responses.size());
- TheGameSpyInfo->addText(munkee, GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- PERF_LOG(("%ls\n", munkee.str()));
-
- std::list::const_iterator it;
- for (it = responses.begin(); it != responses.end(); ++it)
- {
- PERF_LOG((" %s\n", getMessageString(*it)));
- }
- }
-#endif // PERF_TEST
- }
-}// WOLQuickMatchMenuUpdate
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Quick Match Menu input callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLQuickMatchMenuInput( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- switch( msg )
- {
-
- // --------------------------------------------------------------------------------------------
- case GWM_CHAR:
- {
- UnsignedByte key = mData1;
- UnsignedByte state = mData2;
- if (buttonPushed)
- break;
-
- switch( key )
- {
-
- // ----------------------------------------------------------------------------------------
- case KEY_ESC:
- {
-
- //
- // send a simulated selected event to the parent window of the
- // back/exit button
- //
- if( BitTest( state, KEY_STATE_UP ) )
- {
- if(!buttonBack->winIsHidden())
- TheWindowManager->winSendSystemMsg( window, GBM_SELECTED,
- (WindowMsgData)buttonBack, buttonBackID );
-
- } // end if
-
- // don't let key fall through anywhere else
- return MSG_HANDLED;
-
- } // end escape
-
- } // end switch( key )
-
- } // end char
-
- } // end switch( msg )
-
- return MSG_IGNORED;
-}// WOLQuickMatchMenuInput
-
-//-------------------------------------------------------------------------------------------------
-/** WOL Quick Match Menu window system callback */
-//-------------------------------------------------------------------------------------------------
-WindowMsgHandledType WOLQuickMatchMenuSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
-{
- UnicodeString txtInput;
-
- switch( msg )
- {
-
-
- case GWM_CREATE:
- {
-
- break;
- } // case GWM_DESTROY:
-
- case GWM_DESTROY:
- {
- break;
- } // case GWM_DESTROY:
-
- case GWM_INPUT_FOCUS:
- {
- // if we're givin the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
-
- return MSG_HANDLED;
- }//case GWM_INPUT_FOCUS:
-
- case GCM_SELECTED:
- {
- if (buttonPushed)
- break;
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- Int pos = -1;
- GadgetComboBoxGetSelectedPos(control, &pos);
-
- saveQuickMatchOptions();
- if (controlID == comboBoxLadderID && !isPopulatingLadderBox)
- {
- if (pos >= 0)
- {
- QuickMatchPreferences pref;
- Int ladderID = (Int)GadgetComboBoxGetItemData(control, pos);
- if (ladderID == 0)
- {
- // no ladder selected - enable buttons
- GadgetComboBoxSetSelectedPos(comboBoxNumPlayers, max(0, pref.getNumPlayers()/2-1));
- comboBoxNumPlayers->winEnable( TRUE );
- populateQMSideComboBox(pref.getSide()); // this will set side to random and disable if necessary
- }
- else if (ladderID > 0)
- {
- // ladder selected - disable buttons
- const LadderInfo *li = TheLadderList->findLadderByIndex(ladderID);
- if (li)
- GadgetComboBoxSetSelectedPos(comboBoxNumPlayers, li->playersPerTeam-1);
- else
- GadgetComboBoxSetSelectedPos(comboBoxNumPlayers, 0);
- comboBoxNumPlayers->winEnable( FALSE );
-
- populateQMSideComboBox(pref.getSide(), li); // this will set side to random and disable if necessary
- }
- else
- {
- // "Choose a ladder" selected - open overlay
- PopulateQMLadderComboBox(); // this restores the non-"Choose a ladder" selection
- GameSpyOpenOverlay( GSOVERLAY_LADDERSELECT );
- }
- }
- }
- if (!isInInit)
- {
- QuickMatchPreferences pref;
- populateQuickMatchMapSelectListbox(pref);
- UpdateStartButton();
- }
- break;
- } // case GCM_SELECTED
-
- case GBM_SELECTED:
- {
- if (buttonPushed)
- break;
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- static NameKeyType buttonOptionsID = NAMEKEY("WOLQuickMatchMenu.wnd:ButtonOptions");
-
- if ( controlID == buttonStopID )
- {
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_STOPQUICKMATCH;
- TheGameSpyPeerMessageQueue->addRequest(req);
- buttonWiden->winEnable( FALSE );
- buttonStart->winHide( FALSE );
- buttonStop->winHide( TRUE );
- enableOptionsGadgets(TRUE);
- TheGameSpyInfo->addText(TheGameText->fetch("GUI:QMAborted"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow);
- }
- else if ( controlID == buttonOptionsID )
- {
- GameWindow *win =TheWindowManager->winGetWindowFromId(parentWOLQuickMatch,buttonOptionsID);
- if (isInfoShown())
- {
- hideInfoGadgets(TRUE);
- hideOptionsGadgets(FALSE);
- GadgetButtonSetText(win, TheGameText->fetch("GUI:PlayerInfo"));
- }
- else
- {
- hideInfoGadgets(FALSE);
- hideOptionsGadgets(TRUE);
- GadgetButtonSetText(win, TheGameText->fetch("GUI:Setup"));
- }
- }
- else if ( controlID == buttonWidenID )
- {
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_WIDENQUICKMATCHSEARCH;
- TheGameSpyPeerMessageQueue->addRequest(req);
- buttonWiden->winEnable( FALSE );
- }
- else if ( controlID == buttonStartID )
- {
- PeerRequest req;
- req.peerRequestType = PeerRequest::PEERREQUEST_STARTQUICKMATCH;
- req.qmMaps.clear();
- Int numMaps = GadgetListBoxGetNumEntries(listboxMapSelect);
- for ( Int i=0; i= maxPingEntries - 1)
- {
- req.QM.maxPing = TheGameSpyConfig->getPingTimeoutInMs();
- }
- else
- req.QM.maxPing = (val+1)*100;
-
- PSPlayerStats stats = TheGameSpyPSMessageQueue->findPlayerStatsByID(TheGameSpyInfo->getLocalProfileID());
- req.QM.points = CalculateRank(stats);
-
- Int ladderIndex, index, selected;
- GadgetComboBoxGetSelectedPos( comboBoxLadder, &selected );
- ladderIndex = (Int)GadgetComboBoxGetItemData( comboBoxLadder, selected );
- const LadderInfo *ladderInfo = NULL;
- if (ladderIndex < 0)
- {
- ladderIndex = 0;
- }
- if (ladderIndex)
- {
- ladderInfo = TheLadderList->findLadderByIndex( ladderIndex );
- if (!ladderInfo)
- {
- ladderIndex = 0; // sanity
- }
- }
- req.QM.ladderID = ladderIndex;
-
- req.QM.ladderPassCRC = 0;
-
- index = -1;
- GadgetComboBoxGetSelectedPos( comboBoxSide, &selected );
- if (selected >= 0)
- index = (Int)GadgetComboBoxGetItemData( comboBoxSide, selected );
- req.QM.side = index;
- if (ladderInfo && ladderInfo->randomFactions)
- {
- Int sideNum = GameClientRandomValue(0, ladderInfo->validFactions.size()-1);
- DEBUG_LOG(("Looking for %d out of %d random sides\n", sideNum, ladderInfo->validFactions.size()));
- AsciiStringListConstIterator cit = ladderInfo->validFactions.begin();
- while (sideNum)
- {
- ++cit;
- --sideNum;
- }
- if (cit != ladderInfo->validFactions.end())
- {
- Int numPlayerTemplates = ThePlayerTemplateStore->getPlayerTemplateCount();
- AsciiString sideStr = *cit;
- DEBUG_LOG(("Chose %s as our side... finding\n", sideStr.str()));
- for (Int c=0; cgetNthPlayerTemplate(c);
- if (fac && fac->getSide() == sideStr)
- {
- DEBUG_LOG(("Found %s in index %d\n", sideStr.str(), c));
- req.QM.side = c;
- break;
- }
- }
- }
- }
- else if( index == PLAYERTEMPLATE_RANDOM )
- {
- // If not a forced random ladder, then we need to resolve our pick of random right now anyway, or else
- // we will get the same pick every darn time.
- Int randomTries = 0;// Rare to hit Random 10 times in a row, but if it does then random will be converted to a set side by the very bug this tries to fix, so no harm done.
-
- while( randomTries < 10 && index == PLAYERTEMPLATE_RANDOM )
- {
- Int numberComboBoxEntries = GadgetComboBoxGetLength(comboBoxSide);
- Int randomPick = GameClientRandomValue(0, numberComboBoxEntries - 1);
- index = (Int)GadgetComboBoxGetItemData( comboBoxSide, randomPick );
- req.QM.side = index;
-
- randomTries++;
- }
- }
-
- index = -1;
- GadgetComboBoxGetSelectedPos( comboBoxColor, &selected );
- if (selected >= 0)
- index = (Int)GadgetComboBoxGetItemData( comboBoxColor, selected );
- req.QM.color = index;
-
- OptionPreferences natPref;
- req.QM.NAT = natPref.getFirewallBehavior();
-
- if (ladderIndex)
- {
- req.QM.numPlayers = (ladderInfo)?ladderInfo->playersPerTeam*2 : 2;
- }
- else
- {
- GadgetComboBoxGetSelectedPos(comboBoxNumPlayers, &val);
- if (val < 0)
- val = 0;
- req.QM.numPlayers = (val+1)*2;
- }
-
- Int numDiscons = 0;
- PerGeneralMap::iterator it;
- for(it =stats.discons.begin(); it != stats.discons.end(); ++it)
- {
- numDiscons += it->second;
- }
- for(it =stats.desyncs.begin(); it != stats.desyncs.end(); ++it)
- {
- numDiscons += it->second;
- }
- req.QM.discons = numDiscons;
-
-
- strncpy(req.QM.pings, TheGameSpyInfo->getPingString().str(), 17);
- req.QM.pings[16] = 0;
-
- req.QM.botID = TheGameSpyConfig->getQMBotID();
- req.QM.roomID = TheGameSpyConfig->getQMChannel();
-
- req.QM.exeCRC = TheGlobalData->m_exeCRC;
- req.QM.iniCRC = TheGlobalData->m_iniCRC;
-
- TheGameSpyPeerMessageQueue->addRequest(req);
- buttonWiden->winEnable( FALSE );
- buttonStart->winHide( TRUE );
- buttonStop->winHide( FALSE );
- enableOptionsGadgets(FALSE);
-
- if (ladderIndex > 0)
- {
- // save the ladder as being played upon even if we cancel out of matching early...
- LadderPreferences ladPref;
- ladPref.loadProfile( TheGameSpyInfo->getLocalProfileID() );
- LadderPref p;
- p.lastPlayDate = time(NULL);
- p.address = ladderInfo->address;
- p.port = ladderInfo->port;
- p.name = ladderInfo->name;
- ladPref.addRecentLadder( p );
- ladPref.write();
- }
- }
- else if ( controlID == buttonBuddiesID )
- {
- GameSpyToggleOverlay( GSOVERLAY_BUDDY );
- }
- else if ( controlID == buttonBackID )
- {
- buttonPushed = true;
- TheGameSpyInfo->leaveGroupRoom();
- nextScreen = "Menus/WOLWelcomeMenu.wnd";
- TheShell->pop();
- } //if ( controlID == buttonBack )
- else if ( controlID == buttonSelectAllMapsID )
- {
- Int numMaps = GadgetListBoxGetNumEntries(listboxMapSelect);
- for ( Int i=0; iwinGetWindowId();
- Int selected = (Int)mData2;
-
- if ( controlID == listboxMapSelectID )
- {
- const LadderInfo *li = getLadderInfo();
- if (selected >= 0 && (!li || !li->randomMaps))
- {
- Bool wasSelected = (Bool)GadgetListBoxGetItemData(control, selected, 0);
- GadgetListBoxSetItemData(control, (void *)(!wasSelected), selected, 0);
- Int width = 10;
- Int height = 10;
- const Image *img = (!wasSelected)?selectedImage:unselectedImage;
- if ( img )
- {
- width = min(GadgetListBoxGetColumnWidth(control, 0), img->getImageWidth());
- height = width;
- }
- GadgetListBoxAddEntryImage(control, img, selected, 0, height, width);
- GadgetListBoxAddEntryText(control, GadgetListBoxGetText(control, selected, 1), GameSpyColor[(wasSelected)?GSCOLOR_MAP_UNSELECTED:GSCOLOR_MAP_SELECTED], selected, 1);
- }
- if (selected >= 0)
- GadgetListBoxSetSelected(control, -1);
- }
- UpdateStartButton();
- break;
- }// case GLM_SELECTED
-
- case GEM_EDIT_DONE:
- {
- break;
- }
- default:
- return MSG_IGNORED;
-
- }//Switch
-
- return MSG_HANDLED;
-}// WOLQuickMatchMenuSystem
diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLStatusMenu.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLStatusMenu.cpp
deleted file mode 100644
index e951b7ed935..00000000000
--- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLStatusMenu.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
-** Command & Conquer Generals Zero Hour(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see