/ggb_v1.0_src/ggb/gameprotocol.cpp

http://ghostcb.googlecode.com/ · C++ · 253 lines · 168 code · 40 blank · 45 comment · 25 complexity · ac42f3ddf29c54ef7ec15ee7d592aa0d MD5 · raw file

  1. /*
  2. Copyright 2010 Trevor Hogan
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. #include "ggb.h"
  14. #include "util.h"
  15. #include "gameprotocol.h"
  16. //
  17. // CGameProtocol
  18. //
  19. CGameProtocol :: CGameProtocol( CGHostGamesBroadcaster *nGGB )
  20. {
  21. m_GGB = nGGB;
  22. }
  23. CGameProtocol :: ~CGameProtocol( )
  24. {
  25. }
  26. ///////////////////////
  27. // RECEIVE FUNCTIONS //
  28. ///////////////////////
  29. ////////////////////
  30. // SEND FUNCTIONS //
  31. ////////////////////
  32. BYTEARRAY CGameProtocol :: SEND_W3GS_CHAT_FROM_HOST( unsigned char fromPID, BYTEARRAY toPIDs, unsigned char flag, BYTEARRAY flagExtra, string message )
  33. {
  34. BYTEARRAY packet;
  35. if( !toPIDs.empty( ) && !message.empty( ) && message.size( ) < 255 )
  36. {
  37. packet.push_back( W3GS_HEADER_CONSTANT ); // W3GS header constant
  38. packet.push_back( W3GS_CHAT_FROM_HOST ); // W3GS_CHAT_FROM_HOST
  39. packet.push_back( 0 ); // packet length will be assigned later
  40. packet.push_back( 0 ); // packet length will be assigned later
  41. packet.push_back( toPIDs.size( ) ); // number of receivers
  42. UTIL_AppendByteArrayFast( packet, toPIDs ); // receivers
  43. packet.push_back( fromPID ); // sender
  44. packet.push_back( flag ); // flag
  45. UTIL_AppendByteArrayFast( packet, flagExtra ); // extra flag
  46. UTIL_AppendByteArrayFast( packet, message ); // message
  47. AssignLength( packet );
  48. }
  49. else
  50. CONSOLE_Print( "[GAMEPROTO] invalid parameters passed to SEND_W3GS_CHAT_FROM_HOST" );
  51. // DEBUG_Print( "SENT W3GS_CHAT_FROM_HOST" );
  52. // DEBUG_Print( packet );
  53. return packet;
  54. }
  55. BYTEARRAY CGameProtocol :: SEND_W3GS_SEARCHGAME( bool TFT, unsigned char war3Version )
  56. {
  57. unsigned char ProductID_ROC[] = { 51, 82, 65, 87 }; // "WAR3"
  58. unsigned char ProductID_TFT[] = { 80, 88, 51, 87 }; // "W3XP"
  59. unsigned char Version[] = { war3Version, 0, 0, 0 };
  60. unsigned char Unknown[] = { 0, 0, 0, 0 };
  61. BYTEARRAY packet;
  62. packet.push_back( W3GS_HEADER_CONSTANT ); // W3GS header constant
  63. packet.push_back( W3GS_SEARCHGAME ); // W3GS_SEARCHGAME
  64. packet.push_back( 0 ); // packet length will be assigned later
  65. packet.push_back( 0 ); // packet length will be assigned later
  66. if( TFT )
  67. UTIL_AppendByteArray( packet, ProductID_TFT, 4 ); // Product ID (TFT)
  68. else
  69. UTIL_AppendByteArray( packet, ProductID_ROC, 4 ); // Product ID (ROC)
  70. UTIL_AppendByteArray( packet, Version, 4 ); // Version
  71. UTIL_AppendByteArray( packet, Unknown, 4 ); // ???
  72. AssignLength( packet );
  73. // DEBUG_Print( "SENT W3GS_SEARCHGAME" );
  74. // DEBUG_Print( packet );
  75. return packet;
  76. }
  77. BYTEARRAY CGameProtocol :: SEND_W3GS_GAMEINFO( bool TFT, unsigned char war3Version, BYTEARRAY mapGameType, BYTEARRAY mapFlags, BYTEARRAY mapWidth, BYTEARRAY mapHeight, string gameName, string hostName, uint32_t upTime, string mapPath, BYTEARRAY mapCRC, uint32_t slotsTotal, uint32_t slotsOpen, uint16_t port, uint32_t hostCounter, uint32_t entryKey )
  78. {
  79. unsigned char ProductID_ROC[] = { 51, 82, 65, 87 }; // "WAR3"
  80. unsigned char ProductID_TFT[] = { 80, 88, 51, 87 }; // "W3XP"
  81. unsigned char Version[] = { war3Version, 0, 0, 0 };
  82. unsigned char Unknown[] = { 1, 0, 0, 0 };
  83. BYTEARRAY packet;
  84. if( mapGameType.size( ) == 4 && mapFlags.size( ) == 4 && mapWidth.size( ) == 2 && mapHeight.size( ) == 2 && !gameName.empty( ) && !hostName.empty( ) && !mapPath.empty( ) && mapCRC.size( ) == 4 )
  85. {
  86. // make the stat string
  87. BYTEARRAY StatString;
  88. UTIL_AppendByteArrayFast( StatString, mapFlags );
  89. StatString.push_back( 0 );
  90. UTIL_AppendByteArrayFast( StatString, mapWidth );
  91. UTIL_AppendByteArrayFast( StatString, mapHeight );
  92. UTIL_AppendByteArrayFast( StatString, mapCRC );
  93. UTIL_AppendByteArrayFast( StatString, mapPath );
  94. UTIL_AppendByteArrayFast( StatString, hostName );
  95. StatString.push_back( 0 );
  96. StatString = UTIL_EncodeStatString( StatString );
  97. // make the rest of the packet
  98. packet.push_back( W3GS_HEADER_CONSTANT ); // W3GS header constant
  99. packet.push_back( W3GS_GAMEINFO ); // W3GS_GAMEINFO
  100. packet.push_back( 0 ); // packet length will be assigned later
  101. packet.push_back( 0 ); // packet length will be assigned later
  102. if( TFT )
  103. UTIL_AppendByteArray( packet, ProductID_TFT, 4 ); // Product ID (TFT)
  104. else
  105. UTIL_AppendByteArray( packet, ProductID_ROC, 4 ); // Product ID (ROC)
  106. UTIL_AppendByteArray( packet, Version, 4 ); // Version
  107. UTIL_AppendByteArray( packet, hostCounter, false ); // Host Counter
  108. UTIL_AppendByteArray( packet, entryKey, false ); // Entry Key
  109. UTIL_AppendByteArrayFast( packet, gameName ); // Game Name
  110. packet.push_back( 0 ); // ??? (maybe game password)
  111. UTIL_AppendByteArrayFast( packet, StatString ); // Stat String
  112. packet.push_back( 0 ); // Stat String null terminator (the stat string is encoded to remove all even numbers i.e. zeros)
  113. UTIL_AppendByteArray( packet, slotsTotal, false ); // Slots Total
  114. UTIL_AppendByteArrayFast( packet, mapGameType ); // Game Type
  115. UTIL_AppendByteArray( packet, Unknown, 4 ); // ???
  116. UTIL_AppendByteArray( packet, slotsOpen, false ); // Slots Open
  117. UTIL_AppendByteArray( packet, upTime, false ); // time since creation
  118. UTIL_AppendByteArray( packet, port, false ); // port
  119. AssignLength( packet );
  120. }
  121. else
  122. CONSOLE_Print( "[GAMEPROTO] invalid parameters passed to SEND_W3GS_GAMEINFO" );
  123. // DEBUG_Print( "SENT W3GS_GAMEINFO" );
  124. // DEBUG_Print( packet );
  125. return packet;
  126. }
  127. BYTEARRAY CGameProtocol :: SEND_W3GS_CREATEGAME( bool TFT, unsigned char war3Version )
  128. {
  129. unsigned char ProductID_ROC[] = { 51, 82, 65, 87 }; // "WAR3"
  130. unsigned char ProductID_TFT[] = { 80, 88, 51, 87 }; // "W3XP"
  131. unsigned char Version[] = { war3Version, 0, 0, 0 };
  132. unsigned char HostCounter[] = { 1, 0, 0, 0 };
  133. BYTEARRAY packet;
  134. packet.push_back( W3GS_HEADER_CONSTANT ); // W3GS header constant
  135. packet.push_back( W3GS_CREATEGAME ); // W3GS_CREATEGAME
  136. packet.push_back( 0 ); // packet length will be assigned later
  137. packet.push_back( 0 ); // packet length will be assigned later
  138. if( TFT )
  139. UTIL_AppendByteArray( packet, ProductID_TFT, 4 ); // Product ID (TFT)
  140. else
  141. UTIL_AppendByteArray( packet, ProductID_ROC, 4 ); // Product ID (ROC)
  142. UTIL_AppendByteArray( packet, Version, 4 ); // Version
  143. UTIL_AppendByteArray( packet, HostCounter, 4 ); // Host Counter
  144. AssignLength( packet );
  145. // DEBUG_Print( "SENT W3GS_CREATEGAME" );
  146. // DEBUG_Print( packet );
  147. return packet;
  148. }
  149. BYTEARRAY CGameProtocol :: SEND_W3GS_REFRESHGAME( uint32_t players, uint32_t playerSlots )
  150. {
  151. unsigned char HostCounter[] = { 1, 0, 0, 0 };
  152. BYTEARRAY packet;
  153. packet.push_back( W3GS_HEADER_CONSTANT ); // W3GS header constant
  154. packet.push_back( W3GS_REFRESHGAME ); // W3GS_REFRESHGAME
  155. packet.push_back( 0 ); // packet length will be assigned later
  156. packet.push_back( 0 ); // packet length will be assigned later
  157. UTIL_AppendByteArray( packet, HostCounter, 4 ); // Host Counter
  158. UTIL_AppendByteArray( packet, players, false ); // Players
  159. UTIL_AppendByteArray( packet, playerSlots, false ); // Player Slots
  160. AssignLength( packet );
  161. // DEBUG_Print( "SENT W3GS_REFRESHGAME" );
  162. // DEBUG_Print( packet );
  163. return packet;
  164. }
  165. BYTEARRAY CGameProtocol :: SEND_W3GS_DECREATEGAME( uint32_t hostCounter )
  166. {
  167. BYTEARRAY packet;
  168. packet.push_back( W3GS_HEADER_CONSTANT ); // W3GS header constant
  169. packet.push_back( W3GS_DECREATEGAME ); // W3GS_DECREATEGAME
  170. packet.push_back( 0 ); // packet length will be assigned later
  171. packet.push_back( 0 ); // packet length will be assigned later
  172. UTIL_AppendByteArray( packet, hostCounter, false ); // Host Counter
  173. AssignLength( packet );
  174. // DEBUG_Print( "SENT W3GS_DECREATEGAME" );
  175. // DEBUG_Print( packet );
  176. return packet;
  177. }
  178. /////////////////////
  179. // OTHER FUNCTIONS //
  180. /////////////////////
  181. bool CGameProtocol :: AssignLength( BYTEARRAY &content )
  182. {
  183. // insert the actual length of the content array into bytes 3 and 4 (indices 2 and 3)
  184. BYTEARRAY LengthBytes;
  185. if( content.size( ) >= 4 && content.size( ) <= 65535 )
  186. {
  187. LengthBytes = UTIL_CreateByteArray( (uint16_t)content.size( ), false );
  188. content[2] = LengthBytes[0];
  189. content[3] = LengthBytes[1];
  190. return true;
  191. }
  192. return false;
  193. }
  194. bool CGameProtocol :: ValidateLength( BYTEARRAY &content )
  195. {
  196. // verify that bytes 3 and 4 (indices 2 and 3) of the content array describe the length
  197. uint16_t Length;
  198. BYTEARRAY LengthBytes;
  199. if( content.size( ) >= 4 && content.size( ) <= 65535 )
  200. {
  201. LengthBytes.push_back( content[2] );
  202. LengthBytes.push_back( content[3] );
  203. Length = UTIL_ByteArrayToUInt16( LengthBytes, false );
  204. if( Length == content.size( ) )
  205. return true;
  206. }
  207. return false;
  208. }