void PacketBuilder::WriteMonsterMove(const MoveSpline& moveSpline, WorldPacket& data, Unit* unit)
    {
        ObjectGuid guid = unit->GetGUID();
        ObjectGuid transport = unit->GetTransGUID();
        MonsterMoveType type = GetMonsterMoveType(moveSpline);
        G3D::Vector3 const& firstPoint = moveSpline.spline.getPoint(moveSpline.spline.first());

        data << float(firstPoint.z);
        data << float(firstPoint.x);
        data << uint32(moveSpline.GetId());
        data << float(firstPoint.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(type, 3);

        if (type == MonsterMoveFacingTarget)
        {
            ObjectGuid targetGuid = moveSpline.facing.target;
            data.WriteBit(targetGuid[6]);
            data.WriteBit(targetGuid[4]);
            data.WriteBit(targetGuid[3]);
            data.WriteBit(targetGuid[0]);
            data.WriteBit(targetGuid[5]);
            data.WriteBit(targetGuid[7]);
            data.WriteBit(targetGuid[1]);
            data.WriteBit(targetGuid[2]);
        }

        data.WriteBit(1);
        data.WriteBit(1);
        data.WriteBit(1);

        uint32 uncompressedSplineCount = moveSpline.splineflags & MoveSplineFlag::UncompressedPath ? moveSpline.splineflags.cyclic ? moveSpline.spline.getPointCount() - 3 : moveSpline.spline.getPointCount() - 2 : 1;
        data.WriteBits(uncompressedSplineCount,  20);

        data.WriteBit(!moveSpline.splineflags.raw());
        data.WriteBit(guid[3]);
        data.WriteBit(1);
        data.WriteBit(1);
        data.WriteBit(1);
        data.WriteBit(!moveSpline.Duration());
        data.WriteBit(guid[7]);
        data.WriteBit(guid[4]);
        data.WriteBit(1);
        data.WriteBit(guid[5]);

        int32 compressedSplineCount = moveSpline.splineflags & MoveSplineFlag::UncompressedPath ? 0 : moveSpline.spline.getPointCount() - 3;
        data.WriteBits(compressedSplineCount, 22); // WP count

        data.WriteBit(guid[6]);
        data.WriteBit(0); // Fake bit

        data.WriteBit(transport[7]);
        data.WriteBit(transport[1]);
        data.WriteBit(transport[3]);
        data.WriteBit(transport[0]);
        data.WriteBit(transport[6]);
        data.WriteBit(transport[4]);
        data.WriteBit(transport[5]);
        data.WriteBit(transport[2]);

        data.WriteBit(0); // Send no block
        data.WriteBit(0);
        data.WriteBit(guid[2]);
        data.WriteBit(guid[1]);

        data.FlushBits();

        if (compressedSplineCount)
            WriteLinearPath(moveSpline.spline, data);

        data.WriteByteSeq(guid[1]);
        data.WriteByteSeq(transport[6]);
        data.WriteByteSeq(transport[4]);
        data.WriteByteSeq(transport[1]);
        data.WriteByteSeq(transport[7]);
        data.WriteByteSeq(transport[0]);
        data.WriteByteSeq(transport[3]);
        data.WriteByteSeq(transport[5]);
        data.WriteByteSeq(transport[2]);

        if (moveSpline.splineflags & MoveSplineFlag::UncompressedPath)
        {
            if (moveSpline.splineflags.cyclic)
                WriteUncompressedCyclicPath(moveSpline.spline, data);
            else
                WriteUncompressedPath(moveSpline.spline, data);
        }
        else
        {
            G3D::Vector3 const& point = moveSpline.spline.getPoint(moveSpline.spline.getPointCount() - 2);
            data << point.y << point.x << point.z;
        }

        if (type == MonsterMoveFacingTarget)
        {
            ObjectGuid targetGuid = moveSpline.facing.target;
            data.WriteByteSeq(targetGuid[5]);
            data.WriteByteSeq(targetGuid[7]);
            data.WriteByteSeq(targetGuid[0]);
            data.WriteByteSeq(targetGuid[4]);
            data.WriteByteSeq(targetGuid[3]);
            data.WriteByteSeq(targetGuid[2]);
            data.WriteByteSeq(targetGuid[6]);
            data.WriteByteSeq(targetGuid[1]);
        }

        data.WriteByteSeq(guid[5]);

        if (type == MonsterMoveFacingAngle)
            data << float(moveSpline.facing.angle);

        data.WriteByteSeq(guid[3]);

        if (moveSpline.splineflags.raw())
            data << uint32(moveSpline.splineflags.raw());

        data.WriteByteSeq(guid[6]);

        if (type == MonsterMoveFacingPoint)
            data << moveSpline.facing.f.x << moveSpline.facing.f.y << moveSpline.facing.f.z;

        data.WriteByteSeq(guid[0]);
        data.WriteByteSeq(guid[7]);
        data.WriteByteSeq(guid[2]);
        data.WriteByteSeq(guid[4]);

        if (moveSpline.Duration())
            data << uint32(moveSpline.Duration());
    }
	void PacketBuilder::WriteMonsterMove(const MoveSpline& move_spline, WorldPacket& data)
	{
		ObjectGuid moverGuid;
		ObjectGuid transportGuid;
		MoveSplineFlag splineflags = move_spline.splineflags;
		G3D::Vector3 const& firstPoint = move_spline.spline.getPoint(move_spline.spline.first());

		uint8 splineType = 0;

		switch (splineflags & MoveSplineFlag::Mask_Final_Facing)
		{
		case MoveSplineFlag::Final_Target:
			splineType = MonsterMoveFacingTarget;
			break;
		case MoveSplineFlag::Final_Angle:
			splineType = MonsterMoveFacingAngle;
			break;
		case MoveSplineFlag::Final_Point:
			splineType = MonsterMoveFacingSpot;
			break;
		default:
			splineType = MonsterMoveNormal;
			break;
		}

		data << float(firstPoint.z);
		data << float(firstPoint.x);
		data << uint32(move_spline.GetId());
		data << float(firstPoint.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 21
		data.WriteBit(moverGuid[0]); // 32
		data.WriteBits(splineType, 3); // 68

		if (splineType == MonsterMoveFacingTarget)
		{
			ObjectGuid targetGuid = move_spline.facing.target;

			data.WriteBit(targetGuid[6]); // 190
			data.WriteBit(targetGuid[4]); // 188
			data.WriteBit(targetGuid[3]); // 187
			data.WriteBit(targetGuid[0]); // 184
			data.WriteBit(targetGuid[5]); // 189
			data.WriteBit(targetGuid[7]); // 191
			data.WriteBit(targetGuid[1]); // 185
			data.WriteBit(targetGuid[2]); // 186
		}

		data.WriteBit(1); // 19
		data.WriteBit(1); // 69
		data.WriteBit(1); // 120

		uint32 uncompressedSplineCount = move_spline.splineflags & MoveSplineFlag::UncompressedPath ? move_spline.splineflags.cyclic ? move_spline.spline.getPointCount() - 2 : move_spline.spline.getPointCount() - 3 : 1;
		data.WriteBits(uncompressedSplineCount, 20);

		data.WriteBit(!move_spline.splineflags.raw()); // 16
		data.WriteBit(moverGuid[3]); // 35
		data.WriteBit(1); // 108
		data.WriteBit(1); // 22
		data.WriteBit(1); // 109

		data.WriteBit(!move_spline.Duration()); // 20
		data.WriteBit(moverGuid[7]); // 39
		data.WriteBit(moverGuid[4]); // 36
		data.WriteBit(1); // 18
		data.WriteBit(moverGuid[5]); // 37

		int32 compressedSplineCount = move_spline.splineflags & MoveSplineFlag::UncompressedPath ? 0 : move_spline.spline.getPointCount() - 3;
		data.WriteBits(compressedSplineCount, 22); // WP count

		data.WriteBit(moverGuid[6]); // 38

		data.WriteBit(0); // unk

		data.WriteBit(transportGuid[7]); // 119
		data.WriteBit(transportGuid[1]); // 113
		data.WriteBit(transportGuid[3]); // 115
		data.WriteBit(transportGuid[0]); // 112
		data.WriteBit(transportGuid[6]); // 118
		data.WriteBit(transportGuid[4]); // 116
		data.WriteBit(transportGuid[5]); // 117
		data.WriteBit(transportGuid[2]); // 114

		data.WriteBit(0); // 176 unk
		data.WriteBit(0); // 56 unk

		data.WriteBit(moverGuid[2]); // 34
		data.WriteBit(moverGuid[1]); // 33

		data.FlushBits();

		if (compressedSplineCount)
			WriteLinearPath(move_spline.spline, data);

		data.WriteByteSeq(moverGuid[1]);

		data.WriteByteSeq(transportGuid[6]); // 118
		data.WriteByteSeq(transportGuid[4]); // 116
		data.WriteByteSeq(transportGuid[1]); // 113
		data.WriteByteSeq(transportGuid[7]); // 119
		data.WriteByteSeq(transportGuid[0]); // 112
		data.WriteByteSeq(transportGuid[3]); // 115
		data.WriteByteSeq(transportGuid[5]); // 117
		data.WriteByteSeq(transportGuid[2]); // 114

		if (splineflags & MoveSplineFlag::UncompressedPath)
		{
			if (splineflags.cyclic)
				WriteCatmullRomCyclicPath(move_spline.spline, data);
			else
				WriteCatmullRomPath(move_spline.spline, data);
		}
		else
		{
			G3D::Vector3 const& point = move_spline.spline.getPoint(move_spline.spline.getPointCount() - 2);
			data << point.y << point.x << point.z;
		}
		
		if (splineType == MonsterMoveFacingTarget)
		{
			ObjectGuid targetGuid = move_spline.facing.target;

			data.WriteByteSeq(targetGuid[5]); // 189
			data.WriteByteSeq(targetGuid[7]); // 191
			data.WriteByteSeq(targetGuid[0]); // 184
			data.WriteByteSeq(targetGuid[4]); // 188
			data.WriteByteSeq(targetGuid[3]); // 187
			data.WriteByteSeq(targetGuid[2]); // 186
			data.WriteByteSeq(targetGuid[6]); // 190
			data.WriteByteSeq(targetGuid[1]); // 185
		}

		data.WriteByteSeq(moverGuid[5]); // 37

		if (splineType == MonsterMoveFacingAngle)
			data << float(move_spline.facing.angle); // 45

		data.WriteByteSeq(moverGuid[3]); // 35

		data.WriteBit(0);                // 16

		if (move_spline.splineflags.raw())
			data << uint32(move_spline.splineflags.raw()); // 69

		data.WriteByteSeq(moverGuid[6]); // 38

		if (splineType == MonsterMoveFacingSpot)
			data << move_spline.facing.f.x << move_spline.facing.f.y << move_spline.facing.f.z;

		data.WriteByteSeq(moverGuid[0]); // 32
		data.WriteByteSeq(moverGuid[7]); // 39
		data.WriteByteSeq(moverGuid[2]); // 34
		data.WriteByteSeq(moverGuid[4]); // 36

		if (move_spline.Duration())
			data << uint32(move_spline.Duration());
    }
    void PacketBuilder::WriteMonsterMove(const MoveSpline& move_spline, WorldPacket& data, Unit* unit)
    {
        ObjectGuid guid = unit->GetGUID();
        ObjectGuid transport = unit->GetTransGUID();
        uint32 type;

        data << float(0.f); // Most likely transport Y
        data << uint32(getMSTime());
        data << float(0.f); // Most likely transport Z
        data << float(0.f); // Most likely transport X

        if (!move_spline.isCyclic())
        {
            Vector3 dest = move_spline.FinalDestination();
            data << float(dest.x);
            data << float(dest.y);
            data << float(dest.z);
        }
        else
            data << Vector3::zero();
        
        data.WriteBit(guid[3]);
        data.WriteBit(!move_spline.splineflags.raw());
        data.WriteBit(guid[6]);

        data.WriteBit(1);
        data.WriteBit(1);

        switch (move_spline.splineflags & MoveSplineFlag::Mask_Final_Facing)
        {
            case MoveSplineFlag::Final_Target:
                type = 3;
                break;
            case MoveSplineFlag::Final_Angle:
                type = 4;
                break;
            case MoveSplineFlag::Final_Point:
                type = 2;
                break;
            default:
                type = 0;
                break;
        }

        data.WriteBits(type, 3);
        data.WriteBit(1);
        data.WriteBit(guid[2]);
        data.WriteBit(guid[7]);
        data.WriteBit(guid[5]);

        if (type == 3)
        {
            ObjectGuid targetGuid = move_spline.facing.target;
            data.WriteBit(targetGuid[6]);
            data.WriteBit(targetGuid[7]);
            data.WriteBit(targetGuid[0]);
            data.WriteBit(targetGuid[5]);
            data.WriteBit(targetGuid[2]);
            data.WriteBit(targetGuid[3]);
            data.WriteBit(targetGuid[4]);
            data.WriteBit(targetGuid[1]);
        }

        data.WriteBit(1);
        data.WriteBit(guid[4]);
        
        int32 splineWpCount = move_spline.splineflags & MoveSplineFlag::UncompressedPath ? 0 : move_spline.spline.getPointCount() - 3;
        //int32 splineWpCount = move_spline.splineflags & MoveSplineFlag::UncompressedPath ? 1 : move_spline.spline.getPointCount() - 3;
        data.WriteBits(splineWpCount, 22); // WP count
        data.WriteBit(1);
        data.WriteBit(0);

        data.WriteBit(guid[0]);
        data.WriteBit(transport[3]);
        data.WriteBit(transport[6]);
        data.WriteBit(transport[5]);
        data.WriteBit(transport[0]);
        data.WriteBit(transport[1]);
        data.WriteBit(transport[2]);
        data.WriteBit(transport[4]);
        data.WriteBit(transport[7]);

        data.WriteBit(1);
        data.WriteBit(1); // Parabolic speed // esi+4Ch
        data.WriteBit(1);

        //data.WriteBits(!splineWpCount ? move_spline.spline.getPointCount() - 2 : 1, 20);
        data.WriteBits(!splineWpCount ? move_spline.spline.getPointCount() - (move_spline.splineflags.cyclic ? 2 : 3) : 1, 20);

        data.WriteBit(guid[1]);
        data.WriteBit(0); // Send no block
        data.WriteBit(0);
        data.WriteBit(!move_spline.Duration());

        data.FlushBits();

        if (type == 3)
        {
            ObjectGuid targetGuid = move_spline.facing.target;
            data.WriteByteSeq(targetGuid[5]);
            data.WriteByteSeq(targetGuid[3]);
            data.WriteByteSeq(targetGuid[6]);
            data.WriteByteSeq(targetGuid[1]);
            data.WriteByteSeq(targetGuid[4]);
            data.WriteByteSeq(targetGuid[2]);
            data.WriteByteSeq(targetGuid[0]);
            data.WriteByteSeq(targetGuid[7]);
        }

        data.WriteByteSeq(guid[3]);
        data.WriteByteSeq(transport[7]);
        data.WriteByteSeq(transport[3]);
        data.WriteByteSeq(transport[2]);
        data.WriteByteSeq(transport[0]);
        data.WriteByteSeq(transport[6]);
        data.WriteByteSeq(transport[4]);
        data.WriteByteSeq(transport[5]);
        data.WriteByteSeq(transport[1]);

        if (type == 4)
            data << float(move_spline.facing.angle);

        if (move_spline.splineflags.raw())
            data << uint32(move_spline.splineflags.raw());

        data.WriteByteSeq(guid[7]);

        if (!(move_spline.splineflags & MoveSplineFlag::UncompressedPath))
            WriteLinearPath(move_spline.spline, data);

        data.WriteByteSeq(guid[5]);
        data.WriteByteSeq(guid[1]);
        data.WriteByteSeq(guid[2]);

        if (move_spline.splineflags & MoveSplineFlag::UncompressedPath)
        {
            if (move_spline.splineflags.cyclic)
                WriteUncompressedCyclicPath(move_spline.spline, data);
            else
                WriteUncompressedPath(move_spline.spline, data);
        }
        else
        {
            uint32 last_idx = move_spline.spline.getPointCount() - 2;
            const Vector3 * real_path = &move_spline.spline.getPoint(1);
            data << real_path[last_idx].x << real_path[last_idx].y << real_path[last_idx].z; // destination
        }

        data.WriteByteSeq(guid[6]);

        if (move_spline.Duration())
            data << uint32(move_spline.Duration());

        if (type == 2)
            data << move_spline.facing.f.x << move_spline.facing.f.y << move_spline.facing.f.z;

        data.WriteByteSeq(guid[0]);
        data.WriteByteSeq(guid[4]);

    }
示例#4
0
size_t ChatHandler::BuildChatPacket(WorldPacket& data, ChatMsg chatType, Language language, ObjectGuid senderGUID, ObjectGuid receiverGUID, std::string const& message, uint8 chatTag,
                                  std::string const& senderName /*= ""*/, std::string const& receiverName /*= ""*/,
                                  uint32 achievementId /*= 0*/, bool gmMessage /*= false*/, std::string const& channelName /*= ""*/,
                                  std::string const& addonPrefix /*= ""*/)
{
    bool hasAchievementId = (chatType == CHAT_MSG_ACHIEVEMENT || chatType == CHAT_MSG_GUILD_ACHIEVEMENT) && achievementId;
    bool hasSenderName = false;
    bool hasReceiverName = false;
    bool hasChannelName = false;
    bool hasGroupGUID = false;
    bool hasGuildGUID = false;
    bool hasPrefix = false;

    switch (chatType)
    {
        case CHAT_MSG_BATTLEGROUND:
        case CHAT_MSG_BATTLEGROUND_LEADER:
        case CHAT_MSG_PARTY:
        case CHAT_MSG_PARTY_LEADER:
        case CHAT_MSG_RAID:
        case CHAT_MSG_RAID_LEADER:
        case CHAT_MSG_RAID_WARNING:
            hasGroupGUID = true;
            break;
        case CHAT_MSG_GUILD:
        case CHAT_MSG_OFFICER:
        case CHAT_MSG_GUILD_ACHIEVEMENT:
            hasGuildGUID = true;
            break;
        case CHAT_MSG_MONSTER_WHISPER:
        case CHAT_MSG_RAID_BOSS_WHISPER:
        case CHAT_MSG_BATTLENET:
            if (receiverGUID && !IS_PLAYER_GUID(receiverGUID) && !IS_PET_GUID(receiverGUID))
                hasReceiverName = receiverName.length();
        case CHAT_MSG_MONSTER_SAY:
        case CHAT_MSG_MONSTER_PARTY:
        case CHAT_MSG_MONSTER_YELL:
        case CHAT_MSG_MONSTER_EMOTE:
        case CHAT_MSG_RAID_BOSS_EMOTE:
            hasSenderName = senderName.length();
            break;
        case CHAT_MSG_WHISPER_FOREIGN:
            hasSenderName = senderName.length();
            break;
        case CHAT_MSG_BG_SYSTEM_NEUTRAL:
        case CHAT_MSG_BG_SYSTEM_ALLIANCE:
        case CHAT_MSG_BG_SYSTEM_HORDE:
            if (receiverGUID && !IS_PLAYER_GUID(receiverGUID))
                hasReceiverName = receiverName.length();
            break;

        case CHAT_MSG_CHANNEL:
            hasChannelName = channelName.length();
            hasSenderName = senderName.length();
            break;
        default:
            if (gmMessage)
                hasSenderName = senderName.length();
            break;
    }

    if (language == LANG_ADDON)
        hasPrefix = addonPrefix.length();

    Player* sender = sObjectAccessor->FindPlayer(senderGUID);

    ObjectGuid guildGUID = hasGuildGUID && sender && sender->GetGuildId() ? MAKE_NEW_GUID(sender->GetGuildId(), 0, HIGHGUID_GUILD) : 0;
    ObjectGuid groupGUID = hasGroupGUID && sender && sender->GetGroup() ? sender->GetGroup()->GetGUID() : 0;


    data.Initialize(SMSG_MESSAGECHAT);
    data.WriteBit(!hasSenderName);
    data.WriteBit(0); // HideInChatLog - only bubble shows

    if (hasSenderName)
        data.WriteBits(senderName.length(), 11);

    data.WriteBit(0); // Fake Bit
    data.WriteBit(!hasChannelName);
    data.WriteBit(0); // Unk
    data.WriteBit(1); // SendFakeTime - float later
    data.WriteBit(!chatTag); // ChatFlags
    data.WriteBit(1); // RealmID ?

    data.WriteBit(groupGUID[0]);
    data.WriteBit(groupGUID[1]);
    data.WriteBit(groupGUID[5]);
    data.WriteBit(groupGUID[4]);
    data.WriteBit(groupGUID[3]);
    data.WriteBit(groupGUID[2]);
    data.WriteBit(groupGUID[6]);
    data.WriteBit(groupGUID[7]);

     if (chatTag)
        data.WriteBits(chatTag, 9);

    data.WriteBit(0); // Fake Bit

    data.WriteBit(receiverGUID[7]);
    data.WriteBit(receiverGUID[6]);
    data.WriteBit(receiverGUID[1]);
    data.WriteBit(receiverGUID[4]);
    data.WriteBit(receiverGUID[0]);
    data.WriteBit(receiverGUID[2]);
    data.WriteBit(receiverGUID[3]);
    data.WriteBit(receiverGUID[5]);

    data.WriteBit(0); // Fake Bit
    data.WriteBit(!language);
    data.WriteBit(!hasPrefix);

    data.WriteBit(senderGUID[0]);
    data.WriteBit(senderGUID[3]);
    data.WriteBit(senderGUID[7]);
    data.WriteBit(senderGUID[2]);
    data.WriteBit(senderGUID[1]);
    data.WriteBit(senderGUID[5]);
    data.WriteBit(senderGUID[4]);
    data.WriteBit(senderGUID[6]);

    data.WriteBit(!hasAchievementId);
    data.WriteBit(!message.length());

    if (hasChannelName)
        data.WriteBits(channelName.length(), 7);

    if (message.length())
        data.WriteBits(message.length(), 12);

    data.WriteBit(!hasReceiverName);

    if (hasPrefix)
        data.WriteBits(addonPrefix.length(), 5);

    data.WriteBit(1); // RealmID ?

    if (hasReceiverName)
        data.WriteBits(receiverName.length(), 11);

    data.WriteBit(0); // Fake Bit

    data.WriteBit(guildGUID[2]);
    data.WriteBit(guildGUID[5]);
    data.WriteBit(guildGUID[7]);
    data.WriteBit(guildGUID[4]);
    data.WriteBit(guildGUID[0]);
    data.WriteBit(guildGUID[1]);
    data.WriteBit(guildGUID[3]);
    data.WriteBit(guildGUID[6]);

    data.WriteByteSeq(guildGUID[4]);
    data.WriteByteSeq(guildGUID[5]);
    data.WriteByteSeq(guildGUID[7]);
    data.WriteByteSeq(guildGUID[3]);
    data.WriteByteSeq(guildGUID[2]);
    data.WriteByteSeq(guildGUID[6]);
    data.WriteByteSeq(guildGUID[0]);
    data.WriteByteSeq(guildGUID[1]);

    if (hasChannelName)
        data.WriteString(channelName);

    if (hasPrefix)
        data.WriteString(addonPrefix);

    // if (hasFakeTime)
    //     data << float(fakeTime);

    data.WriteByteSeq(senderGUID[4]);
    data.WriteByteSeq(senderGUID[7]);
    data.WriteByteSeq(senderGUID[1]);
    data.WriteByteSeq(senderGUID[5]);
    data.WriteByteSeq(senderGUID[0]);
    data.WriteByteSeq(senderGUID[6]);
    data.WriteByteSeq(senderGUID[2]);
    data.WriteByteSeq(senderGUID[3]);

    data << uint8(chatType);

    if (hasAchievementId)
        data << uint32(achievementId);

    data.WriteByteSeq(groupGUID[1]);
    data.WriteByteSeq(groupGUID[3]);
    data.WriteByteSeq(groupGUID[4]);
    data.WriteByteSeq(groupGUID[6]);
    data.WriteByteSeq(groupGUID[0]);
    data.WriteByteSeq(groupGUID[2]);
    data.WriteByteSeq(groupGUID[5]);
    data.WriteByteSeq(groupGUID[7]);

    data.WriteByteSeq(receiverGUID[2]);
    data.WriteByteSeq(receiverGUID[5]);
    data.WriteByteSeq(receiverGUID[3]);
    data.WriteByteSeq(receiverGUID[6]);
    data.WriteByteSeq(receiverGUID[7]);
    data.WriteByteSeq(receiverGUID[4]);
    data.WriteByteSeq(receiverGUID[1]);
    data.WriteByteSeq(receiverGUID[0]);

    if (language)
        data << uint8(language);

    if (message.length())
        data.WriteString(message);

    if (hasReceiverName)
        data.WriteString(receiverName);

    if (hasSenderName)
        data.WriteString(senderName);

    return data.wpos();
}