LANAPI.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. /*
  2. ** Command & Conquer Generals(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. // LANAPI.h ///////////////////////////////////////////////////////////////
  24. // LANAPI singleton class - defines interface to LAN broadcast communications
  25. // Author: Matthew D. Campbell, October 2001
  26. #pragma once
  27. #ifndef _LANAPI_H_
  28. #define _LANAPI_H_
  29. #include "GameNetwork/Transport.h"
  30. #include "GameNetwork/NetworkInterface.h"
  31. #include "GameNetwork/NetworkDefs.h"
  32. #include "GameNetwork/LANPlayer.h"
  33. #include "GameNetwork/LANGameInfo.h"
  34. //static const Int g_lanPlayerNameLength = 20;
  35. static const Int g_lanPlayerNameLength = 12; // reduced length because of game option length
  36. //static const Int g_lanLoginNameLength = 16;
  37. //static const Int g_lanHostNameLength = 16;
  38. static const Int g_lanLoginNameLength = 1;
  39. static const Int g_lanHostNameLength = 1;
  40. //static const Int g_lanGameNameLength = 32;
  41. static const Int g_lanGameNameLength = 16; // reduced length because of game option length
  42. static const Int g_lanGameNameReservedLength = 16; // save N wchars for ID info
  43. static const Int g_lanMaxChatLength = 100;
  44. static const Int m_lanMaxOptionsLength = MAX_PACKET_SIZE - ( 8 + (g_lanGameNameLength+1)*2 + 4 + (g_lanPlayerNameLength+1)*2
  45. + (g_lanLoginNameLength+1) + (g_lanHostNameLength+1) );
  46. static const Int g_maxSerialLength = 23; // including the trailing '\0'
  47. struct LANMessage;
  48. /**
  49. * The LANAPI class is used to instantiate a singleton which
  50. * implements the interface to all LAN broadcast communications.
  51. */
  52. class LANAPIInterface : public SubsystemInterface
  53. {
  54. public:
  55. virtual ~LANAPIInterface() { };
  56. virtual void init( void ) = 0; ///< Initialize or re-initialize the instance
  57. virtual void reset( void ) = 0; ///< reset the logic system
  58. virtual void update( void ) = 0; ///< update the world
  59. virtual void setIsActive(Bool isActive ) = 0; ///< Tell TheLAN whether or not the app is active.
  60. // Possible types of chat messages
  61. enum ChatType
  62. {
  63. LANCHAT_NORMAL = 0,
  64. LANCHAT_EMOTE,
  65. LANCHAT_SYSTEM,
  66. LANCHAT_MAX
  67. };
  68. // Request functions generate network traffic
  69. virtual void RequestLocations( void ) = 0; ///< Request everybody to respond with where they are
  70. virtual void RequestGameJoin( LANGameInfo *game, UnsignedInt ip = 0 ) = 0; ///< Request to join a game
  71. virtual void RequestGameJoinDirectConnect( UnsignedInt ipaddress ) = 0; ///< Request to join a game at an IP address
  72. virtual void RequestGameLeave( void ) = 0; ///< Tell everyone we're leaving
  73. virtual void RequestAccept( void ) = 0; ///< Indicate we're OK with the game options
  74. virtual void RequestHasMap( void ) = 0; ///< Send our map status
  75. virtual void RequestChat( UnicodeString message, ChatType format ) = 0; ///< Send a chat message
  76. virtual void RequestGameStart( void ) = 0; ///< Tell everyone the game is starting
  77. virtual void RequestGameStartTimer( Int seconds ) = 0;
  78. virtual void RequestGameOptions( AsciiString gameOptions, Bool isPublic, UnsignedInt ip = 0 ) = 0; ///< Change the game options
  79. virtual void RequestGameCreate( UnicodeString gameName, Bool isDirectConnect ) = 0; ///< Try to host a game
  80. virtual void RequestGameAnnounce( void ) = 0; ///< Sound out current game info if host
  81. // virtual void RequestSlotList( void ) = 0; ///< Pump out the Slot info.
  82. virtual void RequestSetName( UnicodeString newName ) = 0; ///< Pick a new name
  83. virtual void RequestLobbyLeave( Bool forced ) = 0; ///< Announce that we're leaving the lobby
  84. virtual void ResetGameStartTimer( void ) = 0;
  85. // Possible result codes passed to On functions
  86. enum ReturnType
  87. {
  88. RET_OK, // Any function
  89. RET_TIMEOUT, // OnGameJoin/Leave/Start, etc
  90. RET_GAME_FULL, // OnGameJoin
  91. RET_DUPLICATE_NAME, // OnGameJoin
  92. RET_CRC_MISMATCH, // OnGameJoin
  93. RET_SERIAL_DUPE, // OnGameJoin
  94. RET_GAME_STARTED, // OnGameJoin
  95. RET_GAME_EXISTS, // OnGameCreate
  96. RET_GAME_GONE, // OnGameJoin
  97. RET_BUSY, // OnGameCreate/Join/etc if another action is in progress
  98. RET_UNKNOWN, // Default message for oddity
  99. RET_MAX
  100. };
  101. UnicodeString getErrorStringFromReturnType( ReturnType ret );
  102. // On functions are (generally) the result of network traffic
  103. virtual void OnGameList( LANGameInfo *gameList ) = 0; ///< List of games
  104. virtual void OnPlayerList( LANPlayer *playerList ) = 0; ///< List of players in the Lobby
  105. virtual void OnGameJoin( ReturnType ret, LANGameInfo *theGame ) = 0; ///< Did we get in the game?
  106. virtual void OnPlayerJoin( Int slot, UnicodeString playerName ) = 0; ///< Someone else joined our game (host only; joiners get a slotlist)
  107. virtual void OnHostLeave( void ) = 0; ///< Host left the game
  108. virtual void OnPlayerLeave( UnicodeString player ) = 0; ///< Someone left the game
  109. virtual void OnAccept( UnsignedInt playerIP, Bool status ) = 0; ///< Someone's accept status changed
  110. virtual void OnHasMap( UnsignedInt playerIP, Bool status ) = 0; ///< Someone's map status changed
  111. virtual void OnChat( UnicodeString player, UnsignedInt ip,
  112. UnicodeString message, ChatType format ) = 0; ///< Chat message from someone
  113. virtual void OnGameStart( void ) = 0; ///< The game is starting
  114. virtual void OnGameStartTimer( Int seconds ) = 0;
  115. virtual void OnGameOptions( UnsignedInt playerIP, Int playerSlot, AsciiString options ) = 0; ///< Someone sent game options
  116. virtual void OnGameCreate( ReturnType ret ) = 0; ///< Your game is created
  117. // virtual void OnSlotList( ReturnType ret, LANGameInfo *theGame ) = 0; ///< Slotlist for a game in setup
  118. virtual void OnNameChange( UnsignedInt IP, UnicodeString newName ) = 0; ///< Someone has morphed
  119. // Misc utility functions
  120. virtual LANGameInfo * LookupGame( UnicodeString gameName ) = 0; ///< return a pointer to a game we know about
  121. virtual LANGameInfo * LookupGameByListOffset( Int offset ) = 0; ///< return a pointer to a game we know about
  122. virtual Bool SetLocalIP( UnsignedInt localIP ) = 0; ///< For multiple NIC machines
  123. virtual void SetLocalIP( AsciiString localIP ) = 0; ///< For multiple NIC machines
  124. virtual Bool AmIHost( void ) = 0; ///< Am I hosting a game?
  125. virtual inline UnicodeString GetMyName( void ) = 0; ///< What's my name?
  126. virtual inline LANGameInfo *GetMyGame( void ) = 0; ///< What's my Game?
  127. virtual void fillInLANMessage( LANMessage *msg ) = 0; ///< Fill in default params
  128. virtual void checkMOTD( void ) = 0;
  129. };
  130. /**
  131. * The LANAPI class is used to instantiate a singleton which
  132. * implements the interface to all LAN broadcast communications.
  133. */
  134. class LANAPI : public LANAPIInterface
  135. {
  136. public:
  137. LANAPI();
  138. virtual ~LANAPI();
  139. virtual void init( void ); ///< Initialize or re-initialize the instance
  140. virtual void reset( void ); ///< reset the logic system
  141. virtual void update( void ); ///< update the world
  142. virtual void setIsActive(Bool isActive); ///< tell TheLAN whether or not
  143. // Request functions generate network traffic
  144. virtual void RequestLocations( void ); ///< Request everybody to respond with where they are
  145. virtual void RequestGameJoin( LANGameInfo *game, UnsignedInt ip = 0 ); ///< Request to join a game
  146. virtual void RequestGameJoinDirectConnect( UnsignedInt ipaddress ); ///< Request to join a game at an IP address
  147. virtual void RequestGameLeave( void ); ///< Tell everyone we're leaving
  148. virtual void RequestAccept( void ); ///< Indicate we're OK with the game options
  149. virtual void RequestHasMap( void ); ///< Send our map status
  150. virtual void RequestChat( UnicodeString message, ChatType format ); ///< Send a chat message
  151. virtual void RequestGameStart( void ); ///< Tell everyone the game is starting
  152. virtual void RequestGameStartTimer( Int seconds );
  153. virtual void RequestGameOptions( AsciiString gameOptions, Bool isPublic, UnsignedInt ip = 0 ); ///< Change the game options
  154. virtual void RequestGameCreate( UnicodeString gameName, Bool isDirectConnect ); ///< Try to host a game
  155. virtual void RequestGameAnnounce( void ); ///< Send out game info if host
  156. virtual void RequestSetName( UnicodeString newName ); ///< Pick a new name
  157. // virtual void RequestSlotList( void ); ///< Pump out the Slot info.
  158. virtual void RequestLobbyLeave( Bool forced ); ///< Announce that we're leaving the lobby
  159. virtual void ResetGameStartTimer( void );
  160. // On functions are (generally) the result of network traffic
  161. virtual void OnGameList( LANGameInfo *gameList ); ///< List of games
  162. virtual void OnPlayerList( LANPlayer *playerList ); ///< List of players in the Lobby
  163. virtual void OnGameJoin( ReturnType ret, LANGameInfo *theGame ); ///< Did we get in the game?
  164. virtual void OnPlayerJoin( Int slot, UnicodeString playerName ); ///< Someone else joined our game (host only; joiners get a slotlist)
  165. virtual void OnHostLeave( void ); ///< Host left the game
  166. virtual void OnPlayerLeave( UnicodeString player ); ///< Someone left the game
  167. virtual void OnAccept( UnsignedInt playerIP, Bool status ); ///< Someone's accept status changed
  168. virtual void OnHasMap( UnsignedInt playerIP, Bool status ); ///< Someone's map status changed
  169. virtual void OnChat( UnicodeString player, UnsignedInt ip,
  170. UnicodeString message, ChatType format ); ///< Chat message from someone
  171. virtual void OnGameStart( void ); ///< The game is starting
  172. virtual void OnGameStartTimer( Int seconds );
  173. virtual void OnGameOptions( UnsignedInt playerIP, Int playerSlot, AsciiString options ); ///< Someone sent game options
  174. virtual void OnGameCreate( ReturnType ret ); ///< Your game is created
  175. //virtual void OnSlotList( ReturnType ret, LANGameInfo *theGame ); ///< Slotlist for a game in setup
  176. virtual void OnNameChange( UnsignedInt IP, UnicodeString newName ); ///< Someone has morphed
  177. virtual void OnInActive( UnsignedInt IP ); ///< Someone has alt-tabbed out.
  178. // Misc utility functions
  179. virtual LANGameInfo * LookupGame( UnicodeString gameName ); ///< return a pointer to a game we know about
  180. virtual LANGameInfo * LookupGameByListOffset( Int offset ); ///< return a pointer to a game we know about
  181. virtual LANPlayer * LookupPlayer( UnsignedInt playerIP ); ///< return a pointer to a player we know about
  182. virtual Bool SetLocalIP( UnsignedInt localIP ); ///< For multiple NIC machines
  183. virtual void SetLocalIP( AsciiString localIP ); ///< For multiple NIC machines
  184. virtual Bool AmIHost( void ); ///< Am I hosting a game?
  185. virtual inline UnicodeString GetMyName( void ) { return m_name; } ///< What's my name?
  186. virtual inline LANGameInfo* GetMyGame( void ) { return m_currentGame; } ///< What's my Game?
  187. virtual inline UnsignedInt GetLocalIP( void ) { return m_localIP; } ///< What's my IP?
  188. virtual void fillInLANMessage( LANMessage *msg ); ///< Fill in default params
  189. virtual void checkMOTD( void );
  190. protected:
  191. enum PendingActionType
  192. {
  193. ACT_NONE = 0,
  194. ACT_JOIN,
  195. ACT_JOINDIRECTCONNECT,
  196. ACT_LEAVE,
  197. ACT_MAX
  198. };
  199. static const UnsignedInt s_resendDelta; // in ms
  200. protected:
  201. LANPlayer * m_lobbyPlayers; ///< List of players in the lobby
  202. LANGameInfo * m_games; ///< List of games
  203. UnicodeString m_name; ///< Who do we think we are?
  204. AsciiString m_userName; ///< login name
  205. AsciiString m_hostName; ///< machine name
  206. UnsignedInt m_gameStartTime;
  207. Int m_gameStartSeconds;
  208. PendingActionType m_pendingAction; ///< What action are we performing?
  209. UnsignedInt m_expiration; ///< When should we give up on our action?
  210. UnsignedInt m_actionTimeout;
  211. UnsignedInt m_directConnectRemoteIP;///< The IP address of the game we are direct connecting to.
  212. // Resend timer ---------------------------------------------------------------------------
  213. UnsignedInt m_lastResendTime; // in ms
  214. Bool m_isInLANMenu; ///< true while we are in a LAN menu (lobby, game options, direct connect)
  215. Bool m_inLobby; ///< Are we in the lobby (not in a game)?
  216. LANGameInfo * m_currentGame; ///< Pointer to game (setup screen) we are currently in (NULL for lobby)
  217. //LANGameInfo *m_currentGameInfo; ///< Pointer to game setup info we are currently in.
  218. UnsignedInt m_localIP;
  219. Transport* m_transport;
  220. UnsignedInt m_broadcastAddr;
  221. UnsignedInt m_lastUpdate;
  222. AsciiString m_lastGameopt; /// @todo: hack for demo - remove this
  223. Bool m_isActive; ///< is the game currently active?
  224. protected:
  225. void sendMessage(LANMessage *msg, UnsignedInt ip = 0); // Convenience function
  226. void removePlayer(LANPlayer *player);
  227. void removeGame(LANGameInfo *game);
  228. void addPlayer(LANPlayer *player);
  229. void addGame(LANGameInfo *game);
  230. AsciiString createSlotString( void );
  231. // Functions to handle incoming messages -----------------------------------
  232. void handleRequestLocations( LANMessage *msg, UnsignedInt senderIP );
  233. void handleGameAnnounce( LANMessage *msg, UnsignedInt senderIP );
  234. void handleLobbyAnnounce( LANMessage *msg, UnsignedInt senderIP );
  235. void handleRequestGameInfo( LANMessage *msg, UnsignedInt senderIP );
  236. void handleRequestJoin( LANMessage *msg, UnsignedInt senderIP );
  237. void handleJoinAccept( LANMessage *msg, UnsignedInt senderIP );
  238. void handleJoinDeny( LANMessage *msg, UnsignedInt senderIP );
  239. void handleRequestGameLeave( LANMessage *msg, UnsignedInt senderIP );
  240. void handleRequestLobbyLeave( LANMessage *msg, UnsignedInt senderIP );
  241. void handleSetAccept( LANMessage *msg, UnsignedInt senderIP );
  242. void handleHasMap( LANMessage *msg, UnsignedInt senderIP );
  243. void handleChat( LANMessage *msg, UnsignedInt senderIP );
  244. void handleGameStart( LANMessage *msg, UnsignedInt senderIP );
  245. void handleGameStartTimer( LANMessage *msg, UnsignedInt senderIP );
  246. void handleGameOptions( LANMessage *msg, UnsignedInt senderIP );
  247. void handleInActive( LANMessage *msg, UnsignedInt senderIP );
  248. };
  249. /**
  250. * LAN message class
  251. */
  252. #pragma pack(push, 1)
  253. struct LANMessage
  254. {
  255. enum ///< What kind of message are we?
  256. {
  257. // Locating everybody
  258. MSG_REQUEST_LOCATIONS, ///< Hey, where is everybody?
  259. MSG_GAME_ANNOUNCE, ///< Here I am, and here's my game info!
  260. MSG_LOBBY_ANNOUNCE, ///< Hey, I'm in the lobby!
  261. // Joining games
  262. MSG_REQUEST_JOIN, ///< Let me in! Let me in!
  263. MSG_JOIN_ACCEPT, ///< Okay, you can join.
  264. MSG_JOIN_DENY, ///< Go away! We don't want any!
  265. // Leaving games
  266. MSG_REQUEST_GAME_LEAVE, ///< I want to leave the game
  267. MSG_REQUEST_LOBBY_LEAVE,///< I'm leaving the lobby
  268. // Game options, chat, etc
  269. MSG_SET_ACCEPT, ///< I'm cool with everything as is.
  270. MSG_MAP_AVAILABILITY, ///< I do (not) have the map.
  271. MSG_CHAT, ///< Just spouting my mouth off.
  272. MSG_GAME_START, ///< Hold on; we're starting!
  273. MSG_GAME_START_TIMER, ///< The game will start in N seconds
  274. MSG_GAME_OPTIONS, ///< Here's some info about the game.
  275. MSG_INACTIVE, ///< I've alt-tabbed out. Unaccept me cause I'm a poo-flinging monkey.
  276. MSG_REQUEST_GAME_INFO, ///< For direct connect, get the game info from a specific IP Address
  277. MSG_MAX
  278. } LANMessageType;
  279. WideChar name[g_lanPlayerNameLength+1]; ///< My name, for convenience
  280. char userName[g_lanLoginNameLength+1]; ///< login name, for convenience
  281. char hostName[g_lanHostNameLength+1]; ///< machine name, for convenience
  282. // No additional data is required for REQUEST_LOCATIONS, LOBBY_ANNOUNCE,
  283. // REQUEST_LOBBY_LEAVE, GAME_START.
  284. union
  285. {
  286. // StartTimer is sent with GAME_START_TIMER
  287. struct
  288. {
  289. Int seconds;
  290. } StartTimer;
  291. // GameJoined is sent with REQUEST_GAME_LEAVE
  292. struct
  293. {
  294. WideChar gameName[g_lanGameNameLength+1];
  295. } GameToLeave;
  296. // GameInfo if sent with GAME_ANNOUNCE
  297. struct
  298. {
  299. WideChar gameName[g_lanGameNameLength+1];
  300. Bool inProgress;
  301. char options[m_lanMaxOptionsLength+1];
  302. Bool isDirectConnect;
  303. } GameInfo;
  304. // PlayerInfo is sent with REQUEST_GAME_INFO for direct connect games.
  305. struct
  306. {
  307. UnsignedInt ip;
  308. WideChar playerName[g_lanPlayerNameLength+1];
  309. } PlayerInfo;
  310. // GameToJoin is sent with REQUEST_JOIN
  311. struct
  312. {
  313. UnsignedInt gameIP;
  314. UnsignedInt exeCRC;
  315. UnsignedInt iniCRC;
  316. char serial[g_maxSerialLength];
  317. } GameToJoin;
  318. // GameJoined is sent with JOIN_ACCEPT
  319. struct
  320. {
  321. WideChar gameName[g_lanGameNameLength+1];
  322. UnsignedInt gameIP;
  323. UnsignedInt playerIP;
  324. Int slotPosition;
  325. } GameJoined;
  326. // GameNotJoined is sent with JOIN_DENY
  327. struct
  328. {
  329. WideChar gameName[g_lanGameNameLength+1];
  330. UnsignedInt gameIP;
  331. UnsignedInt playerIP;
  332. LANAPIInterface::ReturnType reason;
  333. } GameNotJoined;
  334. // Accept is sent with SET_ACCEPT
  335. struct
  336. {
  337. WideChar gameName[g_lanGameNameLength+1];
  338. Bool isAccepted;
  339. } Accept;
  340. // Accept is sent with MAP_AVAILABILITY
  341. struct
  342. {
  343. WideChar gameName[g_lanGameNameLength+1];
  344. UnsignedInt mapCRC; // to make sure we're talking about the same map
  345. Bool hasMap;
  346. } MapStatus;
  347. // Chat is sent with CHAT
  348. struct
  349. {
  350. WideChar gameName[g_lanGameNameLength+1];
  351. LANAPIInterface::ChatType chatType;
  352. WideChar message[g_lanMaxChatLength+1];
  353. } Chat;
  354. // GameOptions is sent with GAME_OPTIONS
  355. struct
  356. {
  357. char options[m_lanMaxOptionsLength+1];
  358. } GameOptions;
  359. };
  360. };
  361. #pragma pack(pop)
  362. #endif // _LANAPI_H_