bool CBNETProtocol :: RECEIVE_SID_AUTH_INFO( BYTEARRAY data ) { // DEBUG_Print( "RECEIVED SID_AUTH_INFO" ); // DEBUG_Print( data ); // 2 bytes -> Header // 2 bytes -> Length // 4 bytes -> LogonType // 4 bytes -> ServerToken // 4 bytes -> ??? // 8 bytes -> MPQFileTime // null terminated string -> IX86VerFileName // null terminated string -> ValueStringFormula if( ValidateLength( data ) && data.size( ) >= 25 ) { m_LogonType = BYTEARRAY( data.begin( ) + 4, data.begin( ) + 8 ); m_ServerToken = BYTEARRAY( data.begin( ) + 8, data.begin( ) + 12 ); m_MPQFileTime = BYTEARRAY( data.begin( ) + 16, data.begin( ) + 24 ); m_IX86VerFileName = UTIL_ExtractCString( data, 24 ); m_ValueStringFormula = UTIL_ExtractCString( data, m_IX86VerFileName.size( ) + 25 ); return true; } return false; }
CIncomingClanList *CBNETProtocol :: RECEIVE_SID_CLANMEMBERSTATUSCHANGE( BYTEARRAY data ) { // DEBUG_Print( "RECEIVED SID_CLANMEMBERSTATUSCHANGE" ); // DEBUG_Print( data ); // 2 bytes -> Header // 2 bytes -> Length // null terminated string -> Name // 1 byte -> Rank // 1 byte -> Status // null terminated string -> Location if( ValidateLength( data ) && data.size( ) >= 5 ) { BYTEARRAY Name = UTIL_ExtractCString( data, 4 ); if( data.size( ) >= Name.size( ) + 7 ) { unsigned char Rank = data[Name.size( ) + 5]; unsigned char Status = data[Name.size( ) + 6]; // in the original VB source the location string is read but discarded, so that's what I do here BYTEARRAY Location = UTIL_ExtractCString( data, Name.size( ) + 7 ); return new CIncomingClanList( string( Name.begin( ), Name.end( ) ), Rank, Status ); } } return NULL; }
vector<CIncomingClanList *> CBNETProtocol :: RECEIVE_SID_CLANMEMBERLIST( BYTEARRAY data ) { // DEBUG_Print( "RECEIVED SID_CLANMEMBERLIST" ); // DEBUG_Print( data ); // 2 bytes -> Header // 2 bytes -> Length // 4 bytes -> ??? // 1 byte -> Total // for( 1 .. Total ) // null term string -> Name // 1 byte -> Rank // 1 byte -> Status // null term string -> Location vector<CIncomingClanList *> ClanList; if( ValidateLength( data ) && data.size( ) >= 9 ) { unsigned int i = 9; unsigned char Total = data[8]; while( Total > 0 ) { Total--; if( data.size( ) < i + 1 ) break; BYTEARRAY Name = UTIL_ExtractCString( data, i ); i += Name.size( ) + 1; if( data.size( ) < i + 3 ) break; unsigned char Rank = data[i]; unsigned char Status = data[i + 1]; i += 2; // in the original VB source the location string is read but discarded, so that's what I do here BYTEARRAY Location = UTIL_ExtractCString( data, i ); i += Location.size( ) + 1; ClanList.push_back( new CIncomingClanList( string( Name.begin( ), Name.end( ) ), Rank, Status ) ); } } return ClanList; }
CIncomingChatEvent *CBNETProtocol :: RECEIVE_SID_CHATEVENT( BYTEARRAY data ) { // DEBUG_Print( "RECEIVED SID_CHATEVENT" ); // DEBUG_Print( data ); // 2 bytes -> Header // 2 bytes -> Length // 4 bytes -> EventID // 4 bytes -> UserFlags // 4 bytes -> Ping // 12 bytes -> ??? // null terminated string -> User // null terminated string -> Message if( ValidateLength( data ) && data.size( ) >= 29 ) { BYTEARRAY EventID = BYTEARRAY( data.begin( ) + 4, data.begin( ) + 8 ); BYTEARRAY UserFlags = BYTEARRAY( data.begin( ) + 8, data.begin( ) + 12 ); BYTEARRAY Ping = BYTEARRAY( data.begin( ) + 12, data.begin( ) + 16 ); BYTEARRAY User = UTIL_ExtractCString( data, 28 ); BYTEARRAY Message = UTIL_ExtractCString( data, User.size( ) + 29 ); switch( UTIL_ByteArrayToUInt32( EventID, false ) ) { case CBNETProtocol :: EID_SHOWUSER: case CBNETProtocol :: EID_JOIN: case CBNETProtocol :: EID_LEAVE: case CBNETProtocol :: EID_WHISPER: case CBNETProtocol :: EID_TALK: case CBNETProtocol :: EID_BROADCAST: case CBNETProtocol :: EID_CHANNEL: case CBNETProtocol :: EID_USERFLAGS: case CBNETProtocol :: EID_WHISPERSENT: case CBNETProtocol :: EID_CHANNELFULL: case CBNETProtocol :: EID_CHANNELDOESNOTEXIST: case CBNETProtocol :: EID_CHANNELRESTRICTED: case CBNETProtocol :: EID_INFO: case CBNETProtocol :: EID_ERROR: case CBNETProtocol :: EID_EMOTE: return new CIncomingChatEvent( (CBNETProtocol :: IncomingChatEvent)UTIL_ByteArrayToUInt32( EventID, false ), UTIL_ByteArrayToUInt32( UserFlags, false ), UTIL_ByteArrayToUInt32( Ping, false ), string( User.begin( ), User.end( ) ), string( Message.begin( ), Message.end( ) ) ); } } return NULL; }
string CBNETProtocol :: RECEIVE_SID_CLANINVITATIONRESPONSE( BYTEARRAY data ) { if( ValidateLength( data ) && data.size( ) >= 12 ) { //skip four bytes cookie m_ClanLastInviteTag = BYTEARRAY( data.begin( ) + 8, data.begin( ) + 12 ); BYTEARRAY ClanName = UTIL_ExtractCString( data, 12 ); m_ClanLastInviteName = UTIL_ExtractCString( data, 12 + ClanName.size( ) ); return string( m_ClanLastInviteName.begin( ), m_ClanLastInviteName.end( ) ); } return NULL; }
vector<CIncomingFriendList *> CBNETProtocol :: RECEIVE_SID_FRIENDSLIST( BYTEARRAY data ) { // DEBUG_Print( "RECEIVED SID_FRIENDSLIST" ); // DEBUG_Print( data ); // 2 bytes -> Header // 2 bytes -> Length // 1 byte -> Total // for( 1 .. Total ) // null term string -> Account // 1 byte -> Status // 1 byte -> Area // 4 bytes -> ??? // null term string -> Location vector<CIncomingFriendList *> Friends; if( ValidateLength( data ) && data.size( ) >= 5 ) { unsigned int i = 5; unsigned char Total = data[4]; while( Total > 0 ) { Total--; if( data.size( ) < i + 1 ) break; BYTEARRAY Account = UTIL_ExtractCString( data, i ); i += Account.size( ) + 1; if( data.size( ) < i + 7 ) break; unsigned char Status = data[i]; unsigned char Area = data[i + 1]; i += 6; BYTEARRAY Location = UTIL_ExtractCString( data, i ); i += Location.size( ) + 1; Friends.push_back( new CIncomingFriendList( string( Account.begin( ), Account.end( ) ), Status, Area, string( Location.begin( ), Location.end( ) ) ) ); } } return Friends; }
CIncomingJoinPlayer *CGameProtocol :: RECEIVE_W3GS_REQJOIN( BYTEARRAY data ) { // DEBUG_Print( "RECEIVED W3GS_REQJOIN" ); // DEBUG_Print( data ); // 2 bytes -> Header // 2 bytes -> Length // 4 bytes -> Host Counter (Game ID) // 4 bytes -> Entry Key (used in LAN) // 1 byte -> ??? // 2 bytes -> Listen Port // 4 bytes -> Peer Key // null terminated string -> Name // 4 bytes -> ??? // 2 bytes -> InternalPort (???) // 4 bytes -> InternalIP if( ValidateLength( data ) && data.size( ) >= 20 ) { uint32_t HostCounter = UTIL_ByteArrayToUInt32( data, false, 4 ); BYTEARRAY Name = UTIL_ExtractCString( data, 19 ); if( !Name.empty( ) && data.size( ) >= Name.size( ) + 30 ) { BYTEARRAY InternalIP = BYTEARRAY( data.begin( ) + Name.size( ) + 26, data.begin( ) + Name.size( ) + 30 ); return new CIncomingJoinPlayer( HostCounter, string( Name.begin( ), Name.end( ) ), InternalIP ); } } return NULL; }
bool CBNETProtocol :: RECEIVE_SID_ENTERCHAT( BYTEARRAY data ) { // DEBUG_Print( "RECEIVED SID_ENTERCHAT" ); // DEBUG_Print( data ); // 2 bytes -> Header // 2 bytes -> Length // null terminated string -> UniqueName if( ValidateLength( data ) && data.size( ) >= 5 ) { m_UniqueName = UTIL_ExtractCString( data, 4 ); return true; } return false; }
CIncomingGameHost *CBNETProtocol :: RECEIVE_SID_GETADVLISTEX( BYTEARRAY data ) { // DEBUG_Print( "RECEIVED SID_GETADVLISTEX" ); // DEBUG_Print( data ); // 2 bytes -> Header // 2 bytes -> Length // 4 bytes -> GamesFound // if( GamesFound > 0 ) // 10 bytes -> ??? // 2 bytes -> Port // 4 bytes -> IP // null term string -> GameName // 2 bytes -> ??? // 8 bytes -> HostCounter if( ValidateLength( data ) && data.size( ) >= 8 ) { BYTEARRAY GamesFound = BYTEARRAY( data.begin( ) + 4, data.begin( ) + 8 ); if( UTIL_ByteArrayToUInt32( GamesFound, false ) > 0 && data.size( ) >= 25 ) { BYTEARRAY Port = BYTEARRAY( data.begin( ) + 18, data.begin( ) + 20 ); BYTEARRAY IP = BYTEARRAY( data.begin( ) + 20, data.begin( ) + 24 ); BYTEARRAY GameName = UTIL_ExtractCString( data, 24 ); if( data.size( ) >= GameName.size( ) + 35 ) { BYTEARRAY HostCounter; HostCounter.push_back( UTIL_ExtractHex( data, GameName.size( ) + 27, true ) ); HostCounter.push_back( UTIL_ExtractHex( data, GameName.size( ) + 29, true ) ); HostCounter.push_back( UTIL_ExtractHex( data, GameName.size( ) + 31, true ) ); HostCounter.push_back( UTIL_ExtractHex( data, GameName.size( ) + 33, true ) ); return new CIncomingGameHost( IP, UTIL_ByteArrayToUInt16( Port, false ), string( GameName.begin( ), GameName.end( ) ), HostCounter ); } } } return NULL; }
bool CBNETProtocol :: RECEIVE_SID_AUTH_CHECK( BYTEARRAY data ) { // DEBUG_Print( "RECEIVED SID_AUTH_CHECK" ); // DEBUG_Print( data ); // 2 bytes -> Header // 2 bytes -> Length // 4 bytes -> KeyState // null terminated string -> KeyStateDescription if( ValidateLength( data ) && data.size( ) >= 9 ) { m_KeyState = BYTEARRAY( data.begin( ) + 4, data.begin( ) + 8 ); m_KeyStateDescription = UTIL_ExtractCString( data, 8 ); if( UTIL_ByteArrayToUInt32( m_KeyState, false ) == KR_GOOD ) return true; } return false; }
CIncomingChatPlayer *CGameProtocol :: RECEIVE_W3GS_CHAT_TO_HOST( BYTEARRAY data ) { // DEBUG_Print( "RECEIVED W3GS_CHAT_TO_HOST" ); // DEBUG_Print( data ); // 2 bytes -> Header // 2 bytes -> Length // 1 byte -> Total // for( 1 .. Total ) // 1 byte -> ToPID // 1 byte -> FromPID // 1 byte -> Flag // if( Flag == 16 ) // null term string -> Message // elseif( Flag == 17 ) // 1 byte -> Team // elseif( Flag == 18 ) // 1 byte -> Colour // elseif( Flag == 19 ) // 1 byte -> Race // elseif( Flag == 20 ) // 1 byte -> Handicap // elseif( Flag == 32 ) // 4 bytes -> ExtraFlags // null term string -> Message if( ValidateLength( data ) ) { unsigned int i = 5; unsigned char Total = data[4]; if( Total > 0 && data.size( ) >= i + Total ) { BYTEARRAY ToPIDs = BYTEARRAY( data.begin( ) + i, data.begin( ) + i + Total ); i += Total; unsigned char FromPID = data[i]; unsigned char Flag = data[i + 1]; i += 2; if( Flag == 16 && data.size( ) >= i + 1 ) { // chat message BYTEARRAY Message = UTIL_ExtractCString( data, i ); return new CIncomingChatPlayer( FromPID, ToPIDs, Flag, string( Message.begin( ), Message.end( ) ) ); } else if( ( Flag >= 17 && Flag <= 20 ) && data.size( ) >= i + 1 ) { // team/colour/race/handicap change request unsigned char Byte = data[i]; return new CIncomingChatPlayer( FromPID, ToPIDs, Flag, Byte ); } else if( Flag == 32 && data.size( ) >= i + 5 ) { // chat message with extra flags BYTEARRAY ExtraFlags = BYTEARRAY( data.begin( ) + i, data.begin( ) + i + 4 ); BYTEARRAY Message = UTIL_ExtractCString( data, i + 4 ); return new CIncomingChatPlayer( FromPID, ToPIDs, Flag, string( Message.begin( ), Message.end( ) ), ExtraFlags ); } } } return NULL; }
CIncomingGameHost *CBNETProtocol :: RECEIVE_SID_GETADVLISTEX( BYTEARRAY data ) { // DEBUG_Print( "RECEIVED SID_GETADVLISTEX" ); // DEBUG_Print( data ); // 2 bytes -> Header // 2 bytes -> Length // 4 bytes -> GamesFound // if( GamesFound > 0 ) // 10 bytes -> ??? // 2 bytes -> Port // 4 bytes -> IP // null term string -> GameName // 2 bytes -> ??? // 8 bytes -> HostCounter if( ValidateLength( data ) && data.size( ) >= 8 ) { BYTEARRAY GamesFound = BYTEARRAY( data.begin( ) + 4, data.begin( ) + 8 ); /* if (UTIL_ByteArrayToUInt32( GamesFound, false )>1) { string sIP =""; string GN =""; uint32_t PR; uint32_t GF = UTIL_ByteArrayToUInt32( GamesFound, false ); uint32_t Idx = 18; uint32_t Idx2 = 0; for (uint32_t i=0;i<GF;i++) { BYTEARRAY Port = BYTEARRAY( data.begin( ) + Idx, data.begin( ) + 2+Idx ); BYTEARRAY IP = BYTEARRAY( data.begin( ) + 2+Idx, data.begin( ) + 6+Idx ); BYTEARRAY GameName = UTIL_ExtractCString( data, 6+Idx ); Idx2 = GameName.size( ); Idx = Idx + Idx2+ 11; GN = string( GameName.begin( ), GameName.end( ) ); PR = UTIL_ByteArrayToUInt16( Port, false ); CONSOLE_Print("[GHOST] Game "+UTIL_ToString(i)+ " "+ GN + " "+sIP+" "+UTIL_ToString(PR)); } } else */ if( UTIL_ByteArrayToUInt32( GamesFound, false ) > 0 && data.size( ) >= 25 ) { BYTEARRAY Port = BYTEARRAY( data.begin( ) + 18, data.begin( ) + 20 ); BYTEARRAY IP = BYTEARRAY( data.begin( ) + 20, data.begin( ) + 24 ); BYTEARRAY GameName = UTIL_ExtractCString( data, 24 ); if( data.size( ) >= GameName.size( ) + 35 ) { BYTEARRAY HostCounter; HostCounter.push_back( UTIL_ExtractHex( data, GameName.size( ) + 27, true ) ); HostCounter.push_back( UTIL_ExtractHex( data, GameName.size( ) + 29, true ) ); HostCounter.push_back( UTIL_ExtractHex( data, GameName.size( ) + 31, true ) ); HostCounter.push_back( UTIL_ExtractHex( data, GameName.size( ) + 33, true ) ); return new CIncomingGameHost( IP, UTIL_ByteArrayToUInt16( Port, false ), string( GameName.begin( ), GameName.end( ) ), HostCounter ); } } } return NULL; }