示例#1
0
void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
{
    uint32 spellId, glyphIndex;
    uint8  cast_count, cast_flags;
    recvPacket >> cast_count;
    recvPacket >> spellId >> glyphIndex;
    recvPacket >> cast_flags;                           // flags (if 0x02 - some additional data are received)

    // ignore for remote control state (for player case)
    Unit* _mover = GetPlayer()->GetMover();
    if (_mover != GetPlayer() && _mover->GetTypeId()==TYPEID_PLAYER)
    {
        recvPacket.rpos(recvPacket.wpos());                 // prevent spam at ignore packet
        return;
    }

    DEBUG_LOG("WORLD: got cast spell packet, spellId - %u, cast_count: %u, cast_flags %u, data length = " SIZEFMTD,
              spellId, cast_count, cast_flags, recvPacket.size());

    /* process anticheat check */
    if (!GetPlayer()->GetAntiCheat()->DoAntiCheatCheck(CHECK_SPELL, spellId, CMSG_CAST_SPELL))
        return;

    SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );

    if(!spellInfo)
    {
        sLog.outError("WORLD: unknown spell id %u", spellId);
        recvPacket.rpos(recvPacket.wpos());                 // prevent spam at ignore packet
        return;
    }

    //  Players on vehicles may cast many simple spells (like knock) from self

    Unit* mover = NULL;

    if (spellInfo->HasAttribute(SPELL_ATTR_EX6_CASTABLE_ON_VEHICLE) && _mover->IsCharmerOrOwnerPlayerOrPlayerItself())
        mover = _mover->GetCharmerOrOwnerPlayerOrPlayerItself();
    else
        mover = _mover;

    // casting own spells on some vehicles
    if (mover->IsVehicle() && mover->GetCharmerOrOwnerPlayerOrPlayerItself())
    {
        Player *plr = mover->GetCharmerOrOwnerPlayerOrPlayerItself();
        if (mover->GetVehicleKit()->GetSeatInfo(plr) &&
           ((mover->GetVehicleKit()->GetSeatInfo(plr)->m_flags & SEAT_FLAG_CAN_ATTACK) ||
            (mover->GetVehicleKit()->GetSeatInfo(plr)->m_flags & SEAT_FLAG_CAN_CAST) ))
            mover = plr;
    }

    bool triggered = false;
    SpellEntry const* triggeredBy = NULL;
    Aura const* triggeredByAura = mover->GetTriggeredByClientAura(spellId);
    if (triggeredByAura)
    {
        triggered = true;
        triggeredBy = triggeredByAura->GetSpellProto();
        cast_count = 0;
    }

    if (mover->GetTypeId()==TYPEID_PLAYER)
    {
        // not have spell in spellbook or spell passive and not casted by client
        if (((((Player*)mover)->GetUInt16Value(PLAYER_FIELD_BYTES2, 0) == 0 &&
            (!((Player*)mover)->HasActiveSpell(spellId) && !triggered))
            || IsPassiveSpell(spellInfo)) && spellId != 1843)
        {
            sLog.outError("WorldSession::HandleCastSpellOpcode: %s casts spell %u which he shouldn't have", mover->GetObjectGuid().GetString().c_str(), spellId);
            //cheater? kick? ban?
            recvPacket.rpos(recvPacket.wpos());                 // prevent spam at ignore packet
            return;
        }
    }
    else
    {
        // not have spell in spellbook or spell passive and not casted by client
        if ((!((Creature*)mover)->HasSpell(spellId) && !triggered)
        || IsPassiveSpell(spellInfo))
        {
            sLog.outError("WorldSession::HandleCastSpellOpcode: %s try casts spell %u which he shouldn't have", mover->GetObjectGuid().GetString().c_str(), spellId);
            //cheater? kick? ban?
            recvPacket.rpos(recvPacket.wpos());                 // prevent spam at ignore packet
            return;
        }
    }

    Unit::AuraList swaps = mover->GetAurasByType(SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS);
    Unit::AuraList const& swaps2 = mover->GetAurasByType(SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS_2);
    if (!swaps2.empty())
        swaps.insert(swaps.end(), swaps2.begin(), swaps2.end());

    for (Unit::AuraList::const_iterator itr = swaps.begin(); itr != swaps.end(); ++itr)
    {
        if ((*itr)->isAffectedOnSpell(spellInfo))
        {
            if (SpellEntry const* newInfo = sSpellStore.LookupEntry((*itr)->GetModifier()->m_amount))
            {
                spellInfo = newInfo;
                spellId = newInfo->Id;
            }
            break;
        }
    }

    // client provided targets
    SpellCastTargets targets;

    recvPacket >> targets.ReadForCaster(mover);

    targets.ReadAdditionalData(recvPacket, cast_flags);

    // auto-selection buff level base at target level (in spellInfo)
    if (Unit* target = targets.getUnitTarget())
    {
        // if rank not found then function return NULL but in explicit cast case original spell can be casted and later failed with appropriate error message
        if (SpellEntry const *actualSpellInfo = sSpellMgr.SelectAuraRankForLevel(spellInfo, target->getLevel()))
            spellInfo = actualSpellInfo;
    }

    Spell *spell = new Spell(mover, spellInfo, triggered, mover->GetObjectGuid(), triggeredBy);
    spell->m_cast_count = cast_count;                       // set count of casts
    spell->m_glyphIndex = glyphIndex;
    spell->prepare(&targets, triggeredByAura);
}
示例#2
0
void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
{
    uint32 spellId, glyphIndex;
    uint8  cast_count, cast_flags;
    recvPacket >> cast_count;
    recvPacket >> spellId >> glyphIndex;
    recvPacket >> cast_flags;                           // flags (if 0x02 - some additional data are received)

    // ignore for remote control state (for player case)
    Unit* _mover = GetPlayer()->GetMover();
    if (_mover != GetPlayer() && _mover->GetTypeId()==TYPEID_PLAYER)
    {
        recvPacket.rpos(recvPacket.wpos());                 // prevent spam at ignore packet
        return;
    }

    DEBUG_LOG("WORLD: got cast spell packet, spellId - %u, cast_count: %u, cast_flags %u, data length = " SIZEFMTD,
              spellId, cast_count, cast_flags, recvPacket.size());

    /* process anticheat check */
    if (!GetPlayer()->GetAntiCheat()->DoAntiCheatCheck(CHECK_SPELL, spellId, CMSG_CAST_SPELL))
        return;

    SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );

    if(!spellInfo)
    {
        sLog.outError("WORLD: unknown spell id %u", spellId);
        recvPacket.rpos(recvPacket.wpos());                 // prevent spam at ignore packet
        return;
    }

    //  Players on vehicles may cast many simple spells (like knock) from self

    Unit* mover = NULL;

    if (spellInfo->HasAttribute(SPELL_ATTR_EX6_CASTABLE_ON_VEHICLE) && _mover->IsCharmerOrOwnerPlayerOrPlayerItself())
        mover = _mover->GetCharmerOrOwnerPlayerOrPlayerItself();
    else
        mover = _mover;

    // casting own spells on some vehicles
    if (Player* plr = mover->GetCharmerOrOwnerPlayerOrPlayerItself())
    {
        if (mover->IsVehicle() && (mover != plr))
        {
            if (VehicleKitPtr vehicle = mover->GetVehicleKit())
            {
                if (VehicleSeatEntry const* seatInfo = vehicle->GetSeatInfo(plr))
                    if (seatInfo->m_flags & (SEAT_FLAG_CAN_ATTACK | SEAT_FLAG_CAN_CAST))
                        mover = plr;
            }
        }
    }

    bool triggered = false;
    SpellEntry const* triggeredBy = NULL;
    Aura const* triggeredByAura = mover->GetTriggeredByClientAura(spellId);
    if (triggeredByAura)
    {
        triggered = true;
        triggeredBy = triggeredByAura->GetSpellProto();
        cast_count = 0;
    }

    Unit::AuraList const& m363auras = mover->GetAurasByType(SPELL_AURA_363);
    for (Unit::AuraList::const_iterator itr = m363auras.begin(); itr != m363auras.end(); ++itr)
    {
        if ((*itr)->GetSpellEffect()->EffectTriggerSpell == spellId)
        {
            triggered = true;
            mover->RemoveSpellAuraHolder((*itr)->GetHolder());
            break;
        }
    }

    if (!spellInfo->HasAttribute(SPELL_ATTR_EX8_RAID_MARKER))
    {
        if (mover->GetTypeId()==TYPEID_PLAYER)
        {
            // not have spell in spellbook or spell passive and not casted by client
            if ((!((Player*)mover)->HasActiveSpell(spellId) && !triggered || IsPassiveSpell(spellInfo)) && !sSpellMgr.IsAbilityOfSkillType(spellInfo, SKILL_ARCHAEOLOGY))
            {
                sLog.outError("WorldSession::HandleCastSpellOpcode: %s casts spell %u which he shouldn't have", mover->GetObjectGuid().GetString().c_str(), spellId);
                //cheater? kick? ban?
                recvPacket.rpos(recvPacket.wpos());                 // prevent spam at ignore packet
                return;
            }
        }
        else
        {
            // not have spell in spellbook or spell passive and not casted by client
            if (!((Creature*)mover)->HasSpell(spellId) && !triggered || IsPassiveSpell(spellInfo))
            {
                sLog.outError("World: Player %u casts spell %u which he shouldn't have", mover->GetGUIDLow(), spellId);
                //cheater? kick? ban?
                recvPacket.rpos(recvPacket.wpos());                 // prevent spam at ignore packet
                return;
            }
        }
    }

    Unit::AuraList swaps = _mover->GetAurasByType(SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS);
    Unit::AuraList const& swaps2 = _mover->GetAurasByType(SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS_2);
    if (!swaps2.empty())
        swaps.insert(swaps.end(), swaps2.begin(), swaps2.end());

    for (Unit::AuraList::const_iterator itr = swaps.begin(); itr != swaps.end(); ++itr)
    {
        if ((*itr)->isAffectedOnSpell(spellInfo))
        {
            if (SpellEntry const* newInfo = sSpellStore.LookupEntry((*itr)->GetModifier()->m_amount))
            {
                spellInfo = newInfo;
                spellId = newInfo->Id;
                // Force triggered to spells mirrored by Dark Simulacrum
                if ((*itr)->GetId() == 77616)
                    triggered = true;
            }
            break;
        }
    }

    // Lifebloom
    if (spellId == 33763)
    {
        // search Tree of Life (Passive)
        if (Aura* aura = _mover->GetAura(81098, EFFECT_INDEX_1))
        {
            if (SpellEntry const* newInfo = sSpellStore.LookupEntry(aura->GetModifier()->m_amount))
            {
                spellInfo = newInfo;
                spellId = newInfo->Id;
            }
        }
    }
    // client provided targets
    SpellCastTargets targets;

    recvPacket >> targets.ReadForCaster(mover);

    targets.ReadAdditionalData(recvPacket, cast_flags);

    // Multi-Shot hack
    if (!targets.getUnitTarget() && spellId == 2643)
    {
        if (Unit* target = _player->GetMap()->GetUnit(_player->GetSelectionGuid()))
            targets.setUnitTarget(target);
    }

    // auto-selection buff level base at target level (in spellInfo)
    if (Unit* target = targets.getUnitTarget())
    {
        // if rank not found then function return NULL but in explicit cast case original spell can be casted and later failed with appropriate error message
        if (SpellEntry const *actualSpellInfo = sSpellMgr.SelectAuraRankForLevel(spellInfo, target->getLevel()))
            spellInfo = actualSpellInfo;
    }

    Spell *spell = new Spell(mover, spellInfo, triggered, mover->GetObjectGuid(), triggeredBy);
    spell->m_cast_count = cast_count;                       // set count of casts
    spell->m_glyphIndex = glyphIndex;
    spell->prepare(&targets, triggeredByAura);
}
示例#3
0
void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
{
    uint32 spellId, glyphIndex;
    uint8  cast_count, cast_flags;
    recvPacket >> cast_count;
    recvPacket >> spellId >> glyphIndex;
    recvPacket >> cast_flags;                           // flags (if 0x02 - some additional data are received)

    // ignore for remote control state (for player case)
    Unit* mover = _player->GetMover();
    if (mover != _player && mover->GetTypeId() == TYPEID_PLAYER)
    {
        recvPacket.rpos(recvPacket.wpos());                 // prevent spam at ignore packet
        return;
    }

    DEBUG_LOG("WORLD: got cast spell packet, spellId - %u, cast_count: %u, cast_flags %u, data length = " SIZEFMTD,
              spellId, cast_count, cast_flags, recvPacket.size());

    SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellId);
    if (!spellInfo)
    {
        sLog.outError("WORLD: unknown spell id %u", spellId);
        recvPacket.rpos(recvPacket.wpos());                 // prevent spam at ignore packet
        return;
    }

    Aura* triggeredByAura = mover->GetTriggeredByClientAura(spellId);

    if (mover->GetTypeId() == TYPEID_PLAYER)
    {
        // not have spell in spellbook or spell passive and not casted by client

        if ((!((Player*)mover)->HasActiveSpell(spellId) && !triggeredByAura) || IsPassiveSpell(spellInfo))
        {
            sLog.outError("World: %s casts spell %u which he shouldn't have", mover->GetGuidStr().c_str(), spellId);
            // cheater? kick? ban?
            recvPacket.rpos(recvPacket.wpos());             // prevent spam at ignore packet
            return;
        }
    }
    else
    {
        // not have spell in spellbook or spell passive and not casted by client
        if (!((Creature*)mover)->HasSpell(spellId) || IsPassiveSpell(spellInfo))
        {
            // cheater? kick? ban?
            recvPacket.rpos(recvPacket.wpos());             // prevent spam at ignore packet
            return;
        }
    }

    Unit::AuraList swaps = mover->GetAurasByType(SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS);
    Unit::AuraList const& swaps2 = mover->GetAurasByType(SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS_2);
    if (!swaps2.empty())
        swaps.insert(swaps.end(), swaps2.begin(), swaps2.end());

    for (Unit::AuraList::const_iterator itr = swaps.begin(); itr != swaps.end(); ++itr)
    {
        if ((*itr)->isAffectedOnSpell(spellInfo))
        {
            if (SpellEntry const* newInfo = sSpellStore.LookupEntry((*itr)->GetModifier()->m_amount))
            {
                spellInfo = newInfo;
                spellId = newInfo->Id;
            }
            break;
        }
    }

    // client provided targets
    SpellCastTargets targets;

    recvPacket >> targets.ReadForCaster(mover);

    targets.ReadAdditionalData(recvPacket, cast_flags);

    // auto-selection buff level base at target level (in spellInfo)
    if (Unit* target = targets.getUnitTarget())
    {
        // if rank not found then function return NULL but in explicit cast case original spell can be casted and later failed with appropriate error message
        if (SpellEntry const* actualSpellInfo = sSpellMgr.SelectAuraRankForLevel(spellInfo, target->getLevel()))
            spellInfo = actualSpellInfo;
    }

    Spell* spell = new Spell(mover, spellInfo, triggeredByAura ? true : false, mover->GetObjectGuid(), triggeredByAura ? triggeredByAura->GetSpellProto() : NULL);
    spell->m_cast_count = cast_count;                       // set count of casts
    spell->m_glyphIndex = glyphIndex;
    spell->prepare(&targets, triggeredByAura);
}