PageRenderTime 43ms CodeModel.GetById 13ms app.highlight 25ms RepoModel.GetById 1ms app.codeStats 1ms

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