rengameres.cpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  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. Project Name: Generic Game Results Server
  22. File Name : rengameres.cpp
  23. Author : Joe Howes ([email protected])
  24. Start Date : Apr 5, 2000
  25. Last Update :
  26. ------------------------------------------------------------------------------
  27. Wraps game results for a game of multiplayer Renegade and provides method
  28. for sending to a WOL game results server.
  29. \****************************************************************************/
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include <assert.h>
  33. #include "packet.h"
  34. #include "tcpmgr.h"
  35. #include "tcpcon.h"
  36. #include "wencrypt.h"
  37. #include "rengameres.h"
  38. RenegadeGameRes::~RenegadeGameRes()
  39. {
  40. if( _host != NULL ) delete[] _host;
  41. if( _map_name != NULL ) delete[] _map_name;
  42. if( _logins != NULL )
  43. {
  44. for(int i = 0; i < _myplayercount; i++)
  45. if( _logins[i] != NULL ) delete[] _logins[i];
  46. delete[] _logins;
  47. }
  48. if( _scores != NULL ) delete[] _scores;
  49. if( _clan_ids != NULL ) delete[] _clan_ids;
  50. if( _durations != NULL ) delete[] _durations;
  51. if( _ips != NULL ) delete[] _ips;
  52. if( _deaths != NULL ) delete[] _deaths;
  53. if( _kills != NULL ) delete[] _kills;
  54. if( _selfkills != NULL ) delete[] _selfkills;
  55. if( _damagepoints != NULL ) delete[] _damagepoints;
  56. }
  57. void RenegadeGameRes::setMapName(const char* val)
  58. {
  59. if( _map_name != NULL ) delete[] _map_name;
  60. if( val == NULL ) return;
  61. _map_name = new char[strlen(val)+1];
  62. strcpy(_map_name, val);
  63. }
  64. void RenegadeGameRes::addPlayer(const char* login, double score, long unsigned int clan_id,
  65. long unsigned int duration, long unsigned int ip,
  66. long unsigned int deaths, long unsigned int kills,
  67. long unsigned int selfkills, long unsigned int damagepoints)
  68. {
  69. char** newstr = _addToArr(_logins, login);
  70. delete[] _logins;
  71. _logins = newstr;
  72. // There's no happy easy way to shoot a floating value over
  73. // the wire. The values in jscores are in (0.0 <= x <= 1.0), so
  74. // we take the maximum value for a 4-byte int and multiply it
  75. // by the jscore floating value. We now have a scale of the same
  76. // accuracy as a 4-byte float.
  77. // Expecting a score X such that -0.5 <= X <= 0.5
  78. score += 0.5; // So that it can be stored unsigned
  79. long unsigned int convscore = (long unsigned int)(score * GR_SCORE_SCALE);
  80. long unsigned int* newlui = _addToArr(_scores, convscore);
  81. delete[] _scores;
  82. _scores = newlui;
  83. newlui = _addToArr(_clan_ids, clan_id);
  84. delete[] _clan_ids;
  85. _clan_ids = newlui;
  86. newlui = _addToArr(_durations, duration);
  87. delete[] _durations;
  88. _durations = newlui;
  89. newlui = _addToArr(_ips, ip);
  90. delete[] _ips;
  91. _ips = newlui;
  92. newlui = _addToArr(_deaths, deaths);
  93. delete[] _deaths;
  94. _deaths = newlui;
  95. newlui = _addToArr(_kills, kills);
  96. delete[] _kills;
  97. _kills = newlui;
  98. newlui = _addToArr(_selfkills, selfkills);
  99. delete[] _selfkills;
  100. _selfkills = newlui;
  101. newlui = _addToArr(_damagepoints, damagepoints);
  102. delete[] _damagepoints;
  103. _damagepoints = newlui;
  104. _myplayercount++; // *** MUST BE INCREMENTED __AFTER__ ADDING ALL THIS STUFF!!!! ***
  105. }
  106. int RenegadeGameRes::sendResults()
  107. {
  108. assert( _host != NULL );
  109. assert( _port != 0 );
  110. //GameResPacket grPacket
  111. // Build the packet
  112. PacketClass rawPacket;
  113. rawPacket.Add_Field(GR_GAME_ID, _game_id);
  114. rawPacket.Add_Field(GR_PLAYER_COUNT, (long)_player_count);
  115. rawPacket.Add_Field(GR_CLAN_GAME, _clan_game);
  116. rawPacket.Add_Field(GR_DURATION, _duration);
  117. rawPacket.Add_Field(GR_MAP_NAME, _map_name);
  118. rawPacket.Add_Field(GR_SKU, _sku);
  119. rawPacket.Add_Field(GR_STYLE, _style);
  120. rawPacket.Add_Field(GR_NUM_CLANS, _num_clans);
  121. rawPacket.Add_Field(GR_START_TIME, _start_time);
  122. rawPacket.Add_Field(GR_TOURNAMENT, _tournament);
  123. for (int i = 0 ; i < _player_count; i++)
  124. {
  125. GR_LOGINS[3] = (char)('0' + (char)i);
  126. rawPacket.Add_Field(GR_LOGINS, (char *)((const char*)_logins[i]));
  127. GR_SCORES[3] = (char)('0' + (char)i);
  128. rawPacket.Add_Field(GR_SCORES, _scores[i]);
  129. GR_CLANIDS[3] = (char)('0' + (char)i);
  130. rawPacket.Add_Field(GR_CLANIDS, _clan_ids[i]);
  131. GR_DURATIONS[3] = (char)('0' + (char)i);
  132. rawPacket.Add_Field(GR_DURATIONS, _durations[i]);
  133. GR_IPS[3] = (char)('0' + (char)i);
  134. rawPacket.Add_Field(GR_IPS, _ips[i]);
  135. GR_DEATHS[3] = (char)('0' + (char)i);
  136. rawPacket.Add_Field(GR_DEATHS, _deaths[i]);
  137. GR_KILLS[3] = (char)('0' + (char)i);
  138. rawPacket.Add_Field(GR_KILLS, _kills[i]);
  139. GR_SELFKILLS[3] = (char)('0' + (char)i);
  140. rawPacket.Add_Field(GR_SELFKILLS, _selfkills[i]);
  141. GR_DAMAGEPOINTS[3] = (char)('0' + (char)i);
  142. rawPacket.Add_Field(GR_DAMAGEPOINTS, _damagepoints[i]);
  143. }
  144. int packetsize = 0;
  145. void* outPacket = rawPacket.Create_Comms_Packet(packetsize);
  146. void* encPacket = PrepareEncryptedPacket((unsigned char*)outPacket, &packetsize);
  147. bit8 result = 0;
  148. sint32 sendlen = 0;
  149. // If the _host member is not set, then this method is being called in-game
  150. // and wants to use the WOLAPI methods to send game results. Otherwise it
  151. // is some small test application and we will use the tcp classes provided by Neal.
  152. #ifndef GRSETTING_USING_WOLAPI
  153. TCPMgr tcpMgr;
  154. TCPCon* tcpCon;
  155. uint32 handle = -1;
  156. result = tcpMgr.connect(_host, _port, &handle);
  157. if( result == FALSE )
  158. sendlen = GR_ERROR_BIND_FAILED;
  159. else
  160. {
  161. result = tcpMgr.getOutgoingConnection(&tcpCon, handle, 5);
  162. if( result == FALSE )
  163. sendlen = GR_ERROR_CONNECT_FAILED;
  164. else
  165. {
  166. sendlen = tcpCon->write((uint8*)encPacket, packetsize, 5);
  167. tcpCon->close();
  168. }
  169. }
  170. #else
  171. result = RequestGameresSend( _host, _port, encPacket, packetsize );
  172. #endif
  173. // Clean up
  174. delete[] outPacket;
  175. delete[] encPacket;
  176. if( _host != NULL )
  177. return sendlen;
  178. else
  179. return (int)result;
  180. return 0;
  181. }
  182. /*----------------------------------------------------------------------------------.
  183. | METHOD: _addToArr |
  184. | Takes a pointer to an array and a new item, constructs a new array and returns |
  185. | a pointer to it. |
  186. `----------------------------------------------------------------------------------*/
  187. char** RenegadeGameRes::_addToArr(char** arr, const char* item)
  188. {
  189. char** newarr = NULL;
  190. if( arr == NULL )
  191. {
  192. // Make a new array
  193. assert( _myplayercount == 0 );
  194. newarr = new char*[1];
  195. newarr[0] = new char[strlen(item)+1]; // Space for the new item
  196. // Add the new item
  197. strcpy(newarr[_myplayercount], item);
  198. }
  199. else
  200. {
  201. // Make a new array and copy all the old stuff over
  202. int i = 0;
  203. assert( _myplayercount > 0 );
  204. newarr = new char*[_myplayercount+1];
  205. for(i = 0; i < _myplayercount; i++)
  206. newarr[i] = arr[i];
  207. newarr[_myplayercount] = new char[strlen(item)+1];
  208. // Add the new item
  209. strcpy(newarr[_myplayercount], item);
  210. }
  211. return newarr;
  212. }
  213. /*----------------------------------------------------------------------------------.
  214. | METHOD: _addToArr |
  215. | Takes a pointer to an array and a new item, constructs a new array and returns |
  216. | a pointer to it. |
  217. `----------------------------------------------------------------------------------*/
  218. long unsigned int* RenegadeGameRes::_addToArr(long unsigned int* arr, long unsigned int item)
  219. {
  220. long unsigned int* newarr = NULL;
  221. if( arr == NULL )
  222. {
  223. // Make a new array
  224. assert( _myplayercount == 0 );
  225. newarr = new long unsigned int[1];
  226. // Add the new item
  227. newarr[0] = item;
  228. }
  229. else
  230. {
  231. // Make a new array and copy all the old stuff over
  232. assert( _myplayercount > 0 );
  233. newarr = new long unsigned int[_myplayercount+1];
  234. for(int i = 0; i < _myplayercount; i++)
  235. newarr[i] = arr[i];
  236. // Add the new item
  237. newarr[_myplayercount] = item;
  238. }
  239. return newarr;
  240. }