void PacketBuilder::WriteStopMovement(Vector3 const& pos, uint32 splineId, ByteBuffer& data, Unit* unit)
    {

        ObjectGuid guid = unit->GetGUID();
        ObjectGuid transport = unit->GetTransGUID();

        data << float(pos.z);
        data << float(pos.x);
        data << uint32(splineId);
        data << float(pos.y);
        data << float(0.f); // Most likely transport Y
        data << float(0.f); // Most likely transport Z
        data << float(0.f); // Most likely transport X

        data.WriteBit(1); // Parabolic speed // esi+4Ch
        data.WriteBit(guid[0]);
        data.WriteBits(MonsterMoveStop, 3);
        data.WriteBit(1);
        data.WriteBit(1);
        data.WriteBit(1);
        data.WriteBits(0,  20);
        data.WriteBit(1);
        data.WriteBit(guid[3]);
        data.WriteBit(1);
        data.WriteBit(1);
        data.WriteBit(1);
        data.WriteBit(1);
        data.WriteGuidMask(guid, 7, 4);
        data.WriteBit(1);
        data.WriteBit(guid[5]);
        data.WriteBits(0, 22); // WP count
        data.WriteBit(guid[6]);
        data.WriteBit(0); // Fake bit
        data.WriteGuidMask(transport, 7, 1, 3, 0, 6, 4, 5, 2);
        data.WriteBit(0); // Send no block
        data.WriteBit(0);
        data.WriteGuidMask(guid, 2, 1);

        data.FlushBits();

        data.WriteByteSeq(guid[1]);
        data.WriteGuidBytes(transport, 6, 4, 1, 7, 0, 3, 5, 2);
        data.WriteGuidBytes(guid, 5, 3, 6, 0, 7, 2, 4);
    }
    void PacketBuilder::WriteFacingTargetPart(MoveSpline const& moveSpline, ByteBuffer& data)
    {
        if (GetMonsterMoveType(moveSpline) == MonsterMoveFacingTarget && !moveSpline.Finalized())
        {
            ObjectGuid facingGuid = moveSpline.facing.target;
            data.WriteGuidMask(facingGuid, 4, 7, 0, 5, 1, 2, 3, 6);

            data.WriteGuidBytes(facingGuid, 4, 2, 0, 5, 6, 3, 1, 7);
        }
    }
    void PacketBuilder::WriteCreateData(MoveSpline const& moveSpline, ByteBuffer& data)
    {
        MoveSplineFlag splineFlags = moveSpline.splineflags;

        if ((splineFlags & MoveSplineFlag::Parabolic) && moveSpline.effect_start_time < moveSpline.Duration())
            data << moveSpline.vertical_acceleration;   // added in 3.1

        data << moveSpline.timePassed();

        if (splineFlags.final_angle)
            data << moveSpline.facing.angle;
        else if (splineFlags.final_target)
        {
            uint8 guidBytes[] = { 5, 3, 7, 1, 6, 5, 2, 0 };
            data.WriteGuidBytes(moveSpline.facing.target, guidBytes, 8, 0);
        }

        uint32 nodes = moveSpline.getPath().size();
        for (uint32 i = 0; i < nodes; ++i)
        {
            data << float(moveSpline.getPath()[i].z);
            data << float(moveSpline.getPath()[i].x);
            data << float(moveSpline.getPath()[i].y);
        }

        if (splineFlags.final_point)
            data << moveSpline.facing.f.x << moveSpline.facing.f.z << moveSpline.facing.f.y;

        data << float(1.f);                             // splineInfo.duration_mod_next; added in 3.1
        data << moveSpline.Duration();
        if (splineFlags & (MoveSplineFlag::Parabolic | MoveSplineFlag::Animation))
            data << moveSpline.effect_start_time;       // added in 3.1

        data << float(1.f);                             // splineInfo.duration_mod; added in 3.1

        if (!moveSpline.isCyclic())
        {
            Vector3 dest = moveSpline.FinalDestination();
            data << float(dest.z);
            data << float(dest.x);
            data << float(dest.y);
        }
        else
            data << Vector3::zero();

        data << moveSpline.GetId();
    }
    void PacketBuilder::WriteData(const MoveSpline& move_spline, ByteBuffer& data)
    {
        MoveSplineFlag splineFlags = move_spline.splineflags;
        uint32 nodes = move_spline.getPath().size();

        data << move_spline.timePassed();

        if (splineFlags.orientationFixed)
            data << move_spline.facing.angle;

        if (splineFlags.final_target)
        {
            uint64 Guid = move_spline.facing.target;

            uint8 guidBytes[] = { 5, 3, 7, 1, 6, 4, 2, 0 };
            data.WriteGuidBytes(Guid, guidBytes, 8, 0);
        }

        for (uint32 i = 0; i < nodes; i++)
        {
            data << move_spline.getPath()[0].z;
            data << move_spline.getPath()[0].x;
            data << move_spline.getPath()[0].y;
        }

        if(splineFlags.flying)
            data << move_spline.facing.f.x << move_spline.facing.f.z << move_spline.facing.f.y;

        data << float(1.f);
        data << uint32(0);

        data << move_spline.effect_start_time;

        data << float(1.f);

        data << move_spline.FinalDestination().z;
        data << move_spline.FinalDestination().x;
        data << move_spline.FinalDestination().y;
        data << move_spline.GetId();
    }
Exemple #5
0
//called when player lists his received mails
void WorldSession::HandleGetMailList(WorldPacket& recvData)
{
    ObjectGuid mailbox;

    recvData.ReadGuidMask(mailbox, 6, 3, 7, 5, 4, 1, 2, 0);

    recvData.ReadGuidBytes(mailbox, 7, 1, 6, 5, 4, 2, 3, 0);

    if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
        return;

    Player* player = _player;

    //load players mails, and mailed items
    if (!player->m_mailsLoaded)
        player->_LoadMail();

    // client can't work with packets > max int16 value
    const uint32 maxPacketSize = 32767;

    uint32 mailCount = 0;
    uint32 realCount = 0;                               // true mail count (includes any skipped mail)
    time_t cur_time = time(NULL);
    ByteBuffer mailData;

    WorldPacket data(SMSG_MAIL_LIST_RESULT, 200);       // guess size
    data << uint32(0);                                  // placeholder

    size_t mailCountPos = data.bitwpos();
    data.WriteBits(0, 18);                              // placeholder

    for (PlayerMails::iterator itr = player->GetMailBegin(); itr != player->GetMailEnd(); ++itr)
    {
        Mail* mail = *itr;

        // Only first 50 mails are displayed
        if (mailCount >= 50)
        {
            realCount += 1;
            continue;
        }

        // skip deleted or not delivered (deliver delay not expired) mails
        if (mail->state == MAIL_STATE_DELETED || cur_time < mail->deliver_time)
            continue;

        // skip mail with more than MAX_MAIL_ITEMS items (should not occur)
        uint8 itemCount = mail->items.size();
        if (itemCount > MAX_MAIL_ITEMS)
        {
            realCount += 1;
            continue;
        }

        // skip mail if the packet has become too large (should not occur)
        size_t nextMailSize = 6 + 1 + 8 + itemCount * (4 + 4 + 4 + 4 + 4 + MAX_INSPECTED_ENCHANTMENT_SLOT * (4 + 4 + 4) +
                              4 + 4 + 4 + 4 + 1 + 4) + mail->body.size() + mail->subject.size() + 4 + 4 + 8 + 4 + 8 + 4 + 4 + 1 + 4;

        if (data.wpos() + nextMailSize > maxPacketSize)
        {
            realCount += 1;
            continue;
        }

        data.WriteBit(mail->messageType != MAIL_NORMAL ? 1 : 0);
        data.WriteBits(mail->subject.size(), 8);
        data.WriteBits(mail->body.size(), 13);
        data.WriteBit(0);
        data.WriteBit(0);

        size_t itemCountPos = data.bitwpos();
        data.WriteBits(0, 17);                          // placeholder

        data.WriteBit(1);                               // has guid

        ObjectGuid guid = mail->messageType == MAIL_NORMAL ? MAKE_NEW_GUID(mail->sender, 0, HIGHGUID_PLAYER) : 0;
        data.WriteGuidMask(guid, 2, 6, 7, 0, 5, 3, 1, 4);

        uint8 trueItemCount = 0;
        for (uint8 i = 0; i < itemCount; i++)
        {
            Item* item = player->GetMItem(mail->items[i].item_guid);
            if (!item)
                continue;

            data.WriteBit(0);

            mailData << uint32(item->GetGUIDLow());
            mailData << uint32(4);                      // unknown
            mailData << uint32(item->GetSpellCharges());
            mailData << uint32(item->GetUInt32Value(ITEM_FIELD_DURABILITY));
            mailData << uint32(0);                      // unknown

            for (uint8 j = 0; j < MAX_INSPECTED_ENCHANTMENT_SLOT; j++)
            {
                mailData << uint32(item->GetEnchantmentCharges((EnchantmentSlot)j));
                mailData << uint32(item->GetEnchantmentDuration((EnchantmentSlot)j));
                mailData << uint32(item->GetEnchantmentId((EnchantmentSlot)j));
            }

            mailData << uint32(item->GetItemSuffixFactor());
            mailData << int32(item->GetItemRandomPropertyId());
            mailData << uint32(item->GetUInt32Value(ITEM_FIELD_MAX_DURABILITY));
            mailData << uint32(item->GetCount());
            mailData << uint8(i);
            mailData << uint32(item->GetEntry());

            trueItemCount++;
        }

        data.PutBits(itemCountPos, trueItemCount, 17);

        mailData.WriteString(mail->body);
        mailData << uint32(mail->messageID);
        mailData.WriteGuidBytes(guid, 4, 0, 5, 3, 1, 7, 2, 6);
        mailData << uint32(mail->mailTemplateId);
        mailData << uint64(mail->COD);
        mailData.WriteString(mail->subject);
        mailData << uint32(mail->stationery);
        mailData << float(float(mail->expire_time - time(NULL)) / DAY);
        mailData << uint64(mail->money);
        mailData << uint32(mail->checked);

        if (mail->messageType != MAIL_NORMAL)
            mailData << uint32(mail->sender);

        mailData << uint8(mail->messageType);
        mailData << uint32(0);                          // unknown

        realCount++;
        mailCount++;
    }

    data.FlushBits();
    data.append(mailData);

    data.put<uint32>(0, realCount);
    data.PutBits(mailCountPos, mailCount, 18);

    SendPacket(&data);

    // recalculate m_nextMailDelivereTime and unReadMails
    _player->UpdateNextMailTimeAndUnreads();
}