From 4ded1b0800d8135e4d43ccfc4359e0b22d703b9d Mon Sep 17 00:00:00 2001 From: MrS-ibra Date: Sat, 24 Jan 2026 15:17:42 +0300 Subject: [PATCH 1/2] CR LF --- .../GUICallbacks/Menus/WOLQuickMatchMenu.cpp | 866 +++++++++--------- 1 file changed, 433 insertions(+), 433 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQuickMatchMenu.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQuickMatchMenu.cpp index 0d2ac3efd4..3448dd3c55 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQuickMatchMenu.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQuickMatchMenu.cpp @@ -29,7 +29,7 @@ /////////////////////////////////////////////////////////////////////////////////////// // INCLUDES /////////////////////////////////////////////////////////////////////////////////////// -#include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine +#include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine #include "Common/GameEngine.h" #include "Common/QuickmatchPreferences.h" @@ -114,33 +114,33 @@ static NameKeyType comboBoxColorID = NAMEKEY_INVALID; // Window Pointers ------------------------------------------------------------------------ -static GameWindow *parentWOLQuickMatch = nullptr; -static GameWindow *buttonBack = nullptr; -static GameWindow *buttonStart = nullptr; -static GameWindow *buttonStop = nullptr; -static GameWindow *buttonWiden = nullptr; -GameWindow *quickmatchTextWindow = nullptr; -static GameWindow *listboxMapSelect = nullptr; -//static GameWindow *textEntryMaxDisconnects = nullptr; -//static GameWindow *textEntryMaxPoints = nullptr; -//static GameWindow *textEntryMinPoints = nullptr; -static GameWindow *textEntryWaitTime = nullptr; -static GameWindow *comboBoxNumPlayers = nullptr; -static GameWindow *comboBoxMaxPing = nullptr; -static GameWindow *comboBoxLadder = nullptr; -static GameWindow *comboBoxDisabledLadder = nullptr; // enable and disable this, but never use it. it is a stand-in for comboBoxLadder for when there are no ladders -static GameWindow *comboBoxMaxDisconnects = nullptr; -static GameWindow *staticTextNumPlayers = nullptr; -static GameWindow *comboBoxSide = nullptr; -static GameWindow *comboBoxColor = nullptr; +static GameWindow *parentWOLQuickMatch = nullptr; +static GameWindow *buttonBack = nullptr; +static GameWindow *buttonStart = nullptr; +static GameWindow *buttonStop = nullptr; +static GameWindow *buttonWiden = nullptr; +GameWindow *quickmatchTextWindow = nullptr; +static GameWindow *listboxMapSelect = nullptr; +//static GameWindow *textEntryMaxDisconnects = nullptr; +//static GameWindow *textEntryMaxPoints = nullptr; +//static GameWindow *textEntryMinPoints = nullptr; +static GameWindow *textEntryWaitTime = nullptr; +static GameWindow *comboBoxNumPlayers = nullptr; +static GameWindow *comboBoxMaxPing = nullptr; +static GameWindow *comboBoxLadder = nullptr; +static GameWindow *comboBoxDisabledLadder = nullptr; // enable and disable this, but never use it. it is a stand-in for comboBoxLadder for when there are no ladders +static GameWindow *comboBoxMaxDisconnects = nullptr; +static GameWindow *staticTextNumPlayers = nullptr; +static GameWindow *comboBoxSide = nullptr; +static GameWindow *comboBoxColor = nullptr; static Bool isShuttingDown = false; static Bool buttonPushed = false; -static const char *nextScreen = nullptr; +static const char *nextScreen = nullptr; static Bool raiseMessageBoxes = false; static Bool isInInit = FALSE; -static const Image *selectedImage = nullptr; -static const Image *unselectedImage = nullptr; +static const Image *selectedImage = nullptr; +static const Image *unselectedImage = nullptr; static bool isPopulatingLadderBox = false; static Int maxPingEntries = 0; @@ -223,7 +223,7 @@ static void enableOptionsGadgets(Bool doIt) } } -enum +enum { MAX_DISCONNECTS_ANY = 0, MAX_DISCONNECTS_5 = 5, @@ -233,11 +233,11 @@ enum }; enum{ MAX_DISCONNECTS_COUNT = 5 }; -static Int MAX_DISCONNECTS[MAX_DISCONNECTS_COUNT] = {MAX_DISCONNECTS_ANY, MAX_DISCONNECTS_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) @@ -294,7 +294,7 @@ static void populateQMColorComboBox(QuickMatchPreferences& pref) // ----------------------------------------------------------------------------- -static void populateQMSideComboBox(Int favSide, const LadderInfo *li = nullptr) +static void populateQMSideComboBox(Int favSide, const LadderInfo *li = nullptr) { Int numPlayerTemplates = ThePlayerTemplateStore->getPlayerTemplateCount(); UnicodeString playerTemplateName; @@ -306,7 +306,7 @@ static void populateQMSideComboBox(Int favSide, const LadderInfo *li = nullptr) GadgetComboBoxSetItemData(comboBoxSide, newIndex, (void *)PLAYERTEMPLATE_RANDOM); std::set seenSides; - + Int entryToSelect = 0; // select Random by default for (Int c=0; cfetch("GUI:NoLadder"), normalColor, -1 ); - GadgetListBoxSetItemData( win, nullptr, index ); + GadgetListBoxSetItemData( win, nullptr, index ); // add the last ladder Int selectedPos = 0; @@ -532,7 +532,7 @@ void PopulateQMLadderComboBox( void ) Int index; GadgetComboBoxReset( comboBoxLadder ); index = GadgetComboBoxAddEntry( comboBoxLadder, TheGameText->fetch("GUI:NoLadder"), normalColor ); - GadgetComboBoxSetItemData( comboBoxLadder, index, nullptr ); + GadgetComboBoxSetItemData( comboBoxLadder, index, nullptr ); std::set usedLadders; @@ -586,9 +586,9 @@ void PopulateQMLadderComboBox( void ) static void populateQuickMatchMapSelectListbox( QuickMatchPreferences& pref ) { NetworkLog(ELogVerbosity::LOG_DEBUG, "Begin Map Dump"); - for (auto it = TheMapCache->begin(); it != TheMapCache->end(); ++it) - { - if (it->second.m_isOfficial && it->second.m_isMultiplayer) + for (auto it = TheMapCache->begin(); it != TheMapCache->end(); ++it) + { + if (it->second.m_isOfficial && it->second.m_isMultiplayer) { NetworkLog(ELogVerbosity::LOG_DEBUG, "%ls - %s", it->second.m_displayName.str(), it->second.m_fileName.str()); } @@ -656,7 +656,7 @@ static void populateQuickMatchMapSelectListbox( QuickMatchPreferences& pref ) GadgetComboBoxGetSelectedPos( comboBoxLadder, &selected ); index = (Int)GadgetComboBoxGetItemData( comboBoxLadder, selected ); const LadderInfo *li = TheLadderList->findLadderByIndex( index ); - //listboxMapSelect->winEnable( li == nullptr || li->randomMaps == FALSE ); + //listboxMapSelect->winEnable( li == nullptr || li->randomMaps == FALSE ); // GO does this differently (and does it above) #if !defined(GENERALS_ONLINE) @@ -859,19 +859,19 @@ void WOLQuickMatchMenuInit( WindowLayout *layout, void *userData ) GameSpyCloseAllOverlays(); GSMessageBoxOk( title, body ); TheGameSpyInfo->reset(); - DEBUG_LOG(("WOLQuickMatchMenuInit() - game was in progress, and we were disconnected, so pop immediate back to main menu")); + DEBUG_LOG(("WOLQuickMatchMenuInit() - game was in progress, and we were disconnected, so pop immediate back to main menu")); TheShell->popImmediate(); return; } } - nextScreen = nullptr; + nextScreen = nullptr; buttonPushed = false; isShuttingDown = false; raiseMessageBoxes = true; - delete TheNAT; - TheNAT = nullptr; + delete TheNAT; + TheNAT = nullptr; parentWOLQuickMatchID = NAMEKEY( "WOLQuickMatchMenu.wnd:WOLQuickMatchMenuParent" ); buttonBackID = NAMEKEY( "WOLQuickMatchMenu.wnd:ButtonBack" ); @@ -895,7 +895,7 @@ void WOLQuickMatchMenuInit( WindowLayout *layout, void *userData ) comboBoxSideID = NAMEKEY( "WOLQuickMatchMenu.wnd:ComboBoxSide" ); comboBoxColorID = NAMEKEY( "WOLQuickMatchMenu.wnd:ComboBoxColor" ); - parentWOLQuickMatch = TheWindowManager->winGetWindowFromId( nullptr, parentWOLQuickMatchID ); + parentWOLQuickMatch = TheWindowManager->winGetWindowFromId( nullptr, parentWOLQuickMatchID ); buttonBack = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, buttonBackID); buttonStart = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, buttonStartID); buttonStop = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, buttonStopID); @@ -918,30 +918,30 @@ void WOLQuickMatchMenuInit( WindowLayout *layout, void *userData ) comboBoxSide = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, comboBoxSideID ); comboBoxColor = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, comboBoxColorID ); - if (TheLadderList->getStandardLadders()->empty() - && TheLadderList->getSpecialLadders()->empty() - && TheLadderList->getLocalLadders()->empty()) + if (TheLadderList->getStandardLadders()->empty() + && TheLadderList->getSpecialLadders()->empty() + && TheLadderList->getLocalLadders()->empty()) { // no ladders, so just disable them comboBoxDisabledLadder = comboBoxLadder; - comboBoxLadder = nullptr; + comboBoxLadder = nullptr; isPopulatingLadderBox = TRUE; - Color normalColor = GameSpyColor[GSCOLOR_MAP_UNSELECTED]; - Int index; - GadgetComboBoxReset( comboBoxDisabledLadder ); - -#if defined(GENERALS_ONLINE) - index = GadgetComboBoxAddEntry(comboBoxDisabledLadder, UnicodeString(L"Automatic Ladder"), normalColor); -#else - index = GadgetComboBoxAddEntry( comboBoxDisabledLadder, TheGameText->fetch("GUI:NoLadder"), normalColor ); -#endif - GadgetComboBoxSetItemData( comboBoxDisabledLadder, index, 0 ); - GadgetComboBoxSetSelectedPos( comboBoxDisabledLadder, index ); - - isPopulatingLadderBox = FALSE; - + Color normalColor = GameSpyColor[GSCOLOR_MAP_UNSELECTED]; + Int index; + GadgetComboBoxReset( comboBoxDisabledLadder ); + +#if defined(GENERALS_ONLINE) + index = GadgetComboBoxAddEntry(comboBoxDisabledLadder, UnicodeString(L"Automatic Ladder"), normalColor); +#else + index = GadgetComboBoxAddEntry( comboBoxDisabledLadder, TheGameText->fetch("GUI:NoLadder"), normalColor ); +#endif + 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) @@ -949,7 +949,7 @@ void WOLQuickMatchMenuInit( WindowLayout *layout, void *userData ) comboBoxLadder->winHide(TRUE); comboBoxLadder->winEnable(FALSE); } - comboBoxLadder = nullptr; + comboBoxLadder = nullptr; GameWindow *staticTextLadder = TheWindowManager->winGetWindowFromId( parentWOLQuickMatch, NAMEKEY("WOLQuickMatchMenu.wnd:StaticTextLadder") ); if (staticTextLadder) @@ -957,7 +957,7 @@ void WOLQuickMatchMenuInit( WindowLayout *layout, void *userData ) */ } - GameWindow *buttonBuddies = TheWindowManager->winGetWindowFromId(nullptr, buttonBuddiesID); + GameWindow *buttonBuddies = TheWindowManager->winGetWindowFromId(nullptr, buttonBuddiesID); if (buttonBuddies) buttonBuddies->winEnable(TRUE); @@ -1059,301 +1059,301 @@ void WOLQuickMatchMenuInit( WindowLayout *layout, void *userData ) #if defined(GENERALS_ONLINE) if (TheNGMPGame != nullptr) - TheNGMPGame->reset(); - - GadgetListBoxReset(listboxMapSelect); - populateQuickMatchMapSelectListbox(pref); - - UpdateLocalPlayerStats(); - UpdateStartButton(); - TheTransitionHandler->setGroup("WOLQuickMatchMenuFade"); - isInInit= FALSE; -#endif - -#if defined(GENERALS_ONLINE) - buttonStart->winEnable(TRUE); - buttonStart->winSetText(UnicodeString(L"START MATCHMAKING")); - buttonStop->winSetText(UnicodeString(L"CANCEL MATCHMAKING")); - buttonBack->winEnable(TRUE); - - // not supported in GO - if (comboBoxLadder) - comboBoxLadder->winEnable(FALSE); - if (comboBoxDisabledLadder) - comboBoxDisabledLadder->winEnable(FALSE); - if (comboBoxMaxPing) - comboBoxMaxPing->winEnable(FALSE); - if (comboBoxMaxDisconnects) - comboBoxMaxDisconnects->winEnable(FALSE); - - // welcome msg + instructions - GadgetListBoxAddEntryText(quickmatchTextWindow, UnicodeString(L"Welcome to QuickMatch. Choose Setup to select playlists and maps."), GameMakeColor(255, 194, 25, 255), -1, -1); - GadgetListBoxAddEntryText(quickmatchTextWindow, UnicodeString(L"Special thanks to map makers Tanso, ReLaX, cncHD, Specovik, Mp3, Jundiyy & Bamovich for making quickmatch possible."), GameMakeColor(255, 194, 25, 255), -1, -1); - - - // refresh out stats, needed for ELO data - NGMP_OnlineServices_AuthInterface* pAuthInterface = NGMP_OnlineServicesManager::GetInterface(); - NGMP_OnlineServices_StatsInterface* pStatsInterface = NGMP_OnlineServicesManager::GetInterface(); - if (pAuthInterface != nullptr && pStatsInterface != nullptr) - { - pStatsInterface->findPlayerStatsByID(pAuthInterface->GetUserID(), [=](bool bSuccess, PSPlayerStats stats) - { - UnicodeString eloStr; - eloStr.format(L"Your current Elo rating is %d after %d match(es)", stats.elo_rating, stats.elo_num_matches); - GadgetListBoxAddEntryText(quickmatchTextWindow, eloStr, GameMakeColor(255, 194, 25, 255), -1, -1); - }, EStatsRequestPolicy::BYPASS_CACHE_FORCE_REQUEST); - } - -#endif - -#if defined(GENERALS_ONLINE) - NGMP_OnlineServices_LobbyInterface* pLobbyInterface = NGMP_OnlineServicesManager::GetInterface(); - - // cannot connect to the lobby we joined - pLobbyInterface->RegisterForCannotConnectToLobbyCallback([](void) - { - // TODO_QUICKMATCH: Show error message + stop matchmaking + enable buttons again - }); - - // get playlist list - NGMP_OnlineServices_MatchmakingInterface* pMatchmakingInterface = NGMP_OnlineServicesManager::GetInterface(); - if (pMatchmakingInterface != nullptr) - { - pMatchmakingInterface->RetrievePlaylists([](std::vector vecPlaylists) - { - // add playlists - UnicodeString s; - - // clear ui element - GadgetComboBoxReset(comboBoxNumPlayers); - - - for (PlaylistEntry& playlist : vecPlaylists) - { - s.format(L"%hs", playlist.Name.c_str()); - GadgetComboBoxAddEntry(comboBoxNumPlayers, s, GameSpyColor[GSCOLOR_DEFAULT]); - } - - GadgetComboBoxSetSelectedPos(comboBoxNumPlayers, 0); - }); - } -#endif - - - if (pLobbyInterface != nullptr) - { - // TODO_QUICKMATCH: Deregister when leaving QM - pLobbyInterface->RegisterForMatchmakingMessageCallback([](std::string strMsg) - { - UnicodeString uMsg; - uMsg.format(L"%hs", strMsg.c_str()); - - Int index = GadgetListBoxAddEntryText(quickmatchTextWindow, uMsg, GameSpyColor[GSCOLOR_DEFAULT], -1, -1); - GadgetListBoxSetItemData(quickmatchTextWindow, (void*)-1, index); - }); - - pLobbyInterface->RegisterForMatchmakingMatchFoundCallback([]() - { - buttonStop->winEnable(FALSE); - }); - - pLobbyInterface->RegisterForMatchmakingStartGameCallback([]() - { - NetworkLog(ELogVerbosity::LOG_DEBUG, "[QUICKMATCH] GOT START GAME EVENT"); - - // Check if TheNGMPGame is initialized before dereferencing it - if (!TheNGMPGame) - { - NetworkLog(ELogVerbosity::LOG_DEBUG, "[QUICKMATCH] NO NGMP GAME INSTANCE"); - return; - } - - // mark everyone as having the map, we dont allow user provided custom maps or map transfers in QM - // TODO_QUICKMATCH: Do this automatically for game type quickmatch, or better yet, do it on the service - for (int i = 0; i < MAX_SLOTS; i++) - { - GameSlot* slot = TheNGMPGame->getSlot(i); - if (slot != nullptr) - { - slot->setMapAvailability(TRUE); - } - } - - // start - NGMP_OnlineServices_LobbyInterface* pLobbyInterface = NGMP_OnlineServicesManager::GetInterface(); - NGMPGame* myGame = pLobbyInterface == nullptr ? nullptr : pLobbyInterface->GetCurrentGame(); - - if (pLobbyInterface == nullptr || !myGame || !myGame->isInGame()) - { - NetworkLog(ELogVerbosity::LOG_DEBUG, "[QUICKMATCH] Checks failed, %d, %d, %d", pLobbyInterface == nullptr, !myGame, !myGame->isInGame()); - return; - } - - - // TODO_NGMP - //SendStatsToOtherPlayers(TheNGMPGame); - - // 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); - - *TheNGMPGame = *myGame; - TheNGMPGame->startGame(0); - }); - - pLobbyInterface->RegisterForJoinLobbyCallback([](EJoinLobbyResult result) - { - NGMP_OnlineServices_LobbyInterface* pLobbyInterface = NGMP_OnlineServicesManager::GetInterface(); - - if (!pLobbyInterface->IsInLobby()) - { - return; - } - - if (TheNGMPGame == nullptr) - { - TheNGMPGame = new NGMPGame(); - TheNGMPGame->markGameAsQM(); - } - pLobbyInterface->UpdateRoomDataCache([]() - { - - }); - - // connection events (for debug really) - NetworkMesh* pMesh = NGMP_OnlineServicesManager::GetNetworkMesh(); - if (pMesh != nullptr) - { - pMesh->RegisterForConnectionEvents([](int64_t userID, std::wstring strDisplayName, PlayerConnection* connection) - { -#if _DEBUG // not enabled in quickmatch because then people see their opponent during matchmaking - std::string strState = "Unknown"; - - EConnectionState connState = connection->GetState(); - std::string strConnectionType = connection->GetConnectionType(); - - switch (connState) - { - case EConnectionState::NOT_CONNECTED: - strState = "Not Connected"; - break; - - case EConnectionState::CONNECTING_DIRECT: - strState = "Connecting"; - break; - case EConnectionState::FINDING_ROUTE: - strState = "Connecting (Finding Route)"; - break; - - case EConnectionState::CONNECTED_DIRECT: - strState = "Connected"; - break; - - case EConnectionState::CONNECTION_FAILED: - strState = "Connection Failed"; - break; - - case EConnectionState::CONNECTION_DISCONNECTED: - strState = "Disconnected (Was Connected Previously)"; - break; - - default: - strState = "Unknown"; - break; - } - - UnicodeString strConnectionMessage; - if (connState == EConnectionState::CONNECTING_DIRECT || connState == EConnectionState::FINDING_ROUTE) - { - strConnectionMessage.format(L"Connecting to %s", strDisplayName.c_str()); - - Int index = GadgetListBoxAddEntryText(quickmatchTextWindow, strConnectionMessage, GameMakeColor(255, 194, 15, 255), -1, -1); - GadgetListBoxSetItemData(quickmatchTextWindow, (void*)-1, index); - } - else if (connState == EConnectionState::CONNECTED_DIRECT) - { - strConnectionMessage.format(L"Connected to %s", strDisplayName.c_str()); - - Int index = GadgetListBoxAddEntryText(quickmatchTextWindow, strConnectionMessage, GameMakeColor(255, 194, 15, 255), -1, -1); - GadgetListBoxSetItemData(quickmatchTextWindow, (void*)-1, index); - } - else - { - if (connState == EConnectionState::CONNECTION_FAILED || connState == EConnectionState::CONNECTION_DISCONNECTED) - { - strConnectionMessage.format(L"Connection failed to %s", strDisplayName.c_str()); - Int index = GadgetListBoxAddEntryText(quickmatchTextWindow, strConnectionMessage, GameMakeColor(255, 194, 15, 255), -1, -1); - GadgetListBoxSetItemData(quickmatchTextWindow, (void*)-1, index); - } - } -#endif - }); - } - - }); - } - -#if defined(GENERALS_ONLINE) - // Update the communicator button anytime we get notifications - NGMP_OnlineServices_SocialInterface* pSocialInterface = NGMP_OnlineServicesManager::GetInterface(); - if (pSocialInterface != nullptr) - { - // notifiactions callback - pSocialInterface->RegisterForCallback_OnNumberGlobalNotificationsChanged([=](int numNotifications) - { - // update communicator button - if (buttonBuddies != nullptr) - { - UnicodeString buttonText; - if (numNotifications > 0) - { - buttonText.format(L"%s [%d]", TheGameText->fetch("GUI:Buddies").str(), numNotifications); - } - else - { - buttonText.format(L"%s", TheGameText->fetch("GUI:Buddies").str()); - } - buttonBuddies->winSetText(buttonText); - } - }); - } - - // And also initialize it - if (buttonBuddies != nullptr && pSocialInterface->GetNumTotalNotifications() > 0) - { - UnicodeString buttonText; - buttonText.format(L"%s [%d]", TheGameText->fetch("GUI:Buddies").str(), pSocialInterface->GetNumTotalNotifications()); - buttonBuddies->winSetText(buttonText); - } -#endif -} - -//------------------------------------------------------------------------------------------------- -/** 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 != nullptr) ); - - if (nextScreen != nullptr) - { - TheShell->push(nextScreen); - } - - nextScreen = nullptr; - -} + TheNGMPGame->reset(); + + GadgetListBoxReset(listboxMapSelect); + populateQuickMatchMapSelectListbox(pref); + + UpdateLocalPlayerStats(); + UpdateStartButton(); + TheTransitionHandler->setGroup("WOLQuickMatchMenuFade"); + isInInit= FALSE; +#endif + +#if defined(GENERALS_ONLINE) + buttonStart->winEnable(TRUE); + buttonStart->winSetText(UnicodeString(L"START MATCHMAKING")); + buttonStop->winSetText(UnicodeString(L"CANCEL MATCHMAKING")); + buttonBack->winEnable(TRUE); + + // not supported in GO + if (comboBoxLadder) + comboBoxLadder->winEnable(FALSE); + if (comboBoxDisabledLadder) + comboBoxDisabledLadder->winEnable(FALSE); + if (comboBoxMaxPing) + comboBoxMaxPing->winEnable(FALSE); + if (comboBoxMaxDisconnects) + comboBoxMaxDisconnects->winEnable(FALSE); + + // welcome msg + instructions + GadgetListBoxAddEntryText(quickmatchTextWindow, UnicodeString(L"Welcome to QuickMatch. Choose Setup to select playlists and maps."), GameMakeColor(255, 194, 25, 255), -1, -1); + GadgetListBoxAddEntryText(quickmatchTextWindow, UnicodeString(L"Special thanks to map makers Tanso, ReLaX, cncHD, Specovik, Mp3, Jundiyy & Bamovich for making quickmatch possible."), GameMakeColor(255, 194, 25, 255), -1, -1); + + + // refresh out stats, needed for ELO data + NGMP_OnlineServices_AuthInterface* pAuthInterface = NGMP_OnlineServicesManager::GetInterface(); + NGMP_OnlineServices_StatsInterface* pStatsInterface = NGMP_OnlineServicesManager::GetInterface(); + if (pAuthInterface != nullptr && pStatsInterface != nullptr) + { + pStatsInterface->findPlayerStatsByID(pAuthInterface->GetUserID(), [=](bool bSuccess, PSPlayerStats stats) + { + UnicodeString eloStr; + eloStr.format(L"Your current Elo rating is %d after %d match(es)", stats.elo_rating, stats.elo_num_matches); + GadgetListBoxAddEntryText(quickmatchTextWindow, eloStr, GameMakeColor(255, 194, 25, 255), -1, -1); + }, EStatsRequestPolicy::BYPASS_CACHE_FORCE_REQUEST); + } + +#endif + +#if defined(GENERALS_ONLINE) + NGMP_OnlineServices_LobbyInterface* pLobbyInterface = NGMP_OnlineServicesManager::GetInterface(); + + // cannot connect to the lobby we joined + pLobbyInterface->RegisterForCannotConnectToLobbyCallback([](void) + { + // TODO_QUICKMATCH: Show error message + stop matchmaking + enable buttons again + }); + + // get playlist list + NGMP_OnlineServices_MatchmakingInterface* pMatchmakingInterface = NGMP_OnlineServicesManager::GetInterface(); + if (pMatchmakingInterface != nullptr) + { + pMatchmakingInterface->RetrievePlaylists([](std::vector vecPlaylists) + { + // add playlists + UnicodeString s; + + // clear ui element + GadgetComboBoxReset(comboBoxNumPlayers); + + + for (PlaylistEntry& playlist : vecPlaylists) + { + s.format(L"%hs", playlist.Name.c_str()); + GadgetComboBoxAddEntry(comboBoxNumPlayers, s, GameSpyColor[GSCOLOR_DEFAULT]); + } + + GadgetComboBoxSetSelectedPos(comboBoxNumPlayers, 0); + }); + } +#endif + + + if (pLobbyInterface != nullptr) + { + // TODO_QUICKMATCH: Deregister when leaving QM + pLobbyInterface->RegisterForMatchmakingMessageCallback([](std::string strMsg) + { + UnicodeString uMsg; + uMsg.format(L"%hs", strMsg.c_str()); + + Int index = GadgetListBoxAddEntryText(quickmatchTextWindow, uMsg, GameSpyColor[GSCOLOR_DEFAULT], -1, -1); + GadgetListBoxSetItemData(quickmatchTextWindow, (void*)-1, index); + }); + + pLobbyInterface->RegisterForMatchmakingMatchFoundCallback([]() + { + buttonStop->winEnable(FALSE); + }); + + pLobbyInterface->RegisterForMatchmakingStartGameCallback([]() + { + NetworkLog(ELogVerbosity::LOG_DEBUG, "[QUICKMATCH] GOT START GAME EVENT"); + + // Check if TheNGMPGame is initialized before dereferencing it + if (!TheNGMPGame) + { + NetworkLog(ELogVerbosity::LOG_DEBUG, "[QUICKMATCH] NO NGMP GAME INSTANCE"); + return; + } + + // mark everyone as having the map, we dont allow user provided custom maps or map transfers in QM + // TODO_QUICKMATCH: Do this automatically for game type quickmatch, or better yet, do it on the service + for (int i = 0; i < MAX_SLOTS; i++) + { + GameSlot* slot = TheNGMPGame->getSlot(i); + if (slot != nullptr) + { + slot->setMapAvailability(TRUE); + } + } + + // start + NGMP_OnlineServices_LobbyInterface* pLobbyInterface = NGMP_OnlineServicesManager::GetInterface(); + NGMPGame* myGame = pLobbyInterface == nullptr ? nullptr : pLobbyInterface->GetCurrentGame(); + + if (pLobbyInterface == nullptr || !myGame || !myGame->isInGame()) + { + NetworkLog(ELogVerbosity::LOG_DEBUG, "[QUICKMATCH] Checks failed, %d, %d, %d", pLobbyInterface == nullptr, !myGame, !myGame->isInGame()); + return; + } + + + // TODO_NGMP + //SendStatsToOtherPlayers(TheNGMPGame); + + // 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); + + *TheNGMPGame = *myGame; + TheNGMPGame->startGame(0); + }); + + pLobbyInterface->RegisterForJoinLobbyCallback([](EJoinLobbyResult result) + { + NGMP_OnlineServices_LobbyInterface* pLobbyInterface = NGMP_OnlineServicesManager::GetInterface(); + + if (!pLobbyInterface->IsInLobby()) + { + return; + } + + if (TheNGMPGame == nullptr) + { + TheNGMPGame = new NGMPGame(); + TheNGMPGame->markGameAsQM(); + } + pLobbyInterface->UpdateRoomDataCache([]() + { + + }); + + // connection events (for debug really) + NetworkMesh* pMesh = NGMP_OnlineServicesManager::GetNetworkMesh(); + if (pMesh != nullptr) + { + pMesh->RegisterForConnectionEvents([](int64_t userID, std::wstring strDisplayName, PlayerConnection* connection) + { +#if _DEBUG // not enabled in quickmatch because then people see their opponent during matchmaking + std::string strState = "Unknown"; + + EConnectionState connState = connection->GetState(); + std::string strConnectionType = connection->GetConnectionType(); + + switch (connState) + { + case EConnectionState::NOT_CONNECTED: + strState = "Not Connected"; + break; + + case EConnectionState::CONNECTING_DIRECT: + strState = "Connecting"; + break; + case EConnectionState::FINDING_ROUTE: + strState = "Connecting (Finding Route)"; + break; + + case EConnectionState::CONNECTED_DIRECT: + strState = "Connected"; + break; + + case EConnectionState::CONNECTION_FAILED: + strState = "Connection Failed"; + break; + + case EConnectionState::CONNECTION_DISCONNECTED: + strState = "Disconnected (Was Connected Previously)"; + break; + + default: + strState = "Unknown"; + break; + } + + UnicodeString strConnectionMessage; + if (connState == EConnectionState::CONNECTING_DIRECT || connState == EConnectionState::FINDING_ROUTE) + { + strConnectionMessage.format(L"Connecting to %s", strDisplayName.c_str()); + + Int index = GadgetListBoxAddEntryText(quickmatchTextWindow, strConnectionMessage, GameMakeColor(255, 194, 15, 255), -1, -1); + GadgetListBoxSetItemData(quickmatchTextWindow, (void*)-1, index); + } + else if (connState == EConnectionState::CONNECTED_DIRECT) + { + strConnectionMessage.format(L"Connected to %s", strDisplayName.c_str()); + + Int index = GadgetListBoxAddEntryText(quickmatchTextWindow, strConnectionMessage, GameMakeColor(255, 194, 15, 255), -1, -1); + GadgetListBoxSetItemData(quickmatchTextWindow, (void*)-1, index); + } + else + { + if (connState == EConnectionState::CONNECTION_FAILED || connState == EConnectionState::CONNECTION_DISCONNECTED) + { + strConnectionMessage.format(L"Connection failed to %s", strDisplayName.c_str()); + Int index = GadgetListBoxAddEntryText(quickmatchTextWindow, strConnectionMessage, GameMakeColor(255, 194, 15, 255), -1, -1); + GadgetListBoxSetItemData(quickmatchTextWindow, (void*)-1, index); + } + } +#endif + }); + } + + }); + } + +#if defined(GENERALS_ONLINE) + // Update the communicator button anytime we get notifications + NGMP_OnlineServices_SocialInterface* pSocialInterface = NGMP_OnlineServicesManager::GetInterface(); + if (pSocialInterface != nullptr) + { + // notifiactions callback + pSocialInterface->RegisterForCallback_OnNumberGlobalNotificationsChanged([=](int numNotifications) + { + // update communicator button + if (buttonBuddies != nullptr) + { + UnicodeString buttonText; + if (numNotifications > 0) + { + buttonText.format(L"%s [%d]", TheGameText->fetch("GUI:Buddies").str(), numNotifications); + } + else + { + buttonText.format(L"%s", TheGameText->fetch("GUI:Buddies").str()); + } + buttonBuddies->winSetText(buttonText); + } + }); + } + + // And also initialize it + if (buttonBuddies != nullptr && pSocialInterface->GetNumTotalNotifications() > 0) + { + UnicodeString buttonText; + buttonText.format(L"%s [%d]", TheGameText->fetch("GUI:Buddies").str(), pSocialInterface->GetNumTotalNotifications()); + buttonBuddies->winSetText(buttonText); + } +#endif +} + +//------------------------------------------------------------------------------------------------- +/** 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 != nullptr) ); + + if (nextScreen != nullptr) + { + TheShell->push(nextScreen); + } + + nextScreen = nullptr; + +} //------------------------------------------------------------------------------------------------- /** WOL Quick Match Menu shutdown method */ @@ -1390,10 +1390,10 @@ void WOLQuickMatchMenuShutdown( WindowLayout *layout, void *userData ) if (!TheGameEngine->getQuitting()) saveQuickMatchOptions(); - parentWOLQuickMatch = nullptr; - buttonBack = nullptr; - quickmatchTextWindow = nullptr; - selectedImage = unselectedImage = nullptr; + parentWOLQuickMatch = nullptr; + buttonBack = nullptr; + quickmatchTextWindow = nullptr; + selectedImage = unselectedImage = nullptr; isShuttingDown = true; @@ -1405,13 +1405,13 @@ void WOLQuickMatchMenuShutdown( WindowLayout *layout, void *userData ) shutdownComplete( layout ); return; - } + } TheShell->reverseAnimatewindow(); TheTransitionHandler->reverse("WOLQuickMatchMenuFade"); RaiseGSMessageBox(); -} +} #ifdef PERF_TEST @@ -1467,19 +1467,19 @@ static const char* getMessageString(Int t) //------------------------------------------------------------------------------------------------- void WOLQuickMatchMenuUpdate( WindowLayout * layout, void *userData) { - // need to exit? - if (NGMP_OnlineServicesManager::GetInstance() != nullptr && NGMP_OnlineServicesManager::GetInstance()->IsPendingFullTeardown()) - { - // Only if not in game and not in anim - if ((TheNGMPGame == nullptr || !TheNGMPGame->isGameInProgress()) && TheShell->isAnimFinished() && TheTransitionHandler->isFinished()) - { - bool bForceShutdown = true; - WOLQuickMatchMenuShutdown(layout, (void*)&bForceShutdown); // userdata is 'force shutdown' - TearDownGeneralsOnline(); - - TheShell->pop(); - return; - } + // need to exit? + if (NGMP_OnlineServicesManager::GetInstance() != nullptr && NGMP_OnlineServicesManager::GetInstance()->IsPendingFullTeardown()) + { + // Only if not in game and not in anim + if ((TheNGMPGame == nullptr || !TheNGMPGame->isGameInProgress()) && TheShell->isAnimFinished() && TheTransitionHandler->isFinished()) + { + bool bForceShutdown = true; + WOLQuickMatchMenuShutdown(layout, (void*)&bForceShutdown); // userdata is 'force shutdown' + TearDownGeneralsOnline(); + + TheShell->pop(); + return; + } } if (TheGameLogic->isInShellGame() && TheGameLogic->getFrame() == 1) @@ -1487,7 +1487,7 @@ void WOLQuickMatchMenuUpdate( WindowLayout * layout, void *userData) SignalUIInteraction(SHELL_SCRIPT_HOOK_GENERALS_ONLINE_ENTERED_FROM_GAME); } - // We'll only be successful if we've requested to + // We'll only be successful if we've requested to if(isShuttingDown && TheShell->isAnimFinished()&& TheTransitionHandler->isFinished()) shutdownComplete(layout); @@ -1497,8 +1497,8 @@ void WOLQuickMatchMenuUpdate( WindowLayout * layout, void *userData) raiseMessageBoxes = false; } -#if defined(GENERALS_ONLINE) // GO needs to tick this, so notifications disappear etc - HandleBuddyResponses(); +#if defined(GENERALS_ONLINE) // GO needs to tick this, so notifications disappear etc + HandleBuddyResponses(); #endif /// @todo: MDC handle disconnects in-game the same way as Custom Match! @@ -1510,7 +1510,7 @@ void WOLQuickMatchMenuUpdate( WindowLayout * layout, void *userData) if (TheGameSpyGame && TheGameSpyGame->isGameInProgress()) { - if (TheGameSpyInfo->isDisconnectedAfterGameStart(nullptr)) + if (TheGameSpyInfo->isDisconnectedAfterGameStart(nullptr)) { return; // already been disconnected, so don't worry. } @@ -1530,7 +1530,7 @@ void WOLQuickMatchMenuUpdate( WindowLayout * layout, void *userData) // check for scorescreen NameKeyType listboxChatWindowScoreScreenID = NAMEKEY("ScoreScreen.wnd:ListboxChatWindowScoreScreen"); - GameWindow *listboxChatWindowScoreScreen = TheWindowManager->winGetWindowFromId( nullptr, listboxChatWindowScoreScreenID ); + GameWindow *listboxChatWindowScoreScreen = TheWindowManager->winGetWindowFromId( nullptr, listboxChatWindowScoreScreenID ); if (listboxChatWindowScoreScreen) { GadgetListBoxAddEntryText(listboxChatWindowScoreScreen, TheGameText->fetch(disconMunkee), @@ -1549,7 +1549,7 @@ void WOLQuickMatchMenuUpdate( WindowLayout * layout, void *userData) return; // if we're in game, all we care about is if we've been disconnected from the chat server } - if (TheNAT != nullptr) { + if (TheNAT != nullptr) { NATStateType NATState = TheNAT->update(); if (NATState == NATSTATE_DONE) { @@ -1562,7 +1562,7 @@ void WOLQuickMatchMenuUpdate( WindowLayout * layout, void *userData) { // delete TheNAT, its no good for us anymore. delete TheNAT; - TheNAT = nullptr; + TheNAT = nullptr; // Just back out. This cleans up some slot list problems buttonPushed = true; @@ -1593,19 +1593,19 @@ void WOLQuickMatchMenuUpdate( WindowLayout * layout, void *userData) { case PeerResponse::PEERRESPONSE_PLAYERUTM: { - if (stricmp(resp.command.c_str(), "STATS") == 0) + if (stricmp(resp.command.c_str(), "STATS") == 0) { - DEBUG_LOG(("Saw STATS from %s, data was '%s'", resp.nick.c_str(), resp.commandOptions.c_str())); + DEBUG_LOG(("Saw STATS from %s, data was '%s'", 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'", id, idStr.str(), data.str())); + DEBUG_LOG(("data: %d(%s) - '%s'", 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", stats.id, oldStats.id)); + DEBUG_LOG(("Parsed ID is %d, old ID is %d", stats.id, oldStats.id)); if (stats.id && (oldStats.id == 0)) TheGameSpyPSMessageQueue->trackPlayerStats(stats); @@ -1622,10 +1622,10 @@ void WOLQuickMatchMenuUpdate( WindowLayout * layout, void *userData) } } Int slotNum = TheGameSpyGame->getSlotNum(resp.nick.c_str()); - if ((slotNum >= 0) && (slotNum < MAX_SLOTS) && (stricmp(resp.command.c_str(), "NAT") == 0)) { + if ((slotNum >= 0) && (slotNum < MAX_SLOTS) && (stricmp(resp.command.c_str(), "NAT") == 0)) { // this is a command for NAT negotiations, pass if off to TheNAT sawImportantMessage = TRUE; - if (TheNAT != nullptr) { + if (TheNAT != nullptr) { TheNAT->processGlobalMessage(slotNum, resp.commandOptions.c_str()); } } @@ -1636,12 +1636,12 @@ void WOLQuickMatchMenuUpdate( WindowLayout * layout, void *userData) (val <= FirewallHelperClass::FIREWALL_TYPE_DESTINATION_PORT_DELTA)) { slot->setNATBehavior((FirewallHelperClass::FirewallBehaviorType)val); - DEBUG_LOG(("Setting NAT behavior to %d for player %d", val, slotNum)); + DEBUG_LOG(("Setting NAT behavior to %d for player %d", val, slotNum)); change = true; } else { - DEBUG_LOG(("Rejecting invalid NAT behavior %d from player %d", val, slotNum)); + DEBUG_LOG(("Rejecting invalid NAT behavior %d from player %d", val, slotNum)); } } */ @@ -1668,11 +1668,11 @@ void WOLQuickMatchMenuUpdate( WindowLayout * layout, void *userData) /* if (resp.joinGroupRoom.ok) { - TheGameSpyInfo->addText(L"Joined group room", GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow); + TheGameSpyInfo->addText(L"Joined group room", GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow); } else { - TheGameSpyInfo->addText(L"Didn't join group room", GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow); + TheGameSpyInfo->addText(L"Didn't join group room", GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow); } */ break; @@ -1765,7 +1765,7 @@ void WOLQuickMatchMenuUpdate( WindowLayout * layout, void *userData) switch( resp.qmStatus.status ) { case QM_IDLE: - //TheGameSpyInfo->addText(L"Status: QM_IDLE", GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow); + //TheGameSpyInfo->addText(L"Status: QM_IDLE", GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow); break; case QM_JOININGQMCHANNEL: TheGameSpyInfo->addText(TheGameText->fetch("QM:JOININGQMCHANNEL"), GameSpyColor[GSCOLOR_DEFAULT], quickmatchTextWindow); @@ -1868,10 +1868,10 @@ void WOLQuickMatchMenuUpdate( WindowLayout * layout, void *userData) } } - DEBUG_LOG(("Starting a QM game: options=[%s]", GameInfoToAsciiString(TheGameSpyGame).str())); + DEBUG_LOG(("Starting a QM game: options=[%s]", GameInfoToAsciiString(TheGameSpyGame).str())); SendStatsToOtherPlayers(TheGameSpyGame); TheGameSpyGame->startGame(0); - GameWindow *buttonBuddies = TheWindowManager->winGetWindowFromId(nullptr, buttonBuddiesID); + GameWindow *buttonBuddies = TheWindowManager->winGetWindowFromId(nullptr, buttonBuddiesID); if (buttonBuddies) buttonBuddies->winEnable(FALSE); GameSpyCloseOverlay(GSOVERLAY_BUDDY); @@ -1928,17 +1928,17 @@ void WOLQuickMatchMenuUpdate( WindowLayout * layout, void *userData) 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", munkee.str())); + PERF_LOG(("%ls", munkee.str())); std::list::const_iterator it; for (it = responses.begin(); it != responses.end(); ++it) { - PERF_LOG((" %s", getMessageString(*it))); + PERF_LOG((" %s", getMessageString(*it))); } } #endif // PERF_TEST } -} +} //------------------------------------------------------------------------------------------------- /** WOL Quick Match Menu input callback */ @@ -1946,7 +1946,7 @@ void WOLQuickMatchMenuUpdate( WindowLayout * layout, void *userData) WindowMsgHandledType WOLQuickMatchMenuInput( GameWindow *window, UnsignedInt msg, WindowMsgData mData1, WindowMsgData mData2 ) { - switch( msg ) + switch( msg ) { // -------------------------------------------------------------------------------------------- @@ -1963,7 +1963,7 @@ WindowMsgHandledType WOLQuickMatchMenuInput( GameWindow *window, UnsignedInt msg // ---------------------------------------------------------------------------------------- case KEY_ESC: { - + // // send a simulated selected event to the parent window of the // back/exit button @@ -1971,56 +1971,56 @@ WindowMsgHandledType WOLQuickMatchMenuInput( GameWindow *window, UnsignedInt msg if( BitIsSet( state, KEY_STATE_UP ) ) { if(!buttonBack->winIsHidden()) - TheWindowManager->winSendSystemMsg( window, GBM_SELECTED, + TheWindowManager->winSendSystemMsg( window, GBM_SELECTED, (WindowMsgData)buttonBack, buttonBackID ); - } + } // don't let key fall through anywhere else return MSG_HANDLED; - } + } - } + } - } + } - } + } return MSG_IGNORED; -} +} //------------------------------------------------------------------------------------------------- /** WOL Quick Match Menu window system callback */ //------------------------------------------------------------------------------------------------- -WindowMsgHandledType WOLQuickMatchMenuSystem( GameWindow *window, UnsignedInt msg, +WindowMsgHandledType WOLQuickMatchMenuSystem( GameWindow *window, UnsignedInt msg, WindowMsgData mData1, WindowMsgData mData2 ) { UnicodeString txtInput; switch( msg ) { - - + + case GWM_CREATE: { - + break; - } + } case GWM_DESTROY: { break; - } + } 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 GCM_SELECTED: { @@ -2072,7 +2072,7 @@ WindowMsgHandledType WOLQuickMatchMenuSystem( GameWindow *window, UnsignedInt ms UpdateStartButton(); } break; - } + } case GBM_SELECTED: { @@ -2091,7 +2091,7 @@ WindowMsgHandledType WOLQuickMatchMenuSystem( GameWindow *window, UnsignedInt ms buttonStop->winHide(TRUE); enableOptionsGadgets(TRUE); - Int index = GadgetListBoxAddEntryText(quickmatchTextWindow, TheGameText->fetch("GUI:QMAborted"), GameSpyColor[GSCOLOR_DEFAULT], -1, -1); + Int index = GadgetListBoxAddEntryText(quickmatchTextWindow, TheGameText->fetch("GUI:QMAborted"), GameSpyColor[GSCOLOR_DEFAULT], -1, -1); GadgetListBoxSetItemData(quickmatchTextWindow, (void*)-1, index); NGMP_OnlineServices_MatchmakingInterface* pMatchmakingInterface = NGMP_OnlineServicesManager::GetInterface(); @@ -2211,7 +2211,7 @@ WindowMsgHandledType WOLQuickMatchMenuSystem( GameWindow *window, UnsignedInt ms } else { - Int index = GadgetListBoxAddEntryText(quickmatchTextWindow, UnicodeString(L"Failed to start matchmaking."), GameSpyColor[GSCOLOR_DEFAULT], -1, -1); + Int index = GadgetListBoxAddEntryText(quickmatchTextWindow, UnicodeString(L"Failed to start matchmaking."), GameSpyColor[GSCOLOR_DEFAULT], -1, -1); GadgetListBoxSetItemData(quickmatchTextWindow, (void*)-1, index); // buttons @@ -2258,7 +2258,7 @@ WindowMsgHandledType WOLQuickMatchMenuSystem( GameWindow *window, UnsignedInt ms val = 0; if( val >= maxPingEntries - 1) { - req.QM.maxPing = TheGameSpyConfig->getPingTimeoutInMs(); + req.QM.maxPing = TheGameSpyConfig->getPingTimeoutInMs(); } else req.QM.maxPing = (val+1)*100; @@ -2269,7 +2269,7 @@ WindowMsgHandledType WOLQuickMatchMenuSystem( GameWindow *window, UnsignedInt ms Int ladderIndex, index, selected; GadgetComboBoxGetSelectedPos( comboBoxLadder, &selected ); ladderIndex = (Int)GadgetComboBoxGetItemData( comboBoxLadder, selected ); - const LadderInfo *ladderInfo = nullptr; + const LadderInfo *ladderInfo = nullptr; if (ladderIndex < 0) { ladderIndex = 0; @@ -2294,7 +2294,7 @@ WindowMsgHandledType WOLQuickMatchMenuSystem( GameWindow *window, UnsignedInt ms if (ladderInfo && ladderInfo->randomFactions) { Int sideNum = GameClientRandomValue(0, ladderInfo->validFactions.size()-1); - DEBUG_LOG(("Looking for %d out of %d random sides", sideNum, ladderInfo->validFactions.size())); + DEBUG_LOG(("Looking for %d out of %d random sides", sideNum, ladderInfo->validFactions.size())); AsciiStringListConstIterator cit = ladderInfo->validFactions.begin(); while (sideNum) { @@ -2305,13 +2305,13 @@ WindowMsgHandledType WOLQuickMatchMenuSystem( GameWindow *window, UnsignedInt ms { Int numPlayerTemplates = ThePlayerTemplateStore->getPlayerTemplateCount(); AsciiString sideStr = *cit; - DEBUG_LOG(("Chose %s as our side... finding", sideStr.str())); + DEBUG_LOG(("Chose %s as our side... finding", sideStr.str())); for (Int c=0; cgetNthPlayerTemplate(c); if (fac && fac->getSide() == sideStr) { - DEBUG_LOG(("Found %s in index %d", sideStr.str(), c)); + DEBUG_LOG(("Found %s in index %d", sideStr.str(), c)); req.QM.side = c; break; } @@ -2369,8 +2369,8 @@ WindowMsgHandledType WOLQuickMatchMenuSystem( GameWindow *window, UnsignedInt ms req.QM.discons = numDiscons; - strlcpy(req.QM.pings, TheGameSpyInfo->getPingString().str(), sizeof(req.QM.pings)); - + strlcpy(req.QM.pings, TheGameSpyInfo->getPingString().str(), sizeof(req.QM.pings)); + req.QM.botID = TheGameSpyConfig->getQMBotID(); req.QM.roomID = TheGameSpyConfig->getQMChannel(); @@ -2389,7 +2389,7 @@ WindowMsgHandledType WOLQuickMatchMenuSystem( GameWindow *window, UnsignedInt ms LadderPreferences ladPref; ladPref.loadProfile( TheGameSpyInfo->getLocalProfileID() ); LadderPref p; - p.lastPlayDate = time(nullptr); + p.lastPlayDate = time(nullptr); p.address = ladderInfo->address; p.port = ladderInfo->port; p.name = ladderInfo->name; @@ -2410,7 +2410,7 @@ WindowMsgHandledType WOLQuickMatchMenuSystem( GameWindow *window, UnsignedInt ms buttonPushed = true; nextScreen = "Menus/WOLWelcomeMenu.wnd"; TheShell->pop(); - } + } else if ( controlID == buttonSelectAllMapsID ) { Int numMaps = GadgetListBoxGetNumEntries(listboxMapSelect); @@ -2420,20 +2420,20 @@ WindowMsgHandledType WOLQuickMatchMenuSystem( GameWindow *window, UnsignedInt ms GadgetListBoxSetItemData(listboxMapSelect, (void *)1, i); GadgetListBoxAddEntryText(listboxMapSelect, GadgetListBoxGetText(listboxMapSelect, i, 1), GameSpyColor[GSCOLOR_MAP_SELECTED], i, 1); } - } + } else if ( controlID == buttonSelectNoMapsID ) { Int numMaps = GadgetListBoxGetNumEntries(listboxMapSelect); for ( Int i=0; i Date: Sat, 24 Jan 2026 15:19:31 +0300 Subject: [PATCH 2/2] play a sound when we find a match --- .../GameClient/GUI/GUICallbacks/Menus/WOLQuickMatchMenu.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQuickMatchMenu.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQuickMatchMenu.cpp index 3448dd3c55..f005607402 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQuickMatchMenu.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQuickMatchMenu.cpp @@ -1155,6 +1155,11 @@ void WOLQuickMatchMenuInit( WindowLayout *layout, void *userData ) pLobbyInterface->RegisterForMatchmakingMatchFoundCallback([]() { buttonStop->winEnable(FALSE); + if (TheAudio) + { + AudioEventRTS evt("GUICommunicatorOpen"); + TheAudio->addAudioEvent(&evt); + } }); pLobbyInterface->RegisterForMatchmakingStartGameCallback([]() @@ -2476,3 +2481,4 @@ WindowMsgHandledType WOLQuickMatchMenuSystem( GameWindow *window, UnsignedInt ms return MSG_HANDLED; } +