natter.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. /*
  2. ** Command & Conquer Renegade(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. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : Command & Conquer *
  23. * *
  24. * $Archive:: /Commando/Code/Commando/natter.h $*
  25. * *
  26. * $Author:: Steve_t $*
  27. * *
  28. * $Modtime:: 3/01/02 2:27p $*
  29. * *
  30. * $Revision:: 18 $*
  31. * *
  32. * *
  33. *---------------------------------------------------------------------------------------------*
  34. * *
  35. * *
  36. *---------------------------------------------------------------------------------------------*
  37. * *
  38. * Functions: *
  39. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  40. #pragma once
  41. #ifndef NATTER_H
  42. #define NATTER_H
  43. #include "always.h"
  44. //#include "nat.h"
  45. #include "nataddr.h"
  46. /*
  47. ** Project specific includes.
  48. */
  49. #include <Notify.h>
  50. #include <wwonline\wolsession.h>
  51. #include <wwonline\woluser.h>
  52. #include <combat\combat.h>
  53. #include <wwnet\wwpacket.h>
  54. /*
  55. ** Commonly available components.
  56. */
  57. #include <wwlib\vector.h>
  58. #ifdef WWASSERT
  59. #ifndef fw_assert
  60. #define fw_assert WWASSERT
  61. #endif //fw_assert
  62. #else //WWASSERT
  63. #define fw_assert assert
  64. #endif //WWASSERT
  65. /*
  66. ** Size of temporary game options storage buffers.
  67. */
  68. #define OPTIONS_STAGING_BUFFER_SIZE 512
  69. #define PORT_BASE_MIN 1024
  70. #define PORT_BASE_MAX 4095
  71. #define PORT_POOL_MIN 4096
  72. #define PORT_POOL_MAX 65535
  73. /*
  74. ** Forward declarations.
  75. */
  76. class SocketHandlerClass;
  77. class RegistryClass;
  78. /*
  79. ** This class performs the inevitable task of interfacing with whatever piece of code happens to be talking to WOLAPI.
  80. **
  81. ** Will have to be completely replaced per project.
  82. **
  83. */
  84. class WOLNATInterfaceClass : public Observer<WWOnline::UserEvent>,
  85. public Observer<WWOnline::GameOptionsMessage>,
  86. public Observer<WWOnline::ConnectionStatus>,
  87. public Observer<WWOnline::UserIPEvent>
  88. {
  89. public:
  90. /*
  91. ** Constructor, destructor.
  92. */
  93. WOLNATInterfaceClass(void);
  94. ~WOLNATInterfaceClass(void);
  95. /*
  96. ** Startup, shutdown.
  97. */
  98. void Init(void);
  99. void Shutdown(void);
  100. /*
  101. ** Service.
  102. */
  103. void Service(void);
  104. void Set_Service_Socket_Handler(SocketHandlerClass *socket);
  105. void Service_Receive_Queue(SocketHandlerClass *socket);
  106. /*
  107. ** User event notification.
  108. */
  109. void HandleNotification(WWOnline::UserEvent&);
  110. /*
  111. ** Game options notificaton.
  112. */
  113. void HandleNotification(WWOnline::GameOptionsMessage&);
  114. /*
  115. ** Server connection notification.
  116. */
  117. void HandleNotification(WWOnline::ConnectionStatus&);
  118. /*
  119. ** User IP event.
  120. */
  121. void HandleNotification(WWOnline::UserIPEvent&);
  122. /*
  123. ** Server query.
  124. */
  125. void Get_Current_Server_ConnData(char *buffer, int size);
  126. /*
  127. ** Private game options.
  128. */
  129. void Send_Private_Game_Options(WOL::User *user, char *options);
  130. bool Get_Private_Game_Options(WOL::User *user, char *options, int option_buffer_len);
  131. /*
  132. ** Conversion.
  133. */
  134. char *Get_Silly_String(WideStringClass *silly_string, char *buffer, int buffer_size);
  135. /*
  136. ** Game packet handling.
  137. */
  138. bool Get_Packet(char *packet_buffer, int buffer_size, IPAddressClass &address);
  139. void Intercept_Game_Packet(cPacket &packet);
  140. bool Send_Game_Format_Packet_To(IPAddressClass *address, char *payload, int payload_size, SocketHandlerClass *socket_handler = NULL);
  141. /*
  142. ** General game helper functions.
  143. */
  144. bool Get_My_Name(char *namebuf);
  145. bool Am_I_Server(void) {return(IsServer);};
  146. void Set_Server(bool is_server);
  147. void Set_Server_Negotiated_Address(IPAddressClass *server_address);
  148. DynamicVectorClass<WOL::Server*> Get_Mangler_Server_List(void);
  149. unsigned short Get_Mangler_Port_By_Index(int index);
  150. bool Get_Mangler_Name_By_Index(int index, char *mangler_name);
  151. int Get_Num_Mangler_Servers(void);
  152. unsigned long Get_Local_Address(void) {
  153. return(0);//return(FirewallHelper.Get_Local_Address());
  154. };
  155. void Tell_Server_That_Client_Is_In_Channel(void);
  156. bool Is_NAT_Thread_Busy(void);
  157. /*
  158. ** Game port management.
  159. */
  160. unsigned short Get_Next_Client_Port(void);
  161. unsigned short Get_Port_As_Server(void);
  162. unsigned short Get_Port_As_Server_Client(void);
  163. unsigned short Get_Force_Port(void) {return(ForcePort);};
  164. /*
  165. ** Config.
  166. */
  167. void Get_Config(RegistryClass *reg, int &port_number, bool &send_delay);
  168. void Set_Config(RegistryClass *reg, int port_number, bool send_delay);
  169. void Save_Firewall_Info_To_Registry(void);
  170. unsigned long Get_Reg_External_IP(void) {return(RegExternalIP);}
  171. unsigned long Get_Reg_External_Port(void) {return(RegExternalPort);}
  172. void Get_Compact_Log(StringClass &log_string);
  173. unsigned long Get_Chat_External_IP(void) {return(ChatExternalIP);}
  174. /*
  175. ** Game options string types.
  176. */
  177. enum {
  178. OPTION_ERROR = 'a',
  179. OPTION_INVITE_PORT_NEGOTIATION,
  180. OPTION_ACCEPT_PORT_NEGOTIATION_INVITATION,
  181. OPTION_PORT_NOTIFICATION,
  182. OPTION_CONNECTION_RESULT,
  183. OPTION_QUEUE_STATE,
  184. OPTION_ABORT_NEGOTIATION,
  185. OPTION_CLIENT_IN_CHANNEL
  186. };
  187. /*
  188. ** Game options format for the firewall code only. All firewall options packets are prefixed with "NAT:"
  189. */
  190. typedef struct tPrivateGameOptions {
  191. /*
  192. ** Option previx (Always "NAT:" for us.
  193. */
  194. char NATOptionsPrefix[4];
  195. /*
  196. ** Option type. See list above.
  197. */
  198. char Option;
  199. /*
  200. ** Option payload union. Each type of option has a different payload.
  201. */
  202. union tOptionData {
  203. /*
  204. ** Data for OPTION_INVITE_PORT_NEGOTIATION.
  205. */
  206. struct InvitationStruct {
  207. char LocalIP[9]; // 00000000,
  208. char LocalPort[5]; // 0000,
  209. char ExternalIP[9]; // 00000000,
  210. char FirewallType[9]; // 00000000,
  211. char Queued[5]; // 0000(null)
  212. } Invitation;
  213. /*
  214. ** Data for OPTION_ACCEPT_PORT_NEGOTIATION_INVITATION.
  215. */
  216. struct AcceptStruct {
  217. char LocalIP[9]; // 00000000,
  218. char LocalPort[5]; // 0000,
  219. char ExternalIP[9]; // 00000000,
  220. char FirewallType[9]; // 00000000(null)
  221. } Accept;
  222. /*
  223. ** Data for OPTION_PORT_NOTIFICATION.
  224. */
  225. struct PortStruct {
  226. char MangledPort[5]; // 0000,
  227. char Name[64]; // "Players name......"(null)
  228. } Port;
  229. /*
  230. ** Data for OPTION_CONNECTION_RESULT.
  231. */
  232. struct ConnectionResultStruct {
  233. char Result[2]; // n,
  234. char Port[5]; // 0000,
  235. char Name[64]; // "Players name......"(null)
  236. } ConnectionResult;
  237. /*
  238. ** Data for OPTION_QUEUE_STATE
  239. */
  240. struct QueueStateStruct {
  241. char Position[3]; // 00(null)
  242. } QueueState;
  243. /*
  244. ** Data for OPTION_ABORT_NEGOTIATION
  245. */
  246. struct QuitTalkingStruct {
  247. char Nothing; // 00
  248. } QuitTalking;
  249. /*
  250. ** Data for OPTION_CLIENT_IN_CHANNEL
  251. */
  252. struct ClientInChannelStruct {
  253. char Name[64]; // "Players name......"(null)
  254. } ClientInChannel;
  255. } OptionData;
  256. } PrivateGameOptionsStruct;
  257. private:
  258. /*
  259. ** PortBase is the start of the current port number range we are using. The range is added to the port base every time
  260. ** we start a new game so we are always using a fresh port. The server uses 2 ports per game and the client uses 1 port.
  261. */
  262. unsigned short PortBase;
  263. /*
  264. ** Set this to non-zero to force it to be used as the local port.
  265. */
  266. unsigned short ForcePort;
  267. /*
  268. ** External IP and port from the registry.
  269. */
  270. unsigned long RegExternalIP;
  271. unsigned short RegExternalPort;
  272. /*
  273. ** Our IP according to westwood chat.
  274. */
  275. unsigned long ChatExternalIP;
  276. /*
  277. ** Bloat pointer to the Session class.
  278. */
  279. RefPtr<WWOnline::Session> SessionPtr;
  280. /*
  281. ** Address we used to send to the server.
  282. */
  283. IPAddressClass ServerNegotiatedAddress;
  284. /*
  285. ** Holding area for incoming game packets.
  286. */
  287. struct GamePacketStruct {
  288. IPAddressClass FromAddress;
  289. unsigned char Payload[512];
  290. };
  291. DynamicVectorClass<GamePacketStruct*> IncomingPackets;
  292. /*
  293. ** This is the socket handler to use when sending or receiving game packets. It's only used on the client side since
  294. ** the server side has to use the games mechanisms to send and receive (the game already has a socket bound to the port
  295. ** we want to use in the server case).
  296. */
  297. SocketHandlerClass *ServiceSocketHandler;
  298. /*
  299. ** Am I a game server?
  300. */
  301. bool IsServer;
  302. /*
  303. ** Game options staging areas.
  304. */
  305. typedef struct tGameOptionsStagingStruct {
  306. WOL::User User;
  307. char Options[OPTIONS_STAGING_BUFFER_SIZE];
  308. } GameOptionsStagingStruct;
  309. DynamicVectorClass<GameOptionsStagingStruct*> IncomingOptions;
  310. DynamicVectorClass<GameOptionsStagingStruct*> OutgoingOptions;
  311. /*
  312. ** Mutex to serialise access to game options.
  313. */
  314. HANDLE GameOptionsMutex;
  315. /*
  316. ** Thread safety for game options.
  317. */
  318. class ThreadLockClass
  319. {
  320. public:
  321. /*
  322. ** Constructor. Grabs the mutex.
  323. */
  324. inline ThreadLockClass(WOLNATInterfaceClass *wnptr) {
  325. WNPtr = wnptr;
  326. int deadlock = WaitForSingleObject(wnptr->GameOptionsMutex, 10 * 1000);
  327. if (deadlock == WAIT_TIMEOUT) {
  328. WWDEBUG_SAY(("FirewallHelper - Timeout waiting for firewall helper data mutex\n"));
  329. fw_assert(deadlock != WAIT_TIMEOUT);
  330. }
  331. };
  332. WOLNATInterfaceClass *WNPtr;
  333. /*
  334. ** Destructor, releases the mutex.
  335. */
  336. inline ~ThreadLockClass(void) {
  337. ReleaseMutex(WNPtr->GameOptionsMutex);
  338. };
  339. };
  340. friend ThreadLockClass;
  341. };
  342. /*
  343. ** Extern for single instance of the WOLNATInterface.
  344. */
  345. extern WOLNATInterfaceClass WOLNATInterface;
  346. #endif //NATTER_H