/* ** 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: LANGameInfo.cpp ////////////////////////////////////////////////////// // LAN 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 "GameClient/GameInfoWindow.h" #include "GameClient/GameText.h" #include "GameClient/GadgetListBox.h" #include "GameNetwork/LANGameInfo.h" #include "GameNetwork/LANAPICallbacks.h" #include "Common/MultiplayerSettings.h" #include "strtok_r.h" /* #include "GameNetwork/LAN.h" #include "GameNetwork/LANGame.h" #include "GameNetwork/LANPing.h" #include "GameNetwork/LANusers.h" #include "GameNetwork/LANmenus.h" */ // Singleton ------------------------------------------ LANGameInfo *TheLANGameInfo = NULL; // LANGameSlot ---------------------------------------- LANGameSlot::LANGameSlot() { m_lastHeard = 0; } LANPlayer * LANGameSlot::getUser( void ) { if (isHuman()) { m_user.setIP(getIP()); m_user.setLastHeard(getLastHeard()); m_user.setName(getName()); m_user.setNext(NULL); return &m_user; } return NULL; } // Various tests Bool LANGameSlot::isUser( LANPlayer *user ) { return (user && m_state == SLOT_PLAYER && user->getIP() == getIP()); } Bool LANGameSlot::isUser( UnicodeString userName ) { return (m_state == SLOT_PLAYER && !userName.compareNoCase(getName())); } Bool LANGameSlot::isLocalPlayer( void ) const { return isHuman() && TheLAN && TheLAN->GetLocalIP() == getIP(); } // LANGameInfo ---------------------------------------- LANGameInfo::LANGameInfo() { //Added By Sadullah Nader //Initializtions missing and needed m_lastHeard = 0; m_next = NULL; // for (Int i = 0; i< MAX_SLOTS; ++i) setSlotPointer(i, &m_LANSlot[i]); setLocalIP(TheLAN->GetLocalIP()); } void LANGameInfo::setSlot( Int slotNum, LANGameSlot slotInfo ) { DEBUG_ASSERTCRASH( slotNum >= 0 && slotNum < MAX_SLOTS, ("LANGameInfo::setSlot - Invalid slot number")); if (slotNum < 0 || slotNum >= MAX_SLOTS) return; m_LANSlot[slotNum] = slotInfo; if (slotNum == 0) { m_LANSlot[slotNum].setAccept(); m_LANSlot[slotNum].setMapAvailability(true); } } LANGameSlot* LANGameInfo::getLANSlot( Int slotNum ) { DEBUG_ASSERTCRASH( slotNum >= 0 && slotNum < MAX_SLOTS, ("LANGameInfo::getLANSlot - Invalid slot number")); if (slotNum < 0 || slotNum >= MAX_SLOTS) return NULL; return &m_LANSlot[slotNum]; } const LANGameSlot* LANGameInfo::getConstLANSlot( Int slotNum ) const { DEBUG_ASSERTCRASH( slotNum >= 0 && slotNum < MAX_SLOTS, ("LANGameInfo::getConstLANSlot - Invalid slot number")); if (slotNum < 0 || slotNum >= MAX_SLOTS) return NULL; return &m_LANSlot[slotNum]; } Int LANGameInfo::getLocalSlotNum( void ) const { DEBUG_ASSERTCRASH(m_inGame, ("Looking for local game slot while not in game")); if (!m_inGame) return -1; for (Int i=0; iisLocalPlayer()) return i; } return -1; } Int LANGameInfo::getSlotNum( UnicodeString userName ) { DEBUG_ASSERTCRASH(m_inGame, ("Looking for game slot while not in game")); if (!m_inGame) return -1; for (Int i=0; iisUser( userName )) return i; } return -1; } Bool LANGameInfo::amIHost( void ) { DEBUG_ASSERTCRASH(m_inGame, ("Looking for game slot while not in game")); if (!m_inGame) return false; return getLANSlot(0)->isLocalPlayer(); } void LANGameInfo::setMap( AsciiString mapName ) { GameInfo::setMap(mapName); } void LANGameInfo::setSeed( Int seed ) { GameInfo::setSeed(seed); } void LANGameInfo::resetAccepted( void ) { if (TheLAN) { TheLAN->ResetGameStartTimer(); if (TheLAN->GetMyGame() == this && TheLAN->AmIHost()) LANEnableStartButton(true); } for(int i = 0; i< MAX_SLOTS; i++) { m_LANSlot[i].unAccept(); } } // Misc game-related functionality -------------------- void LANDisplayGameList( GameWindow *gameListbox, LANGameInfo *gameList ) { LANGameInfo *selectedPtr = NULL; Int selectedIndex = -1; Int indexToSelect = -1; if (gameListbox) { GadgetListBoxGetSelected(gameListbox, &selectedIndex); if (selectedIndex != -1 ) { selectedPtr = (LANGameInfo *)GadgetListBoxGetItemData(gameListbox, selectedIndex, 0); } GadgetListBoxReset(gameListbox); while (gameList) { UnicodeString txtGName; txtGName = L""; if( gameList->isGameInProgress() ) { txtGName.concat(L"["); } txtGName.concat(gameList->getPlayerName(0)); if( gameList->isGameInProgress() ) { txtGName.concat(L"]"); } Int addedIndex = GadgetListBoxAddEntryText(gameListbox, txtGName, (gameList->isGameInProgress())?gameInProgressColor:gameColor, -1, -1); GadgetListBoxSetItemData(gameListbox, (void *)gameList, addedIndex, 0 ); if (selectedPtr == gameList) indexToSelect = addedIndex; gameList = gameList->getNext(); } if (indexToSelect >= 0) GadgetListBoxSetSelected(gameListbox, indexToSelect); else HideGameInfoWindow(TRUE); } } AsciiString GenerateGameOptionsString( void ) { if(!TheLAN->GetMyGame() || !TheLAN->GetMyGame()->amIHost()) return AsciiString.TheEmptyString; return GameInfoToAsciiString(TheLAN->GetMyGame()); } Bool ParseGameOptionsString(LANGameInfo *game, AsciiString options) { if (!TheLAN || !game) return false; Int oldLocalSlotNum = (game->isInGame()) ? game->getLocalSlotNum() : -1; Bool wasInGame = oldLocalSlotNum >= 0; // Int hadMap = wasInGame && game->getSlot(oldLocalSlotNum)->hasMap(); AsciiString oldMap = game->getMap(); UnsignedInt oldMapCRC, newMapCRC; oldMapCRC = game->getMapCRC(); std::map oldLogins, oldMachines; std::map::iterator mapIt; Int i; for (i=0; igetLANSlot(i); if (slot && slot->isHuman()) { //DEBUG_LOG(("Saving off %ls@%ls for %ls\n", slot->getUser()->getLogin().str(), slot->getUser()->getHost().str(), slot->getName().str())); oldLogins[slot->getName()] = slot->getUser()->getLogin(); oldMachines[slot->getName()] = slot->getUser()->getHost(); } } if (ParseAsciiStringToGameInfo(game, options)) { Int newLocalSlotNum = (game->isInGame()) ? game->getLocalSlotNum() : -1; Bool isInGame = newLocalSlotNum >= 0; if (!TheLAN->AmIHost() && isInGame) { // Int hasMap = game->getSlot(newLocalSlotNum)->hasMap(); newMapCRC = game->getMapCRC(); //DEBUG_LOG(("wasInGame:%d isInGame:%d hadMap:%d hasMap:%d oldMap:%s newMap:%s\n", wasInGame, isInGame, hadMap, hasMap, oldMap.str(), game->getMap().str())); if ( (oldMapCRC ^ newMapCRC)/*(hasMap ^ hadMap)*/ || (!wasInGame && isInGame) ) { // it changed. send it TheLAN->RequestHasMap(); lanUpdateSlotList(); updateGameOptions(); } } // clean up LAN users, etc. UnsignedInt now = timeGetTime(); for (i=0; igetLANSlot(i); if (slot->isHuman()) { slot->setLastHeard(now); mapIt = oldLogins.find(slot->getName()); if (mapIt != oldLogins.end()) slot->setLogin(mapIt->second); mapIt = oldMachines.find(slot->getName()); if (mapIt != oldMachines.end()) slot->setHost(mapIt->second); //DEBUG_LOG(("Restored %ls@%ls for %ls\n", slot->getUser()->getLogin().str(), slot->getUser()->getHost().str(), slot->getName().str())); } } return true; } return false; }