LANGameInfo.cpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. /*
  2. ** Command & Conquer Generals Zero Hour(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // FILE: LANGameInfo.cpp //////////////////////////////////////////////////////
  24. // LAN game setup state info
  25. // Author: Matthew D. Campbell, December 2001
  26. #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
  27. #include "GameClient/GameInfoWindow.h"
  28. #include "GameClient/GameText.h"
  29. #include "GameClient/GadgetListBox.h"
  30. #include "GameNetwork/LANGameInfo.h"
  31. #include "GameNetwork/LANAPICallbacks.h"
  32. #include "Common/MultiplayerSettings.h"
  33. #include "strtok_r.h"
  34. /*
  35. #include "GameNetwork/LAN.h"
  36. #include "GameNetwork/LANGame.h"
  37. #include "GameNetwork/LANPing.h"
  38. #include "GameNetwork/LANusers.h"
  39. #include "GameNetwork/LANmenus.h"
  40. */
  41. // Singleton ------------------------------------------
  42. LANGameInfo *TheLANGameInfo = NULL;
  43. // LANGameSlot ----------------------------------------
  44. LANGameSlot::LANGameSlot()
  45. {
  46. m_lastHeard = 0;
  47. }
  48. LANPlayer * LANGameSlot::getUser( void )
  49. {
  50. if (isHuman())
  51. {
  52. m_user.setIP(getIP());
  53. m_user.setLastHeard(getLastHeard());
  54. m_user.setName(getName());
  55. m_user.setNext(NULL);
  56. return &m_user;
  57. }
  58. return NULL;
  59. }
  60. // Various tests
  61. Bool LANGameSlot::isUser( LANPlayer *user )
  62. {
  63. return (user && m_state == SLOT_PLAYER && user->getIP() == getIP());
  64. }
  65. Bool LANGameSlot::isUser( UnicodeString userName )
  66. {
  67. return (m_state == SLOT_PLAYER && !userName.compareNoCase(getName()));
  68. }
  69. Bool LANGameSlot::isLocalPlayer( void ) const
  70. {
  71. return isHuman() && TheLAN && TheLAN->GetLocalIP() == getIP();
  72. }
  73. // LANGameInfo ----------------------------------------
  74. LANGameInfo::LANGameInfo()
  75. {
  76. //Added By Sadullah Nader
  77. //Initializtions missing and needed
  78. m_lastHeard = 0;
  79. m_next = NULL;
  80. //
  81. for (Int i = 0; i< MAX_SLOTS; ++i)
  82. setSlotPointer(i, &m_LANSlot[i]);
  83. setLocalIP(TheLAN->GetLocalIP());
  84. }
  85. void LANGameInfo::setSlot( Int slotNum, LANGameSlot slotInfo )
  86. {
  87. DEBUG_ASSERTCRASH( slotNum >= 0 && slotNum < MAX_SLOTS, ("LANGameInfo::setSlot - Invalid slot number"));
  88. if (slotNum < 0 || slotNum >= MAX_SLOTS)
  89. return;
  90. m_LANSlot[slotNum] = slotInfo;
  91. if (slotNum == 0)
  92. {
  93. m_LANSlot[slotNum].setAccept();
  94. m_LANSlot[slotNum].setMapAvailability(true);
  95. }
  96. }
  97. LANGameSlot* LANGameInfo::getLANSlot( Int slotNum )
  98. {
  99. DEBUG_ASSERTCRASH( slotNum >= 0 && slotNum < MAX_SLOTS, ("LANGameInfo::getLANSlot - Invalid slot number"));
  100. if (slotNum < 0 || slotNum >= MAX_SLOTS)
  101. return NULL;
  102. return &m_LANSlot[slotNum];
  103. }
  104. const LANGameSlot* LANGameInfo::getConstLANSlot( Int slotNum ) const
  105. {
  106. DEBUG_ASSERTCRASH( slotNum >= 0 && slotNum < MAX_SLOTS, ("LANGameInfo::getConstLANSlot - Invalid slot number"));
  107. if (slotNum < 0 || slotNum >= MAX_SLOTS)
  108. return NULL;
  109. return &m_LANSlot[slotNum];
  110. }
  111. Int LANGameInfo::getLocalSlotNum( void ) const
  112. {
  113. DEBUG_ASSERTCRASH(m_inGame, ("Looking for local game slot while not in game"));
  114. if (!m_inGame)
  115. return -1;
  116. for (Int i=0; i<MAX_SLOTS; ++i)
  117. {
  118. const LANGameSlot *slot = getConstLANSlot(i);
  119. if (slot->isLocalPlayer())
  120. return i;
  121. }
  122. return -1;
  123. }
  124. Int LANGameInfo::getSlotNum( UnicodeString userName )
  125. {
  126. DEBUG_ASSERTCRASH(m_inGame, ("Looking for game slot while not in game"));
  127. if (!m_inGame)
  128. return -1;
  129. for (Int i=0; i<MAX_SLOTS; ++i)
  130. {
  131. LANGameSlot *slot = getLANSlot(i);
  132. if (slot->isUser( userName ))
  133. return i;
  134. }
  135. return -1;
  136. }
  137. Bool LANGameInfo::amIHost( void )
  138. {
  139. DEBUG_ASSERTCRASH(m_inGame, ("Looking for game slot while not in game"));
  140. if (!m_inGame)
  141. return false;
  142. return getLANSlot(0)->isLocalPlayer();
  143. }
  144. void LANGameInfo::setMap( AsciiString mapName )
  145. {
  146. GameInfo::setMap(mapName);
  147. }
  148. void LANGameInfo::setSeed( Int seed )
  149. {
  150. GameInfo::setSeed(seed);
  151. }
  152. void LANGameInfo::resetAccepted( void )
  153. {
  154. if (TheLAN)
  155. {
  156. TheLAN->ResetGameStartTimer();
  157. if (TheLAN->GetMyGame() == this && TheLAN->AmIHost())
  158. LANEnableStartButton(true);
  159. }
  160. for(int i = 0; i< MAX_SLOTS; i++)
  161. {
  162. m_LANSlot[i].unAccept();
  163. }
  164. }
  165. // Misc game-related functionality --------------------
  166. void LANDisplayGameList( GameWindow *gameListbox, LANGameInfo *gameList )
  167. {
  168. LANGameInfo *selectedPtr = NULL;
  169. Int selectedIndex = -1;
  170. Int indexToSelect = -1;
  171. if (gameListbox)
  172. {
  173. GadgetListBoxGetSelected(gameListbox, &selectedIndex);
  174. if (selectedIndex != -1 )
  175. {
  176. selectedPtr = (LANGameInfo *)GadgetListBoxGetItemData(gameListbox, selectedIndex, 0);
  177. }
  178. GadgetListBoxReset(gameListbox);
  179. while (gameList)
  180. {
  181. UnicodeString txtGName;
  182. txtGName = L"";
  183. if( gameList->isGameInProgress() )
  184. {
  185. txtGName.concat(L"[");
  186. }
  187. txtGName.concat(gameList->getPlayerName(0));
  188. if( gameList->isGameInProgress() )
  189. {
  190. txtGName.concat(L"]");
  191. }
  192. Int addedIndex = GadgetListBoxAddEntryText(gameListbox, txtGName, (gameList->isGameInProgress())?gameInProgressColor:gameColor, -1, -1);
  193. GadgetListBoxSetItemData(gameListbox, (void *)gameList, addedIndex, 0 );
  194. if (selectedPtr == gameList)
  195. indexToSelect = addedIndex;
  196. gameList = gameList->getNext();
  197. }
  198. if (indexToSelect >= 0)
  199. GadgetListBoxSetSelected(gameListbox, indexToSelect);
  200. else
  201. HideGameInfoWindow(TRUE);
  202. }
  203. }
  204. AsciiString GenerateGameOptionsString( void )
  205. {
  206. if(!TheLAN->GetMyGame() || !TheLAN->GetMyGame()->amIHost())
  207. return AsciiString.TheEmptyString;
  208. return GameInfoToAsciiString(TheLAN->GetMyGame());
  209. }
  210. Bool ParseGameOptionsString(LANGameInfo *game, AsciiString options)
  211. {
  212. if (!TheLAN || !game)
  213. return false;
  214. Int oldLocalSlotNum = (game->isInGame()) ? game->getLocalSlotNum() : -1;
  215. Bool wasInGame = oldLocalSlotNum >= 0;
  216. // Int hadMap = wasInGame && game->getSlot(oldLocalSlotNum)->hasMap();
  217. AsciiString oldMap = game->getMap();
  218. UnsignedInt oldMapCRC, newMapCRC;
  219. oldMapCRC = game->getMapCRC();
  220. std::map<UnicodeString, UnicodeString> oldLogins, oldMachines;
  221. std::map<UnicodeString, UnicodeString>::iterator mapIt;
  222. Int i;
  223. for (i=0; i<MAX_SLOTS; ++i)
  224. {
  225. LANGameSlot *slot = game->getLANSlot(i);
  226. if (slot && slot->isHuman())
  227. {
  228. //DEBUG_LOG(("Saving off %ls@%ls for %ls\n", slot->getUser()->getLogin().str(), slot->getUser()->getHost().str(), slot->getName().str()));
  229. oldLogins[slot->getName()] = slot->getUser()->getLogin();
  230. oldMachines[slot->getName()] = slot->getUser()->getHost();
  231. }
  232. }
  233. if (ParseAsciiStringToGameInfo(game, options))
  234. {
  235. Int newLocalSlotNum = (game->isInGame()) ? game->getLocalSlotNum() : -1;
  236. Bool isInGame = newLocalSlotNum >= 0;
  237. if (!TheLAN->AmIHost() && isInGame)
  238. {
  239. // Int hasMap = game->getSlot(newLocalSlotNum)->hasMap();
  240. newMapCRC = game->getMapCRC();
  241. //DEBUG_LOG(("wasInGame:%d isInGame:%d hadMap:%d hasMap:%d oldMap:%s newMap:%s\n", wasInGame, isInGame, hadMap, hasMap, oldMap.str(), game->getMap().str()));
  242. if ( (oldMapCRC ^ newMapCRC)/*(hasMap ^ hadMap)*/ || (!wasInGame && isInGame) )
  243. {
  244. // it changed. send it
  245. TheLAN->RequestHasMap();
  246. lanUpdateSlotList();
  247. updateGameOptions();
  248. }
  249. }
  250. // clean up LAN users, etc.
  251. UnsignedInt now = timeGetTime();
  252. for (i=0; i<MAX_SLOTS; ++i)
  253. {
  254. LANGameSlot *slot = game->getLANSlot(i);
  255. if (slot->isHuman())
  256. {
  257. slot->setLastHeard(now);
  258. mapIt = oldLogins.find(slot->getName());
  259. if (mapIt != oldLogins.end())
  260. slot->setLogin(mapIt->second);
  261. mapIt = oldMachines.find(slot->getName());
  262. if (mapIt != oldMachines.end())
  263. slot->setHost(mapIt->second);
  264. //DEBUG_LOG(("Restored %ls@%ls for %ls\n", slot->getUser()->getLogin().str(), slot->getUser()->getHost().str(), slot->getName().str()));
  265. }
  266. }
  267. return true;
  268. }
  269. return false;
  270. }