Example #1
0
/// Only _static_ data is sent in this packet !!!
void WorldSession::HandleGameObjectQueryOpcode(WorldPacket& recvData)
{
    uint32 entry;
    recvData >> entry;
    uint64 guid;
    recvData >> guid;

    const GameObjectTemplate* info = sObjectMgr->GetGameObjectTemplate(entry);
    if (info)
    {
        std::string Name;
        std::string IconName;
        std::string CastBarCaption;

        Name = info->name;
        IconName = info->IconName;
        CastBarCaption = info->castBarCaption;

        int loc_idx = GetSessionDbLocaleIndex();
        if (loc_idx >= 0)
        {
            if (GameObjectLocale const* gl = sObjectMgr->GetGameObjectLocale(entry))
            {
                ObjectMgr::GetLocaleString(gl->Name, loc_idx, Name);
                ObjectMgr::GetLocaleString(gl->CastBarCaption, loc_idx, CastBarCaption);
            }
        }
        sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_GAMEOBJECT_QUERY '%s' - Entry: %u. ", info->name.c_str(), entry);
        WorldPacket data (SMSG_GAMEOBJECT_QUERY_RESPONSE, 150);
        data << uint32(entry);
        data << uint32(info->type);
        data << uint32(info->displayId);
        data << Name;
        data << uint8(0) << uint8(0) << uint8(0);           // name2, name3, name4
        data << IconName;                                   // 2.0.3, string. Icon name to use instead of default icon for go's (ex: "Attack" makes sword)
        data << CastBarCaption;                             // 2.0.3, string. Text will appear in Cast Bar when using GO (ex: "Collecting")
        data << info->unk1;                                 // 2.0.3, string
        data.append(info->raw.data, MAX_GAMEOBJECT_DATA);
        data << float(info->size);                          // go size
        for (uint32 i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; ++i)
            data << uint32(info->questItems[i]);              // itemId[6], quest drop
        SendPacket(&data);
        sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE");
    }
    else
    {
        sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_GAMEOBJECT_QUERY - Missing gameobject info for (GUID: %u, ENTRY: %u)",
            GUID_LOPART(guid), entry);
        WorldPacket data (SMSG_GAMEOBJECT_QUERY_RESPONSE, 4);
        data << uint32(entry | 0x80000000);
        SendPacket(&data);
        sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE");
    }
}
Example #2
0
bool AddonMgr::AppendPublicKey(WorldPacket & data, std::string & AddonName, uint32 CRC)
{
	if(CRC == 0x4C1C776D)
	{
		// Open public key file with that addon
		AddonDataItr itr = mAddonData.find(AddonName);

		if(itr != mAddonData.end())
			data.append(itr->second);
		else
		{
			// open the file
			char path[500];
			snprintf(path, 500, "addons\\%s.pub", AddonName.c_str());
			FILE* f = fopen(path, "rb");
			if(f != 0)
			{
				// read the file into a bytebuffer
				ByteBuffer buf;
				fseek(f, 0, SEEK_END);
				uint32 length = 264/*ftell(f)*/;
				fseek(f, 0, SEEK_SET);
				buf.resize(length);
				fread((void*)buf.contents(), length, 1, f);
				fclose(f);

				mAddonData[AddonName] = buf;
				data.append(buf);
			}
			else
			{
				ByteBuffer buf;
				buf.append(PublicKey, 264);
				mAddonData[AddonName] = buf;
				data.append(buf);
			}
		}
		return true;
	}
	return false;
}
Example #3
0
void WorldSession::SendGMTicketGetTicket(uint32 status, char const* text)
{
    int len = text ? strlen(text) : 0;
    WorldPacket data;
    data.Initialize( SMSG_GMTICKET_GETTICKET, (4+len+4) );
    data << uint32(6);
    if(len > 0)
        data.append((uint8 *)text,len+1);
    else
        data << uint32(0);
    SendPacket( &data );
}
/// Only _static_ data is sent in this packet !!!
void WorldSession::HandleGameObjectQueryOpcode(WorldPacket& recvData)
{
    uint32 entry;
    recvData >> entry;
    ObjectGuid guid;
    recvData >> guid;

    const GameObjectTemplate* info = sObjectMgr->GetGameObjectTemplate(entry);
    if (info)
    {
        std::string Name;
        std::string IconName;
        std::string CastBarCaption;

        Name = info->name;
        IconName = info->IconName;
        CastBarCaption = info->castBarCaption;

        LocaleConstant localeConstant = GetSessionDbLocaleIndex();
        if (localeConstant >= LOCALE_enUS)
            if (GameObjectLocale const* gameObjectLocale = sObjectMgr->GetGameObjectLocale(entry))
            {
                ObjectMgr::GetLocaleString(gameObjectLocale->Name, localeConstant, Name);
                ObjectMgr::GetLocaleString(gameObjectLocale->CastBarCaption, localeConstant, CastBarCaption);
            }

        TC_LOG_DEBUG("network", "WORLD: CMSG_GAMEOBJECT_QUERY '%s' - Entry: %u. ", info->name.c_str(), entry);
        WorldPacket data (SMSG_GAMEOBJECT_QUERY_RESPONSE, 150);
        data << uint32(entry);
        data << uint32(info->type);
        data << uint32(info->displayId);
        data << Name;
        data << uint8(0) << uint8(0) << uint8(0);           // name2, name3, name4
        data << IconName;                                   // 2.0.3, string. Icon name to use instead of default icon for go's (ex: "Attack" makes sword)
        data << CastBarCaption;                             // 2.0.3, string. Text will appear in Cast Bar when using GO (ex: "Collecting")
        data << info->unk1;                                 // 2.0.3, string
        data.append(info->raw.data, MAX_GAMEOBJECT_DATA);
        data << float(info->size);                          // go size

        data << int32(info->unkInt32);                      // 4.x, unknown
        SendPacket(&data);
        TC_LOG_DEBUG("network", "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE");
    }
    else
    {
        TC_LOG_DEBUG("network", "WORLD: CMSG_GAMEOBJECT_QUERY - Missing gameobject info for (%s, ENTRY: %u)",
            guid.ToString().c_str(), entry);
        WorldPacket data (SMSG_GAMEOBJECT_QUERY_RESPONSE, 4);
        data << uint32(entry | 0x80000000);
        SendPacket(&data);
        TC_LOG_DEBUG("network", "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE");
    }
}
Example #5
0
void WorldSession::HandleWhoOpcode( WorldPacket & recv_data )
{
    uint64 clientcount = 0;
    int datalen = 8;
    int countcheck = 0;
    WorldPacket data;

    Log::getSingleton( ).outDebug( "WORLD: Recvd CMSG_WHO Message" );
#ifndef ENABLE_GRID_SYSTEM
    ObjectMgr::PlayerMap::const_iterator itr;
    for (itr = objmgr.Begin<Player>(); itr != objmgr.End<Player>(); itr++)
#else
    ObjectAccessor::PlayerMapType &m(ObjectAccessor::Instance().GetPlayers());
    for(ObjectAccessor::PlayerMapType::iterator itr = m.begin(); itr != m.end(); ++itr)
#endif
    {
        if ( itr->second->GetName() )
        {
            clientcount++;

            datalen = datalen + strlen(itr->second->GetName()) + 1 + 21;
        }
    }

    data.Initialize( SMSG_WHO );
    data << uint64( clientcount );

#ifndef ENABLE_GRID_SYSTEM
    for (itr = objmgr.Begin<Player>(); itr != objmgr.End<Player>(); itr++)
#else
    for(ObjectAccessor::PlayerMapType::iterator itr = m.begin(); itr != m.end(); ++itr)
#endif
    {
        if ( itr->second->GetName() && (countcheck  < clientcount))
        {
            countcheck++;

            data.append(itr->second->GetName() , strlen(itr->second->GetName()) + 1);
            data << uint8( 0x00 );
            data << uint32( itr->second->getLevel() );
            data << uint32( itr->second->getClass() );
            data << uint32( itr->second->getRace() );
            data << uint32( itr->second->GetZoneId() );

            data << uint32( 0x00000000 );         // this is the guild id...once we have guilds working it'll go here.
        }
    }

    WPAssert(data.size() == datalen);
    SendPacket(&data);
}
Example #6
0
void WorldSession::HandlePetitionShowListOpcode( WorldPacket & recv_data )
{
    WorldPacket data;
    uint64 guid;
    unsigned char tdata[21] =
    {
        0x01, 0x01, 0x00, 0x00, 0x00, 0xe7, 0x16, 0x00, 0x00, 0xef, 0x23, 0x00, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00
    };
    recv_data >> guid;
    data.Initialize( SMSG_PETITION_SHOWLIST );
    data << guid;
    data.append( tdata, sizeof(tdata) );
    SendPacket( &data );
}
Example #7
0
            void operator()(WorldPacket& data, int32 loc_idx)
            {
                char const* nam = i_target ? i_target->GetNameForLocaleIdx(loc_idx) : NULL;
                uint32 namlen = (nam ? strlen(nam) : 0) + 1;

                data.Initialize(SMSG_TEXT_EMOTE, (20+namlen));
                data << i_player.GetGUID();
                data << (uint32)i_text_emote;
                data << i_emote_num;
                data << (uint32)namlen;
                if( namlen > 1 )
                    data.append(nam, namlen);
                else
                    data << (uint8)0x00;
            }
Example #8
0
            void operator()(WorldPacket& data, int32 loc_idx)
            {
                char const* nam = i_target ? i_target->GetNameForLocaleIdx(loc_idx) : NULL;
                uint32 namlen = (nam ? strlen(nam) : 0) + 1;

                data.Initialize(SMSG_TEXT_EMOTE, (20 + namlen));
                data << ObjectGuid(i_player.GetObjectGuid());
                data << uint32(i_text_emote);
                data << uint32(i_emote_num);
                data << uint32(namlen);
                if (namlen > 1)
                    data.append(nam, namlen);
                else
                    data << uint8(0x00);
            }
Example #9
0
/// Only _static_ data send in this packet !!!
void WorldSession::HandleGameObjectQueryOpcode( WorldPacket & recv_data )
{
    uint32 entryID;
    recv_data >> entryID;
    recv_data.read_skip<uint64>();                          // guid

    const GameObjectInfo *info = ObjectMgr::GetGameObjectInfo(entryID);
    if(info)
    {
        std::string Name = info->name;

        int loc_idx = GetSessionDbLocaleIndex();
        if (loc_idx >= 0)
        {
            GameObjectLocale const *gl = sObjectMgr.GetGameObjectLocale(entryID);
            if (gl)
            {
                if (gl->Name.size() > size_t(loc_idx) && !gl->Name[loc_idx].empty())
                    Name = gl->Name[loc_idx];
            }
        }
        sLog.outDetail("WORLD: CMSG_GAMEOBJECT_QUERY '%s' - Entry: %u. ", info->name, entryID);
        WorldPacket data ( SMSG_GAMEOBJECT_QUERY_RESPONSE, 150 );
        data << uint32(entryID);
        data << uint32(info->type);
        data << uint32(info->displayId);
        data << Name;
        data << uint16(0) << uint8(0) << uint8(0);           // name2, name3, name4
        data.append(info->raw.data, 24);
        //data << float(info->size);                          // go size , to check
        SendPacket( &data );
        sLog.outDebug( "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE" );
    }
    else
    {

        uint64 guid;
        recv_data >> guid;

        sLog.outDebug(  "WORLD: CMSG_GAMEOBJECT_QUERY - Missing gameobject info for (GUID: %u, ENTRY: %u)",
            GUID_LOPART(guid), entryID );
        WorldPacket data ( SMSG_GAMEOBJECT_QUERY_RESPONSE, 4 );
        data << uint32(entryID | 0x80000000);
        SendPacket( &data );
        sLog.outDebug( "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE" );
    }
}
Example #10
0
bool UpdateData::buildPacket(WorldPacket& packet, bool hasTransport)
{
	ByteBuffer buf(m_data.size() + 10 + m_guidList.size() * 8);

	buf << (u_int)(!m_guidList.empty() ? m_blockCount + 1 : m_blockCount);
	buf << (u_char)(hasTransport ? 1 : 0);

	if (!m_guidList.empty())
	{
		buf << (u_char)UPDATETYPE_OUT_OF_RANGE_OBJECTS;
		buf << (u_int)m_guidList.size();

		for (IDList::const_iterator itr = m_guidList.begin(); itr != m_guidList.end(); ++itr)
		{
			buf << (u_char)0xFF;
			buf << (u_int64)*itr;
		}
	}

	buf.append(m_data);

	packet.clear();

	// 大小超过50字节的数据包要压缩
	if (m_data.size() > 50)
	{
		u_int destSize = (u_int)buf.size() + buf.size() / 10 + 16;
		packet.resize(destSize);

		packet.put(0, (u_int)buf.size());

		compress(const_cast<u_char*>(packet.contents()) + sizeof(u_int), &destSize,
			(void*)buf.contents(), (u_int)buf.size());
		if (destSize == 0)
			return false;

		packet.resize(destSize + sizeof(u_int));
		packet.setOpcode(SMSG_COMPRESSED_UPDATE_OBJECT);
	}
	else
	{
		packet.append(buf);
		packet.setOpcode(SMSG_UPDATE_OBJECT);
	}

	return true;
}
Example #11
0
void BlackMarketMgr::BuildBlackMarketAuctionsPacket(WorldPacket& data, uint32 guidLow)
{
    uint32 count = 0;

    data << uint32(time(NULL));

    for (auto const &kvPair : m_bmAuctionsMap)
        if (kvPair.second->IsActive())
            ++count;

    data.WriteBits(count, 18);

    ByteBuffer datas;

    for (auto const &kvPair : m_bmAuctionsMap)
    {
        auto const auction = kvPair.second;
        if (!auction->IsActive())
            continue;

        // Is owner
        data.WriteBit(guidLow == auction->bidder);

        uint64 currentBid = auction->bidder ? auction->bid : 0;
        uint64 nextBidPrice = auction->bidder ? auction->bid + GetAuctionOutBid(auction->bid) : auction->bid;
        uint64 upPrice = auction->bidder ? nextBidPrice - currentBid : 1;

        datas << uint32(auction->bmTemplate->itemEntry);
        datas << uint32(auction->bmTemplate->seller);
        datas << uint32(auction->id);
        datas << uint32(auction->bidderCount);
        datas << uint32(auction->TimeLeft());
        datas << uint64(currentBid);
        datas << uint32(auction->bmTemplate->itemCount);
        datas << uint32(0);                                 // Unk
        datas << uint64(nextBidPrice);
        datas << uint64(upPrice);
    }

    data.FlushBits();

    if (datas.size())
        data.append(datas);

    TC_LOG_DEBUG("network", ">> Sent %u BlackMarket Auctions", count);
}
Example #12
0
void WorldSession::HandleGMTicketGetTicketOpcode( WorldPacket & recv_data )
{
    WorldPacket data;
    uint64 guid;
    std::stringstream query,query1;
    Field *fields;
    guid = GetPlayer()->GetGUID();
    query << "SELECT COUNT(*) FROM `gmtickets` where guid='" << guid << "'";
    QueryResult *result = sDatabase.Query( query.str().c_str() );

    if (result)
    {
        int cnt;
        fields = result->Fetch();
        cnt = fields[0].GetUInt32();

        if ( cnt > 0 )
        {
            data.Initialize( SMSG_GMTICKET_GETTICKET );
            query1 << "SELECT * FROM `gmtickets` where guid='" << guid << "'";
            QueryResult *result = sDatabase.Query( query1.str().c_str() );
            fields = result->Fetch();

            printf( "query=%s\n", query1.str().c_str() );
            char tickettext[255];
            strcpy( tickettext,fields[2].GetString() );
            data << uint32(6); // means we have open tickets
            data.append((uint8 *)tickettext,strlen(tickettext)+1);
            data << uint8(0); // ??
            data << uint8(3); // ??
            SendPacket( &data );
        }
        else
        {
            data << uint32(1); // all !6 means we have no open tickets
            data << uint32(0);
            data << uint8(0);
            data << uint8(0);
            SendPacket( &data );
        }

    }
    delete result;
}
void BlackMarketMgr::BuildBlackMarketAuctionsPacket(WorldPacket& data, uint32 guidLow)
{
    uint32 count = 0;
    ByteBuffer datas;

    data << uint32(time(NULL));

    for (BMAuctionEntryMap::const_iterator itr = GetAuctionsBegin(); itr != GetAuctionsEnd(); ++itr)
        if (itr->second->IsActive())
            ++count;

    data.WriteBits(count, 18);

    for (BMAuctionEntryMap::const_iterator itr = GetAuctionsBegin(); itr != GetAuctionsEnd(); ++itr)
    {
        BMAuctionEntry* auction = itr->second;

        if (!auction->IsActive())
            continue;

        data.WriteBit(guidLow == auction->bidder);          // Is owner

        uint64 currentBid = auction->bidder ? auction->bid : 0;
        uint64 nextBidPrice = auction->bidder ? auction->bid + GetAuctionOutBid(auction->bid) : auction->bid;
        uint64 upPrice = auction->bidder ? nextBidPrice - currentBid : 1;

        datas << uint32(auction->bm_template->itemEntry);
        datas << uint64(nextBidPrice);
        datas << uint64(currentBid);
        datas << uint32(0);                                 // Unk
        datas << uint32(auction->id);
        datas << uint32(auction->bm_template->seller);
        datas << uint64(upPrice);
        datas << uint32(auction->TimeLeft());
        datas << uint32(auction->bidderCount);
        datas << uint32(auction->bm_template->itemCount);
    }

    data.FlushBits();
    if (datas.size())
        data.append(datas);

    sLog->outInfo(LOG_FILTER_NETWORKIO, ">> Sent %u BlackMarket Auctions", count);
}
/// Only _static_ data send in this packet !!!
void WorldSession::HandleGameObjectQueryOpcode( WorldPacket & recv_data )
{
    uint32 entryID;
    recv_data >> entryID;
    ObjectGuid guid;
    recv_data >> guid;

    const GameObjectInfo *info = ObjectMgr::GetGameObjectInfo(entryID);
    if(info)
    {
        std::string Name = info->name;

        int loc_idx = GetSessionDbLocaleIndex();
        if (loc_idx >= 0)
        {
            GameObjectLocale const *gl = sObjectMgr.GetGameObjectLocale(entryID);
            if (gl)
            {
                if (gl->Name.size() > size_t(loc_idx) && !gl->Name[loc_idx].empty())
                    Name = gl->Name[loc_idx];
            }
        }
        DETAIL_LOG("WORLD: CMSG_GAMEOBJECT_QUERY '%s' - Entry: %u. ", info->name, entryID);
        WorldPacket data ( SMSG_GAMEOBJECT_QUERY_RESPONSE, 150 );
        data << uint32(entryID);
        data << uint32(info->type);
        data << uint32(info->displayId);
        data << Name;
        data << uint16(0) << uint8(0) << uint8(0);           // name2, name3, name4
        data.append(info->raw.data, 24);
        //data << float(info->size);                          // go size , to check
        SendPacket( &data );
        DEBUG_LOG( "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE" );
    }
    else
    {
        DEBUG_LOG("WORLD: CMSG_GAMEOBJECT_QUERY - Guid: %s Entry: %u Missing gameobject info!",
            guid.GetString().c_str(), entryID);
        WorldPacket data ( SMSG_GAMEOBJECT_QUERY_RESPONSE, 4 );
        data << uint32(entryID | 0x80000000);
        SendPacket( &data );
        DEBUG_LOG( "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE" );
    }
}
        void RemoveGravityLapse()
        {
            std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin();
            for (i = me->getThreatManager().getThreatList().begin(); i!= me->getThreatManager().getThreatList().end(); ++i)
            {
                Unit* unit = Unit::GetUnit((*me), (*i)->getUnitGuid());
                if (unit && (unit->GetTypeId() == TYPEID_PLAYER))
                {
                    unit->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_FLY);
                    unit->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_DOT);

                    WorldPacket data;
                    data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY);
                    data.append(unit->GetPackGUID());
                    data << uint32(0);
                    unit->SendMessageToSet(&data, true);
                }
            }
        }
 void CastGravityLapseFly()                              // Use Fly Packet hack for now as players can't cast "fly" spells unless in map 530. Has to be done a while after they get knocked into the air...
 {
     std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin();
     for (i = me->getThreatManager().getThreatList().begin(); i!= me->getThreatManager().getThreatList().end(); ++i)
     {
         Unit* unit = Unit::GetUnit((*me), (*i)->getUnitGuid());
         if (unit && (unit->GetTypeId() == TYPEID_PLAYER))
         {
             // Also needs an exception in spell system.
             unit->CastSpell(unit, SPELL_GRAVITY_LAPSE_FLY, true, 0, 0, me->GetGUID());
             // Use packet hack
             WorldPacket data;
             data.SetOpcode(SMSG_MOVE_SET_CAN_FLY);
             data.append(unit->GetPackGUID());
             data << uint32(0);
             unit->SendMessageToSet(&data, true);
         }
     }
 }
Example #17
0
void WorldSession::_HandleCompressedUpdateObjectOpcode(WorldPacket& recvPacket)
{
    uint32 realsize;
    recvPacket >> realsize;
    ZCompressor z;
    z.append(recvPacket.contents() + sizeof(uint32),recvPacket.size() - sizeof(uint32));
    z.Compressed(true);
    z.RealSize(realsize);
    z.Inflate();
    if(z.Compressed())
    {
        logerror("_HandleCompressedUpdateObjectOpcode(): Inflate() failed! size=%u realsize=%u",z.size(),realsize);
        return;
    }
    WorldPacket wp;
    wp.SetOpcode(recvPacket.GetOpcode());
    wp.append(z.contents(),z.size());

    _HandleUpdateObjectOpcode(wp);
}
Example #18
0
void WorldSocket::OutPacket(uint16 opcode, size_t len, const void* data)
{
    OUTPACKET_RESULT res;
    if( (len + 10) > WORLDSOCKET_SENDBUF_SIZE )
    {
        printf("WARNING: Tried to send a packet of %u bytes (which is too large) to a socket. Opcode was: %u (0x%03X)\n", (unsigned int)len, (unsigned int)opcode, (unsigned int)opcode);
        return;
    }

    res = _OutPacket(opcode, len, data);
    if(res == OUTPACKET_RESULT_SUCCESS)
        return;

    if(res == OUTPACKET_RESULT_NO_ROOM_IN_BUFFER)
    {
        /* queue the packet */
        queueLock.Acquire();
        WorldPacket * pck = new WorldPacket(opcode, len);
        if(len) pck->append((const uint8*)data, len);
        _queue.Push(pck);
        queueLock.Release();
    }
}
Example #19
0
void AddonMgr::SendAddonInfoPacket(WorldPacket* source, uint32 pos, WorldSession* m_session)
{
    WorldPacket returnpacket;
    returnpacket.Initialize(SMSG_ADDON_INFO);

    source->ResetRead();
    source->read_skip(52);

    uint32 addonSize;
    *source >> addonSize;

    uint32 realsize;
    uLongf rsize;

    //*source >> realsize;

    //rsize = realsize;
    rsize = addonSize;
    size_t position = source->rpos();

    ByteBuffer unpacked;
    unpacked.resize(rsize);

    int32 result;
    result = uncompress((uint8*)unpacked.contents(), &rsize, (uint8*)(*source).contents() + position, (uLong)((*source).size() - position));

    if (result != Z_OK)
    {
        sLog.outError("Decompression of addon section of CMSG_AUTH_SESSION failed.");
        return;
    }

    sLog.outDetail("Decompression of addon section of CMSG_AUTH_SESSION succeeded.");

    uint32 addoncount;
    unpacked >> addoncount;

    if (addoncount > 100)
        return; //have a hunch they are fucking with us

    uint8 Enable; // based on the parsed files from retool
    uint32 crc;
    uint32 unknown;
    bool have_new_addons = false;

    std::string name;
    for (uint32 i = 0; i< addoncount; ++i)
    {
        unpacked >> name;
        unpacked >> Enable;
        unpacked >> crc;
        unpacked >> unknown;

        // Hacky fix, Yea I know its a hacky fix I will make a proper handler one's I got the crc crap
        if (crc != 0x4C1C776D) // CRC of public key version 2.0.1
        {
            returnpacket.append(PublicKey, 264); // part of the hacky fix
            have_new_addons = true;
        }
        else
            returnpacket << uint8(0x02) << uint8(0x01) << uint8(0x00) << uint32(0) << uint8(0);

        if (unpacked.rpos() >= unpacked.wpos())
            break;
    }

    if (have_new_addons == false)
    {
        returnpacket << uint32(0);	//this is a counter !
    }

    m_session->SendPacket(&returnpacket);
}
Example #20
0
bool ChatHandler::HandleModifyMountCommand(const char* args)
{
    WorldPacket data;

    if(!*args)
        return false;

    uint16 mId = 1147;
    float speed = (float)15;
    uint32 num = 0;

    num = atoi((char*)args);
    switch(num)
    {
        case 1:
            mId=14340;
            break;
        case 2:
            mId=4806;
            break;
        case 3:
            mId=6471;
            break;
        case 4:
            mId=12345;
            break;
        case 5:
            mId=6472;
            break;
        case 6:
            mId=6473;
            break;
        case 7:
            mId=10670;
            break;
        case 8:
            mId=10719;
            break;
        case 9:
            mId=10671;
            break;
        case 10:
            mId=10672;
            break;
        case 11:
            mId=10720;
            break;
        case 12:
            mId=14349;
            break;
        case 13:
            mId=11641;
            break;
        case 14:
            mId=12244;
            break;
        case 15:
            mId=12242;
            break;
        case 16:
            mId=14578;
            break;
        case 17:
            mId=14579;
            break;
        case 18:
            mId=14349;
            break;
        case 19:
            mId=12245;
            break;
        case 20:
            mId=14335;
            break;
        case 21:
            mId=207;
            break;
        case 22:
            mId=2328;
            break;
        case 23:
            mId=2327;
            break;
        case 24:
            mId=2326;
            break;
        case 25:
            mId=14573;
            break;
        case 26:
            mId=14574;
            break;
        case 27:
            mId=14575;
            break;
        case 28:
            mId=604;
            break;
        case 29:
            mId=1166;
            break;
        case 30:
            mId=2402;
            break;
        case 31:
            mId=2410;
            break;
        case 32:
            mId=2409;
            break;
        case 33:
            mId=2408;
            break;
        case 34:
            mId=2405;
            break;
        case 35:
            mId=14337;
            break;
        case 36:
            mId=6569;
            break;
        case 37:
            mId=10661;
            break;
        case 38:
            mId=10666;
            break;
        case 39:
            mId=9473;
            break;
        case 40:
            mId=9476;
            break;
        case 41:
            mId=9474;
            break;
        case 42:
            mId=14374;
            break;
        case 43:
            mId=14376;
            break;
        case 44:
            mId=14377;
            break;
        case 45:
            mId=2404;
            break;
        case 46:
            mId=2784;
            break;
        case 47:
            mId=2787;
            break;
        case 48:
            mId=2785;
            break;
        case 49:
            mId=2736;
            break;
        case 50:
            mId=2786;
            break;
        case 51:
            mId=14347;
            break;
        case 52:
            mId=14346;
            break;
        case 53:
            mId=14576;
            break;
        case 54:
            mId=9695;
            break;
        case 55:
            mId=9991;
            break;
        case 56:
            mId=6448;
            break;
        case 57:
            mId=6444;
            break;
        case 58:
            mId=6080;
            break;
        case 59:
            mId=6447;
            break;
        case 60:
            mId=4805;
            break;
        case 61:
            mId=9714;
            break;
        case 62:
            mId=6448;
            break;
        case 63:
            mId=6442;
            break;
        case 64:
            mId=14632;
            break;
        case 65:
            mId=14332;
            break;
        case 66:
            mId=14331;
            break;
        case 67:
            mId=8469;
            break;
        case 68:
            mId=2830;
            break;
        case 69:
            mId=2346;
            break;
        default:
            SendSysMessage(LANG_NO_MOUNT);
            return true;
    }

    Player *chr = getSelectedPlayer();
    if (chr == NULL)
    {
        SendSysMessage(LANG_NO_CHAR_SELECTED);
        return true;
    }

    PSendSysMessage(LANG_YOU_GIVE_MOUNT, chr->GetName());

    char buf[256];
    sprintf((char*)buf,LANG_MOUNT_GIVED, m_session->GetPlayer()->GetName());
    FillSystemMessageData(&data, m_session, buf);

    chr->GetSession()->SendPacket(&data);

    chr->SetUInt32Value( UNIT_FIELD_FLAGS , 0x001000 );
    chr->Mount(mId);

    data.Initialize( SMSG_FORCE_RUN_SPEED_CHANGE, (8+4+4) );
    data.append(chr->GetPackGUID());
    data << (uint32)0;
    data << float(speed);
    chr->SendMessageToSet( &data, true );

    data.Initialize( SMSG_FORCE_SWIM_SPEED_CHANGE, (8+4+4) );
    data.append(chr->GetPackGUID());
    data << (uint32)0;
    data << float(speed);
    chr->SendMessageToSet( &data, true );

    return true;
}
/// Update the WorldSession (triggered by World update)
bool WorldSession::Update(uint32 diff, PacketFilter& updater)
{
    if (updater.ProcessLogout())
    {
        UpdateTimeOutTime(diff);
        if (IsConnectionIdle())
            m_Socket->CloseSocket();
    }

    HandleTeleportTimeout(updater.ProcessLogout());

    uint32 _startMSTime = getMSTime();
    WorldPacket* packet = NULL;
    WorldPacket* movementPacket = NULL;
    bool deletePacket = true;
    WorldPacket* firstDelayedPacket = NULL;
    uint32 processedPackets = 0;

    while (m_Socket && !m_Socket->IsClosed() && !_recvQueue.empty() && _recvQueue.peek(true) != firstDelayedPacket && _recvQueue.next(packet, updater))
    {
        if (packet->GetOpcode() < NUM_MSG_TYPES)
        {
            OpcodeHandler &opHandle = opcodeTable[packet->GetOpcode()];
            try
            {
                switch (opHandle.status)
                {
                    case STATUS_LOGGEDIN:
                        if (!_player)
                        {
                            // pussywizard: such packets were sent to do something for a character that has already logged out, skip them
                        }
                        else if (!_player->IsInWorld())
                        {
                            // pussywizard: such packets may do something important and the player is just being teleported, move to the end of the queue
                            // pussywizard: previously such were skipped, so leave it as it is xD proper code below if we wish to change that

                            // pussywizard: requeue only important packets not related to maps (PROCESS_THREADUNSAFE)
                            /*if (opHandle.packetProcessing == PROCESS_THREADUNSAFE)
                            {
                                if (!firstDelayedPacket)
                                    firstDelayedPacket = packet;
                                deletePacket = false;
                                QueuePacket(packet);
                            }*/
                        }
                        else
                        {
                            if (opHandle.isGrouppedMovementOpcode)
                            {
                                if (movementPacket)
                                    delete movementPacket;
                                movementPacket = new WorldPacket(packet->GetOpcode(), 0);
                                movementPacket->append(*((ByteBuffer*)packet));
                            }
                            else
                            {
                                if (movementPacket)
                                {
                                    HandleMovementOpcodes(*movementPacket);
                                    delete movementPacket;
                                    movementPacket = NULL;
                                }
                                sScriptMgr->OnPacketReceive(this, *packet);
#ifdef ELUNA
                                if (!sEluna->OnPacketReceive(this, *packet))
                                    break;
#endif
                                (this->*opHandle.handler)(*packet);
                            }
                        }
                        break;
                    case STATUS_TRANSFER:
                        if (_player && !_player->IsInWorld())
                        {
                            if (movementPacket)
                            {
                                delete movementPacket;
                                movementPacket = NULL;
                            }
                            sScriptMgr->OnPacketReceive(this, *packet);
#ifdef ELUNA
                            if (!sEluna->OnPacketReceive(this, *packet))
                                break;
#endif
                            (this->*opHandle.handler)(*packet);
                        }
                        break;
                    case STATUS_AUTHED:
                        if (m_inQueue) // prevent cheating
                            break;

                        sScriptMgr->OnPacketReceive(this, *packet);
#ifdef ELUNA
                        if (!sEluna->OnPacketReceive(this, *packet))
                            break;
#endif
                        (this->*opHandle.handler)(*packet);
                        break;
                    case STATUS_NEVER:
                        break;
                    case STATUS_UNHANDLED:
                        break;
                }
            }
            catch(ByteBufferException &)
            {
                sLog->outError("WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i. Skipped packet.", packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId());
                if (sLog->IsOutDebug())
                {
                    sLog->outDebug(LOG_FILTER_NETWORKIO, "Dumping error causing packet:");
                    packet->hexlike();
                }
            }
        }

        if (deletePacket)
            delete packet;
        else
            deletePacket = true;

        if (++processedPackets >= 150) // limit (by count) packets processed in one update, prevent DDoS
            break;

        if (getMSTimeDiff(_startMSTime, getMSTime()) >= 3) // limit (by time) packets processed in one update, prevent DDoS
            break;
    }

    if (movementPacket)
    {
        if (_player && _player->IsInWorld())
            HandleMovementOpcodes(*movementPacket);
        delete movementPacket;
    }

    if (m_Socket && !m_Socket->IsClosed())
        ProcessQueryCallbacks();

    if (updater.ProcessLogout())
    {
        time_t currTime = time(NULL);
        if (ShouldLogOut(currTime) && !m_playerLoading)
            LogoutPlayer(true);

        if (m_Socket && !m_Socket->IsClosed() && _warden)
            _warden->Update();

        if (m_Socket && m_Socket->IsClosed())
        {
            m_Socket->RemoveReference();
            m_Socket = NULL;
        }

        if (!m_Socket)
            return false;
    }

    return true;
}
Example #22
0
void WorldSession::HandleTextEmoteOpcode( WorldPacket & recv_data )
{
    WorldPacket data;
    uint32 text_emote, unk;
    uint64 guid;

    recv_data >> text_emote;
    recv_data >> unk;
    recv_data >> guid;

    const char *nam = 0;
    uint32 namlen = 1;

#ifndef ENABLE_GRID_SYSTEM
    Creature *pCreature = objmgr.GetObject<Creature>( guid );
    if(pCreature)
    {
        nam = pCreature->GetName();
        namlen = strlen( nam ) + 1;
    }
    else
    {
        Player *pChar = objmgr.GetObject<Player>( guid );
        if(pChar)
        {
            nam = pChar->GetName();
            namlen = strlen(nam) + 1;
        }
    }
#else
    // gets the name of either a unit or a player.. same thing
    Unit* unit = ObjectAccessor::Instance().GetUnit(*_player, guid);
    Creature *pCreature = dynamic_cast<Creature *>(unit);
    if( pCreature != NULL )
    {
        nam = pCreature->GetName();
        namlen = strlen(nam) + 1;
    }
    {
    Player *pChar = dynamic_cast<Player *>(unit);
    if( pChar != NULL )
    {
        nam = pChar->GetName();
        namlen = strlen(nam) + 1;
    }
    }
#endif

    emoteentry *em = sEmoteStore.LookupEntry(text_emote);
    if (em)                                       // server crashes with some emotes, that arent in dbc
    {
        uint32 emote_anim = em->textid;

        data.Initialize(SMSG_EMOTE);
        data << (uint32)emote_anim;
        data << GetPlayer()->GetGUID();
        WPAssert(data.size() == 12);
        sWorld.SendGlobalMessage(&data);

        data.Initialize(SMSG_TEXT_EMOTE);
        data << GetPlayer()->GetGUID();
        data << (uint32)text_emote;
        data << (uint32)0xFF;                     // dunno whats that- send by server when using emote w/o target
        data << (uint32)namlen;
        if( namlen > 1 )
        {
            data.append(nam, namlen);
        }
        else
        {
            data << (uint8)0x00;
        }

        WPAssert(data.size() == 20 + namlen);
        SendPacket( &data );
        sWorld.SendGlobalMessage(&data, this);
    }
}
Example #23
0
void WorldSession::HandleTextEmoteOpcode( WorldPacket & recv_data )
{
    CHECK_PACKET_SIZE(recv_data,4+4+8);

    uint32 text_emote, emoteNum;
    uint64 guid;

    recv_data >> text_emote;
    recv_data >> emoteNum;
    recv_data >> guid;

    const char *nam = 0;
    uint32 namlen = 1;

    Unit* unit = ObjectAccessor::Instance().GetUnit(*_player, guid);
    Creature *pCreature = dynamic_cast<Creature *>(unit);
    if( pCreature != NULL )
    {
        nam = pCreature->GetCreatureInfo()->Name;
        namlen = (nam ? strlen(nam) : 0) + 1;
    }
    {
        Player *pChar = dynamic_cast<Player *>(unit);
        if( pChar != NULL )
        {
            nam = pChar->GetName();
            namlen = (nam ? strlen(nam) : 0) + 1;
        }
    }

    EmotesTextEntry const *em = sEmotesTextStore.LookupEntry(text_emote);
    if (em)
    {
        uint32 emote_anim = em->textid;

        WorldPacket data;

        switch(emote_anim)
        {
            case EMOTE_STATE_SLEEP:
            case EMOTE_STATE_SIT:
            case EMOTE_STATE_KNEEL:
                break;
            default:
                data.Initialize(SMSG_EMOTE, 12);
                data << (uint32)emote_anim;
                data << GetPlayer()->GetGUID();
                WPAssert(data.size() == 12);
                GetPlayer()->SendMessageToSet( &data, true );
                break;
        }

        data.Initialize(SMSG_TEXT_EMOTE, (20+namlen));
        data << GetPlayer()->GetGUID();
        data << (uint32)text_emote;
        data << emoteNum;
        data << (uint32)namlen;
        if( namlen > 1 )
        {
            data.append(nam, namlen);
        }
        else
        {
            data << (uint8)0x00;
        }

        GetPlayer()->SendMessageToSet( &data, true );

        //Send scripted event call
        if (pCreature && Script)
            Script->ReceiveEmote(GetPlayer(),pCreature,emote_anim);
    }
}
Example #24
0
/// Only _static_ data send in this packet !!!
void WorldSession::HandleGameObjectQueryOpcode( WorldPacket & recv_data )
{
    CHECK_PACKET_SIZE(recv_data,4+8);

    uint32 entryID;
    recv_data >> entryID;

    const GameObjectInfo *info = objmgr.GetGameObjectInfo(entryID);
    if(info)
    {
        std::string Name;
        std::string IconName;
        std::string CastBarCaption;

        Name = info->name;
        IconName = info->IconName;
        CastBarCaption = info->castBarCaption;

        int loc_idx = GetSessionDbLocaleIndex();
        if (loc_idx >= 0)
        {
            GameObjectLocale const *gl = objmgr.GetGameObjectLocale(entryID);
            if (gl)
            {
                if (gl->Name.size() > size_t(loc_idx) && !gl->Name[loc_idx].empty())
                    Name = gl->Name[loc_idx];
                if (gl->CastBarCaption.size() > size_t(loc_idx) && !gl->CastBarCaption[loc_idx].empty())
                    CastBarCaption = gl->CastBarCaption[loc_idx];
            }
        }
        sLog.outDetail("WORLD: CMSG_GAMEOBJECT_QUERY '%s' - Entry: %u. ", info->name, entryID);
        WorldPacket data ( SMSG_GAMEOBJECT_QUERY_RESPONSE, 150 );
        data << uint32(entryID);
        data << uint32(info->type);
        data << uint32(info->displayId);
        data << Name;
        data << uint8(0) << uint8(0) << uint8(0);           // name2, name3, name4
        data << IconName;                                   // 2.0.3, string. Icon name to use instead of default icon for go's (ex: "Attack" makes sword)
        data << CastBarCaption;                             // 2.0.3, string. Text will appear in Cast Bar when using GO (ex: "Collecting")
        data << info->unk1;                                 // 2.0.3, string
        data.append(info->raw.data, 24);
        data << float(info->size);                          // go size
        for(uint32 i = 0; i < 4; ++i)
            data << uint32(info->questItems[i]);            // itemId[4], quest drop
        SendPacket( &data );
        sLog.outDebug( "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE" );
    }
    else
    {

        uint64 guid;
        recv_data >> guid;

        sLog.outDebug(  "WORLD: CMSG_GAMEOBJECT_QUERY - Missing gameobject info for (GUID: %u, ENTRY: %u)",
            GUID_LOPART(guid), entryID );
        WorldPacket data ( SMSG_GAMEOBJECT_QUERY_RESPONSE, 4 );
        data << uint32(entryID | 0x80000000);
        SendPacket( &data );
        sLog.outDebug( "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE" );
    }
}
void WorldSession::HandleGameObjectStatsOpcode(WorldPacket & recv_data)
{
    uint64 guid;
    uint32 entryID;

    recv_data >> entryID;
    recv_data >> guid;

    if (Chest == true)
    {
        entryID = Chestentry;
        guid = Chestguid;
        --guid;
        Chest = false;
    }

    const GameObjectTemplate *info = sObjectMgr->GetGameObjectTemplate(entryID);
    if (info)
    {
        std::string Name;
        std::string IconName;
        std::string CastBarCaption;

        Name = info->name;
        IconName = info->IconName;
        CastBarCaption = info->castBarCaption;

        int loc_idx = GetSessionDbLocaleIndex();
        if (loc_idx >= 0)
        {
            if (GameObjectLocale const *gl = sObjectMgr->GetGameObjectLocale(entryID))
            {
                sObjectMgr->GetLocaleString(gl->Name, loc_idx, Name);
                sObjectMgr->GetLocaleString(gl->CastBarCaption, loc_idx, CastBarCaption);
            }
        }
        sLog->outDetail("WORLD: CMSG_GAME_OBJECT_STATS '%s' - Entry: %u. ", info->name.c_str(), entryID);
        WorldPacket data (SMSG_GAME_OBJECT_STATS, 200);
        data << uint32(entryID);
        data << uint32(info->type);
        data << uint32(info->displayId);
        data << Name;
        data << uint8(0) << uint8(0) << uint8(0);           // name2, name3, name4
        data << IconName;                                   // 2.0.3, string. Icon name to use instead of default icon for go's (ex: "Attack" makes sword)
        data << CastBarCaption;                             // 2.0.3, string. Text will appear in Cast Bar when using GO (ex: "Collecting")
        data << info->unk1;                                 // 2.0.3, string
        data.append(info->raw.data, MAX_GAMEOBJECT_DATA);
        data << float(info->size);                          // go size
        for (uint32 i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; ++i)
            data << uint32(info->questItems[i]);            // itemId[6], quest drop
        data << uint32(info->unk2);                         // Found in 4.2.0, data from gameobjectcache.wdb
        SendPacket(&data);
        sLog->outDebug("WORLD: Sent SMSG_GAME_OBJECT_STATS");
    }
    else
    {
        sLog->outDebug("WORLD: CMSG_GAME_OBJECT_STATS - Missing gameobject stats for (GUID: %u, ENTRY: %u)", GUID_LOPART(guid), entryID);

        WorldPacket data (SMSG_GAME_OBJECT_STATS, 4);
        data << uint32(entryID | 0x80000000);
        SendPacket(&data);
        sLog->outDebug("WORLD: Sent SMSG_GAME_OBJECT_STATS");
    }
}
Example #26
0
void AddonMgr::SendAddonInfoPacket(WorldPacket *source, uint32 pos, WorldSession *m_session)
{
	WorldPacket returnpacket;
	returnpacket.Initialize(SMSG_ADDON_INFO);	// SMSG_ADDON_INFO

	uint32 realsize;
	uLongf rsize;
	try
	{
		*source >> realsize;
	}
	catch (ByteBuffer::error &)
	{
		DEBUG_LOG("AddonMgr","Warning, Incomplete auth session sent.");
		return;
	}	
	rsize = realsize;
	size_t position = source->rpos();

	ByteBuffer unpacked;
	unpacked.resize(realsize);

	if((source->size() - position) < 4 || realsize == 0)
	{
		// we shouldnt get here.. but just in case this will stop any crash here.
		DEBUG_LOG("AddonMgr","Warning, Incomplete auth session sent.");
		return;
	}
	int32 result;
	result = uncompress((uint8*)unpacked.contents(), &rsize, (uint8*)(*source).contents() + position, (uLong)((*source).size() - position));

	if(result != Z_OK)
	{
		DEBUG_LOG("AddonMgr","Decompression of addon section of CMSG_AUTH_SESSION failed.");
		return;
	}

	DEBUG_LOG("AddonMgr","Decompression of addon section of CMSG_AUTH_SESSION succeeded.");


	uint32 addons; // Added in 3.0.8
	uint8 Enable; // based on the parsed files from retool
	uint32 crc;
	uint32 unknown;

	unpacked >> addons;
	size_t p = unpacked.rpos(); 
	if( p + (addons*10) > unpacked.size() - p - 4) 
	{ 
		// stupid fucker, trying to make us waste CPU cycles 
		m_session->Disconnect(); 
		return; 
	}

	std::string name;
	for (uint32 i = 0; i < addons; ++i)
	{
		unpacked >> name;
		unpacked >> Enable;
		unpacked >> crc;
		unpacked >> unknown;

		// Hacky fix, Yea I know its a hacky fix I will make a proper handler one's I got the crc crap
		if (crc != 0x4C1C776D) // CRC of public key version 2.0.1
			returnpacket.append(PublicKey,264); // part of the hacky fix
		else
			returnpacket << uint8(0x02) << uint8(0x01) << uint8(0x00) << uint32(0) << uint8(0);
		/*if(!AppendPublicKey(returnpacket, name, crc))
		returnpacket << uint8(1) << uint8(0) << uint8(0);*/

	}

	uint32 unk308;

	unpacked >> unk308;
	m_session->SendPacket(&returnpacket);
}
Example #27
0
void WorldSession::HandleTextEmoteOpcode( WorldPacket & recv_data )
{
    if(!GetPlayer()->isAlive())
        return;

    if (!GetPlayer()->CanSpeak())
    {
        std::string timeStr = secsToTimeString(m_muteTime - time(NULL));
        SendNotification(GetMangosString(LANG_WAIT_BEFORE_SPEAKING),timeStr.c_str());
        return;
    }

    CHECK_PACKET_SIZE(recv_data,4+4+8);

    uint32 text_emote, emoteNum;
    uint64 guid;

    recv_data >> text_emote;
    recv_data >> emoteNum;
    recv_data >> guid;

    const char *nam = 0;
    uint32 namlen = 1;

    Unit* unit = ObjectAccessor::GetUnit(*_player, guid);
    Creature *pCreature = dynamic_cast<Creature *>(unit);
    if(unit)
    {
        nam = unit->GetName();
        namlen = (nam ? strlen(nam) : 0) + 1;
    }

    EmotesTextEntry const *em = sEmotesTextStore.LookupEntry(text_emote);
    if (em)
    {
        uint32 emote_anim = em->textid;

        WorldPacket data;

        switch(emote_anim)
        {
            case EMOTE_STATE_SLEEP:
            case EMOTE_STATE_SIT:
            case EMOTE_STATE_KNEEL:
            case EMOTE_ONESHOT_NONE:
                break;
            default:
                GetPlayer()->HandleEmoteCommand(emote_anim);
                break;
        }

        data.Initialize(SMSG_TEXT_EMOTE, (20+namlen));
        data << GetPlayer()->GetGUID();
        data << (uint32)text_emote;
        data << emoteNum;
        data << (uint32)namlen;
        if( namlen > 1 )
        {
            data.append(nam, namlen);
        }
        else
        {
            data << (uint8)0x00;
        }

        GetPlayer()->SendMessageToSetInRange(&data,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),true);

        //Send scripted event call
        if (pCreature && Script)
            Script->ReceiveEmote(GetPlayer(),pCreature,text_emote);
    }
}
Example #28
0
bool WorldSocket::ProcessIncomingData()
{
    ClientPktHeader header;

    if (m_useExistingHeader)
    {
        m_useExistingHeader = false;
        header = m_existingHeader;

        ReadSkip(sizeof(ClientPktHeader));
    }
    else
    {
        if (!Read((char *)&header, sizeof(ClientPktHeader)))
        {
            errno = EBADMSG;
            return false;
        }

        m_crypt.DecryptRecv((uint8 *)&header, sizeof(ClientPktHeader));

        EndianConvertReverse(header.size);
        EndianConvert(header.cmd);
    }

    // there must always be at least four bytes for the opcode,
    // and 0x2800 is the largest supported buffer in the client
    if ((header.size < 4) || (header.size > 0x2800) || (header.cmd >= NUM_MSG_TYPES))
    {
        sLog.outError("WorldSocket::ProcessIncomingData: client sent malformed packet size = %u , cmd = %u", header.size, header.cmd);

        errno = EINVAL;
        return false;
    }

    // the minus four is because we've already read the four byte opcode value
    const uint16 validBytesRemaining = header.size - 4;

    // check if the client has told us that there is more data than there is
    if (validBytesRemaining > ReadLengthRemaining())
    {
        // we must preserve the decrypted header so as not to corrupt the crypto state, and to prevent duplicating work
        m_useExistingHeader = true;
        m_existingHeader = header;

        // we move the read pointer backward because it will be skipped again later.  this is a slight kludge, but to solve
        // it more elegantly would require introducing protocol awareness into the socket library, which we want to avoid
        ReadSkip(-static_cast<int>(sizeof(ClientPktHeader)));

        errno = EBADMSG;
        return false;
    }

    const Opcodes opcode = static_cast<Opcodes>(header.cmd);

    if (IsClosed())
        return false;

    // Dump received packet.
    //sLog.outWorldPacketDump(uint32(get_handle()), new_pct->GetOpcode(), new_pct->GetOpcodeName(), new_pct, true);

    WorldPacket *pct = new WorldPacket(opcode, validBytesRemaining);

    if (validBytesRemaining)
    {
        pct->append(InPeak(), validBytesRemaining);
        ReadSkip(validBytesRemaining);
    }

    try
    {
        switch (opcode)
        {
        case CMSG_AUTH_SESSION:
            if (m_session)
            {
                sLog.outError("WorldSocket::ProcessIncomingData: Player send CMSG_AUTH_SESSION again");
                return false;
            }

            return HandleAuthSession(*pct);

        case CMSG_PING:
            return HandlePing(*pct);

        case CMSG_KEEP_ALIVE:
            DEBUG_LOG("CMSG_KEEP_ALIVE ,size: " SIZEFMTD " ", pct->size());

            return true;

        default:
        {
            if (!m_session)
            {
                sLog.outError("WorldSocket::ProcessIncomingData: Client not authed opcode = %u", uint32(opcode));
                return false;
            }

            m_session->QueuePacket(pct);

            return true;
        }
        }
    }
    catch (ByteBufferException&)
    {
        sLog.outError("WorldSocket::ProcessIncomingData ByteBufferException occured while parsing an instant handled packet (opcode: %u) from client %s, accountid=%i.",
                      opcode, GetRemoteAddress().c_str(), m_session ? m_session->GetAccountId() : -1);

        if (sLog.HasLogLevelOrHigher(LOG_LVL_DEBUG))
        {
            DEBUG_LOG("Dumping error-causing packet:");
            pct->hexlike();
        }

        if (sWorld.getConfig(CONFIG_BOOL_KICK_PLAYER_ON_BAD_PACKET))
        {
            DETAIL_LOG("Disconnecting session [account id %i / address %s] for badly formatted packet.",
                       m_session ? m_session->GetAccountId() : -1, GetRemoteAddress().c_str());

            return false;
        }
    }

    return true;
}
Example #29
0
void AddonMgr::SendAddonInfoPacket(WorldPacket *source, uint32 pos, WorldSession *m_session)
{
	WorldPacket returnpacket;
	returnpacket.Initialize(SMSG_ADDON_INFO);	// SMSG_ADDON_INFO

	uint32 realsize;
	uLongf rsize;
	try
	{
		*source >> realsize;
	}
	catch (ByteBuffer::error &)
	{
		OUT_DEBUG("Warning: Incomplete auth session sent.");
		return;
	}	
	rsize = realsize;
	size_t position = source->rpos();

	ByteBuffer unpacked;
	unpacked.resize(realsize);

	if((source->size() - position) < 4 || realsize == 0)
	{
		// we shouldnt get here.. but just in case this will stop any crash here.
		OUT_DEBUG("Warning: Incomplete auth session sent.");
		return;
	}
	int32 result;
	result = uncompress((uint8*)unpacked.contents(), &rsize, (uint8*)(*source).contents() + position, (uLong)((*source).size() - position));

	if(result != Z_OK)
	{
		OUT_DEBUG("Decompression of addon section of CMSG_AUTH_SESSION failed.");
		return;
	}

	OUT_DEBUG("Decompression of addon section of CMSG_AUTH_SESSION succeeded.");
	
	uint32 addons;
	uint8 Enable; // based on the parsed files from retool
	uint32 crc;
	uint32 unknown;

	unpacked >> addons;

	size_t p = unpacked.rpos(); 
	if( p + (addons*10) > unpacked.size() - p - 4) 
	{ 
		// stupid fucker, trying to make us waste CPU cycles 
		m_session->Disconnect(); 
		return; 
	}


	std::string name;
	//size_t p = unpacked.rpos();
	{
		uint8 unk;
		uint8 unk1;
		uint8 unk2;
		uint32 unk3;
		for(uint32 i = 0; i < addons; ++i)
		{
			unpacked >> name;
			unpacked >> Enable;
			unpacked >> crc;
			unpacked >> unknown;

			unk = (Enable ? 2 : 1);
			returnpacket << unk;
			unk1 = (Enable ? 1 : 0);
			returnpacket << unk1;
			if (unk1)
			{
				if(crc != 0x4C1C776D)
				{
					returnpacket << uint8(1);
					returnpacket.append(PublicKey,264);
				}
				else
					returnpacket << uint8(0);

				returnpacket << uint32(0);
			}

			unk2 = (Enable ? 0 : 1);
			returnpacket << unk2;
			if (unk2)
				returnpacket << uint8(0);

			//p = unpacked.rpos();
		}

		unpacked >> unk3; //Added in 3.0.8
	}
	m_session->SendPacket(&returnpacket);

}
Example #30
0
void AddonMgr::SendAddonInfoPacket(WorldPacket* source, uint32 pos, WorldSession* m_session)
{
	WorldPacket returnpacket;
	returnpacket.Initialize(SMSG_ADDON_INFO);	// SMSG_ADDON_INFO

	uint32 realsize;
	uLongf rsize;

	try
	{
		*source >> realsize;
	}
	catch(ByteBuffer::error &)
	{
		LOG_DEBUG("Warning: Incomplete auth session sent.");
		return;
	}

	rsize = realsize;
	size_t position = source->rpos();

	ByteBuffer unpacked;
	unpacked.resize(realsize);

	if((source->size() - position) < 4 || realsize == 0)
	{
		// we shouldn't get here.. but just in case this will stop any crash here.
		LOG_DEBUG("Warning: Incomplete auth session sent.");
		return;
	}

	int32 result = uncompress((uint8*)unpacked.contents(), &rsize, (uint8*)(*source).contents() + position, (uLong)((*source).size() - position));

	if(result != Z_OK)
	{
		LOG_ERROR("Decompression of addon section of CMSG_AUTH_SESSION failed.");
		return;
	}

	LOG_DETAIL("Decompression of addon section of CMSG_AUTH_SESSION succeeded.");

	uint8 Enable; // based on the parsed files from retool
	uint32 crc;
	uint32 unknown;

	std::string name;

	uint32 addoncount;
	unpacked >> addoncount;

	uint8 unk;
	uint8 unk1;
	uint8 unk2;
	for(uint32 i = 0; i < addoncount; ++i)
	{
		if(unpacked.rpos() >= unpacked.size())
			break;

		unpacked >> name;
		unpacked >> Enable;
		unpacked >> crc;
		unpacked >> unknown;

		// Hacky fix, Yea I know its a hacky fix I will make a proper handler one's I got the crc crap
		/*		if (crc != 0x4C1C776D) // CRC of public key version 2.0.1
					returnpacket.append(PublicKey,264); // part of the hacky fix
				else
					returnpacket << uint8(0x02) << uint8(0x01) << uint8(0x00) << uint32(0) << uint8(0);*/
		/*if(!AppendPublicKey(returnpacket, name, crc))
			returnpacket << uint8(1) << uint8(0) << uint8(0);*/

		unk = (Enable ? 2 : 1);
		returnpacket << unk;
		unk1 = (Enable ? 1 : 0);
		returnpacket << unk1;
		if(unk1)
		{
			if(crc != 0x4C1C776D)
			{
				returnpacket << uint8(1);
				returnpacket.append(PublicKey, 264);
			}
			else
				returnpacket << uint8(0);

			returnpacket << uint32(0);
		}

		unk2 = (Enable ? 0 : 1);
		returnpacket << unk2;
		if(unk2)
			returnpacket << uint8(0);
	}

	/*unknown 4 bytes at the end of the packet. Stays 0 for me. Tried custom addons, deleting, faulty etc. It stays 0.
	*/
	returnpacket << uint32(0); //Some additional count for additional records, but we won't send them.

	m_session->SendPacket(&returnpacket);
}