void MovementInform(uint32 movementType, uint32 pointId) override { if (movementType == WAYPOINT_MOTION_TYPE && pointId == POINT_EYE_MOVE_END - 1) { me->SetSheath(SHEATH_STATE_MELEE); me->RemoveAllAuras(); if (Player* owner = me->GetCharmerOrOwner()->ToPlayer()) { owner->RemoveAura(SPELL_EYE_FLIGHT_BOOST); for (uint8 i = 0; i < MAX_MOVE_TYPE; ++i) me->SetSpeedRate(UnitMoveType(i), owner->GetSpeedRate(UnitMoveType(i))); Talk(TALK_CONTROL, owner); } me->SetDisableGravity(false); DoCast(me, SPELL_EYE_FLIGHT); } if (movementType == POINT_MOTION_TYPE && pointId == POINT_EYE_FALL) { me->SetDisableGravity(true); me->SetControlled(true, UNIT_STATE_ROOT); _events.ScheduleEvent(EVENT_MOVE_START, 5000); } }
void UpdateAI(uint32 diff) override { _events.Update(diff); while (uint32 eventId = _events.ExecuteEvent()) { switch (eventId) { case EVENT_MOVE_START: { DoCast(me, SPELL_EYE_FLIGHT_BOOST); me->SetControlled(false, UNIT_STATE_ROOT); if (Player* owner = me->GetCharmerOrOwner()->ToPlayer()) { for (uint8 i = 0; i < MAX_MOVE_TYPE; ++i) me->SetSpeedRate(UnitMoveType(i), owner->GetSpeedRate(UnitMoveType(i))); Talk(TALK_MOVE_START, owner); } me->GetMotionMaster()->MovePath(me->GetEntry() * 100, false); break; } default: break; } } }
void AnticheatMgr::SpeedHackDetection(Player* player,MovementInfo movementInfo) { if ((sWorld->getIntConfig(CONFIG_ANTICHEAT_DETECTIONS_ENABLED) & SPEED_HACK_DETECTION) == 0) return; if (player->GetMapId() == 607 || player->HasAura(35477) || player->HasAura(2983) || player->HasAura(1850) || player->HasAuraType(SPELL_AURA_FEATHER_FALL) || player->HasAuraType(SPELL_AURA_SAFE_FALL) || player->GetMapId() == 369 || player->GetMapId() == 582 || player->GetMapId() == 584 || player->GetMapId() == 586 || player->GetMapId() == 587 || player->GetMapId() == 588 || player->GetMapId() == 589 || player->GetMapId() == 590 || player->GetMapId() == 591 || player->GetMapId() == 592 || player->GetMapId() == 593 || player->GetMapId() == 594 || player->GetMapId() == 596 || player->GetMapId() == 610 || player->GetMapId() == 612 || player->GetMapId() == 613 || player->GetMapId() == 614 || player->GetMapId() == 620 || player->GetMapId() == 621 || player->GetMapId() == 622 || player->GetMapId() == 623 || player->GetMapId() == 641 || player->GetMapId() == 642 || player->GetMapId() == 647 || player->GetMapId() == 672 || player->GetMapId() == 673 || player->GetMapId() == 712 || player->GetMapId() == 713 || player->GetMapId() == 718) return; uint32 key = player->GetGUIDLow(); // We also must check the map because the movementFlag can be modified by the client. // If we just check the flag, they could always add that flag and always skip the speed hacking detection. // 369 == DEEPRUN TRAM if (m_Players[key].GetLastMovementInfo().HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && (player->GetMapId() == 369 || player->GetMapId() == 607)) return; uint32 distance2D = (uint32)movementInfo.pos.GetExactDist2d(&m_Players[key].GetLastMovementInfo().pos); uint8 moveType = 0; // we need to know HOW is the player moving // TO-DO: Should we check the incoming movement flags? if (player->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING)) moveType = MOVE_SWIM; else if (player->IsFlying()) moveType = MOVE_FLIGHT; else if (player->HasUnitMovementFlag(MOVEMENTFLAG_WALKING)) moveType = MOVE_WALK; else moveType = MOVE_RUN; // how many yards the player can do in one sec. uint32 speedRate = (uint32)(player->GetSpeed(UnitMoveType(moveType)) + movementInfo.j_xyspeed); // how long the player took to move to here. uint32 timeDiff = getMSTimeDiff(m_Players[key].GetLastMovementInfo().time,movementInfo.time); if (!timeDiff) timeDiff = 1; // this is the distance doable by the player in 1 sec, using the time done to move to this point. uint32 clientSpeedRate = distance2D * 1000 / timeDiff; // we did the (uint32) cast to accept a margin of tolerance if (clientSpeedRate > speedRate) { BuildReport(player,SPEED_HACK_REPORT); //sLog->outError("AnticheatMgr:: Speed-Hack detected player GUID (low) %u",player->GetGUIDLow()); } }
void AnticheatMgr::SpeedHackDetection(Player* player,MovementInfo movementInfo) { // Ignorar spell 56640 if (player->HasAura(56640)) return; if ((sWorld->getIntConfig(CONFIG_ANTICHEAT_DETECTIONS_ENABLED) & SPEED_HACK_DETECTION) == 0) return; uint32 key = player->GetGUIDLow(); // We also must check the map because the movementFlag can be modified by the client. // If we just check the flag, they could always add that flag and always skip the speed hacking detection. // 369 == DEEPRUN TRAM && 607 == SoTA // if (m_Players[key].GetLastMovementInfo().HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && player->GetMapId() == 369 || player->GetMapId() == 607) // Para dejarlo como estaba borrar el de abajo y descomentar el anterior if (m_Players[key].GetLastMovementInfo().HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) return; uint32 distance2D = (uint32)movementInfo.pos.GetExactDist2d(&m_Players[key].GetLastMovementInfo().pos); uint8 moveType = 0; // we need to know HOW is the player moving // TO-DO: Should we check the incoming movement flags? if (player->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING)) moveType = MOVE_SWIM; else if (player->IsFlying()) moveType = MOVE_FLIGHT; else if (player->HasUnitMovementFlag(MOVEMENTFLAG_WALKING)) moveType = MOVE_WALK; else moveType = MOVE_RUN; // how many yards the player can do in one sec. uint32 speedRate = (uint32)(player->GetSpeed(UnitMoveType(moveType)) + movementInfo.j_xyspeed); // how long the player took to move to here. uint32 timeDiff = getMSTimeDiff(m_Players[key].GetLastMovementInfo().time,movementInfo.time); if (!timeDiff) timeDiff = 1; // this is the distance doable by the player in 1 sec, using the time done to move to this point. uint32 clientSpeedRate = distance2D * 1000 / timeDiff; // we did the (uint32) cast to accept a margin of tolerance if (clientSpeedRate > speedRate) { BuildReport(player,SPEED_HACK_REPORT); sLog->outError("AnticheatMgr:: Speed-Hack detected player GUID (low) %u",player->GetGUIDLow()); } }
void AnticheatMgr::SpeedHackDetection(Player* player,MovementInfo movementInfo) { uint32 key = player->GetGUIDLow(); // We also must check the map because the movementFlag can be modified by the client. // If we just check the flag, they could always add that flag and always skip the speed hacking detection. // 369 == DEEPRUN TRAM if (m_Players[key].GetLastMovementInfo().HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT) || m_Players[key].GetLastMovementInfo().HasMovementFlag(MOVEMENTFLAG_FALLING) || player->GetMapId() == 369) return; uint32 distance2D = (uint32)movementInfo.pos.GetExactDist2d(&m_Players[key].GetLastMovementInfo().pos); uint8 moveType = 0; // we need to know HOW is the player moving // TO-DO: Should we check the incoming movement flags? if (player->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING)) moveType = MOVE_SWIM; else if (player->IsFlying()) moveType = MOVE_FLIGHT; else if (player->HasUnitMovementFlag(MOVEMENTFLAG_WALKING)) moveType = MOVE_WALK; else moveType = MOVE_RUN; // how many yards the player can do in one sec. uint32 speedRate = (uint32)(player->GetSpeed(UnitMoveType(moveType)) + movementInfo.jump.xyspeed); // how long the player took to move to here. uint32 timeDiff = getMSTimeDiff(m_Players[key].GetLastMovementInfo().time,movementInfo.time); if (!timeDiff) timeDiff = 1; // this is the distance doable by the player in 1 sec, using the time done to move to this point. uint32 clientSpeedRate = distance2D * 1000 / timeDiff; // we did the (uint32) cast to accept a margin of tolerance if (clientSpeedRate > speedRate) { Report(player, SPEED_HACK); } }
void WorldSession::HandleMovementOpcodes(WorldPacket & recv_data) { uint16 opcode = recv_data.GetOpcode(); recv_data.hexlike(); Unit *mover = _player->m_mover; ASSERT(mover != NULL); // there must always be a mover Player *plMover = mover->GetTypeId() == TYPEID_PLAYER ? (Player*)mover : NULL; // ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck if (plMover && plMover->IsBeingTeleported()) { recv_data.rpos(recv_data.wpos()); // prevent warnings spam return; } /* extract packet */ uint64 guid; recv_data.readPackGUID(guid); MovementInfo movementInfo; movementInfo.guid = guid; ReadMovementInfo(recv_data, &movementInfo); recv_data.rpos(recv_data.wpos()); // prevent warnings spam // prevent tampered movement data if (guid != mover->GetGUID()) return; if (!movementInfo.pos.IsPositionValid()) { recv_data.rpos(recv_data.wpos()); // prevent warnings spam return; } /* handle special cases */ if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT) { // transports size limited // (also received at zeppelin leave by some reason with t_* as absolute in continent coordinates, can be safely skipped) if (movementInfo.t_pos.GetPositionX() > 50 || movementInfo.t_pos.GetPositionY() > 50 || movementInfo.t_pos.GetPositionZ() > 50) { recv_data.rpos(recv_data.wpos()); // prevent warnings spam return; } if (!Trinity::IsValidMapCoord(movementInfo.pos.GetPositionX() + movementInfo.t_pos.GetPositionX(), movementInfo.pos.GetPositionY() + movementInfo.t_pos.GetPositionY(), movementInfo.pos.GetPositionZ() + movementInfo.t_pos.GetPositionZ(), movementInfo.pos.GetOrientation() + movementInfo.t_pos.GetOrientation())) { recv_data.rpos(recv_data.wpos()); // prevent warnings spam return; } // if we boarded a transport, add us to it if (plMover && !plMover->GetTransport()) { // elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just unmount if the guid can be found in the transport list for (MapManager::TransportSet::const_iterator iter = sMapMgr.m_Transports.begin(); iter != sMapMgr.m_Transports.end(); ++iter) { if ((*iter)->GetGUID() == movementInfo.t_guid) { plMover->m_transport = (*iter); (*iter)->AddPassenger(plMover); break; } } } if (!mover->GetTransport() && !mover->GetVehicle()) { GameObject *go = mover->GetMap()->GetGameObject(movementInfo.t_guid); if (!go || go->GetGoType() != GAMEOBJECT_TYPE_TRANSPORT) movementInfo.flags &= ~MOVEMENTFLAG_ONTRANSPORT; } } else if (plMover && plMover->GetTransport()) // if we were on a transport, leave { plMover->m_transport->RemovePassenger(plMover); plMover->m_transport = NULL; movementInfo.t_pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f); movementInfo.t_time = 0; movementInfo.t_seat = -1; } // fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map). if (opcode == MSG_MOVE_FALL_LAND && plMover && !plMover->isInFlight()) plMover->HandleFall(movementInfo); if (plMover && ((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != plMover->IsInWater()) { // now client not include swimming flag in case jumping under water plMover->SetInWater(!plMover->IsInWater() || plMover->GetBaseMap()->IsUnderWater(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ())); } /*----------------------*/ // ANTICHEAT CHECKS if (sWorld.getBoolConfig(CONFIG_ANTICHEAT_ENABLE)) { /*********************/ /* Exceptions: In Flight On Transport Being Teleported Can't free move Is GameMaster **********************/ // preventing escape from JAIL! MUAHAHHAHA if (plMover && plMover->GetAreaId() == 876 && !plMover->isGameMaster()) { if (plMover->GetBaseMap()->GetAreaId(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ()) != 876) { plMover->TeleportTo(1,16226.5f,16403.6f,-64.5f,3.2f); return; } } if (plMover && !plMover->isInFlight() && !plMover->GetTransport() && !plMover->IsBeingTeleported() && plMover->CanFreeMove() && !plMover->isGameMaster()) { // speed hack detection called! plMover->SpeedHackDetection(plMover->GetLastPacket(), movementInfo,opcode, plMover->GetLastSpeedRate()); if (plMover->isAlive()) plMover->WalkOnWaterHackDetection(plMover->GetLastPacket(),movementInfo); // fly hack detection called! plMover->FlyHackDetection(plMover->GetLastPacket(),movementInfo); } // save packet time for next control. if (plMover) { uint8 uiMoveType = 0; if (plMover->IsFlying()) uiMoveType = MOVE_FLIGHT; else if (plMover->IsUnderWater()) uiMoveType = MOVE_SWIM; else uiMoveType = MOVE_RUN; plMover->SaveLastPacket(movementInfo); plMover->SetLastSpeedRate(plMover->GetSpeedRate(UnitMoveType(uiMoveType)));//plMover->GetSpeed(UnitMoveType(uiMoveType)));//Rate(UnitMoveType(uiMoveType))); plMover->SetLastOpcode(opcode); } } /* process position-change */ WorldPacket data(opcode, recv_data.size()); movementInfo.time = getMSTime(); movementInfo.guid = mover->GetGUID(); WriteMovementInfo(&data, &movementInfo); mover->SendMessageToSet(&data, _player); mover->m_movementInfo = movementInfo; // this is almost never true (not sure why it is sometimes, but it is), normally use mover->IsVehicle() if (mover->GetVehicle()) { mover->SetOrientation(movementInfo.pos.GetOrientation()); return; } mover->SetPosition(movementInfo.pos); if (plMover) // nothing is charmed, or player charmed { plMover->UpdateFallInformationIfNeed(movementInfo, opcode); if (movementInfo.pos.GetPositionZ() < -500.0f) { if (!(plMover->InBattleground() && plMover->GetBattleground() && plMover->GetBattleground()->HandlePlayerUnderMap(_player))) { // NOTE: this is actually called many times while falling // even after the player has been teleported away // TODO: discard movement packets after the player is rooted if (plMover->isAlive()) { plMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth()); // pl can be alive if GM/etc if (!plMover->isAlive()) { // change the death state to CORPSE to prevent the death timer from // starting in the next player update plMover->KillPlayer(); plMover->BuildPlayerRepop(); } } // cancel the death timer here if started plMover->RepopAtGraveyard(); } } } }
void DoIntro() { Creature *pMadrigosa = (Creature*)me->GetUnit(pInstance->GetData64(DATA_MADRIGOSA)); if (!pMadrigosa) return; switch (IntroPhase) { case 0: DoScriptText(YELL_MADR_ICE_BARRIER, pMadrigosa); pMadrigosa->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); for (uint8 i = 0; i < 8; ++i) pMadrigosa->SetSpeed(UnitMoveType(i), 2.5); pMadrigosa->GetMotionMaster()->MovePoint(1, MADRI_FLY_X, MADRI_FLY_Y, MADRI_FLY_Z); IntroPhaseTimer = 6500; ++IntroPhase; break; case 1: pInstance->SetData(DATA_BRUTALLUS_INTRO_EVENT, IN_PROGRESS); pMadrigosa->SetLevitate(false); pMadrigosa->SetWalk(true); pMadrigosa->HandleEmoteCommand(EMOTE_ONESHOT_LAND); IntroPhaseTimer = 2500; ++IntroPhase; break; case 2: pMadrigosa->SendHeartBeat(); DoScriptText(YELL_MADR_INTRO, pMadrigosa); IntroPhaseTimer = 5000; ++IntroPhase; break; case 3: float x, y, z; pMadrigosa->GetMap()->CreatureRelocation((Creature*)pMadrigosa, MADRI_FLY_X, MADRI_FLY_Y, MADRI_FLY_Z, me->GetOrientation()); me->SetInFront(pMadrigosa); pMadrigosa->SetInFront(me); DoScriptText(YELL_INTRO, me); IntroPhaseTimer = 6000; ++IntroPhase; break; case 4: pMadrigosa->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); DoStartMovement(pMadrigosa); pMadrigosa->GetMotionMaster()->MoveChase(me); me->Attack(pMadrigosa, true); pMadrigosa->Attack(me, true); IntroPhaseTimer = 7000; ++IntroPhase; break; case 5: pMadrigosa->CastSpell(me, SPELL_INTRO_FROST_BREATH, false); me->CastSpell(me, SPELL_INTRO_FROST_BREATH, true); IntroPhaseTimer = 2500; ++IntroPhase; break; case 6: me->GetMotionMaster()->MoveIdle(); pMadrigosa->SetLevitate(true); pMadrigosa->GetPosition(x, y, z); pMadrigosa->GetMotionMaster()->MovePoint(2, x, y, z+15); pMadrigosa->setHover(true); IntroPhaseTimer = 4500; ++IntroPhase; case 7: pMadrigosa->SetInFront(me); pMadrigosa->CastSpell(me, SPELL_INTRO_FROST_BLAST, false); me->CastSpell(me, SPELL_INTRO_FROST_BLAST, true); DoScriptText(YELL_MADR_ICE_BLOCK, pMadrigosa); IntroFrostBoltTimer = 500; IntroPhaseTimer = 10000; ++IntroPhase; break; case 8: DoScriptText(YELL_INTRO_BREAK_ICE, me); IntroPhaseTimer = 2000; ++IntroPhase; break; case 9: me->GetMotionMaster()->MoveIdle(); me->AttackStop(); pMadrigosa->setHover(false); pMadrigosa->SetLevitate(false); pMadrigosa->SetWalk(true); pMadrigosa->HandleEmoteCommand(EMOTE_ONESHOT_LAND); pMadrigosa->SendHeartBeat(); IntroPhaseTimer = 1000; ++IntroPhase; break; case 10: pMadrigosa->GetMotionMaster()->MoveIdle(); IntroPhaseTimer = 2500; ++IntroPhase; break; case 11: pMadrigosa->GetMap()->CreatureRelocation((Creature*)pMadrigosa, MADRI_FLY_X, MADRI_FLY_Y, MADRI_FLY_Z, me->GetOrientation()); pMadrigosa->GetMotionMaster()->MoveIdle(); IntroPhaseTimer = 2000; ++IntroPhase; break; case 12: me->GetMotionMaster()->MoveIdle(); pMadrigosa->CastSpell(me, SPELL_INTRO_ENCAPSULATE, false); DoScriptText(YELL_MADR_TRAP, pMadrigosa); IntroPhaseTimer = 1000; ++IntroPhase; break; case 13: me->GetPosition(x, y, z); me->GetMotionMaster()->MovePoint(1, x-6, y-15, z+10); me->SetInFront(pMadrigosa); IntroPhaseTimer = 8000; ++IntroPhase; break; case 14: me->RemoveAurasDueToSpell(44883); pMadrigosa->InterruptNonMeleeSpells(false); pMadrigosa->GetMotionMaster()->MoveIdle(); DoScriptText(YELL_INTRO_CHARGE, me); me->SetInFront(pMadrigosa); me->GetPosition(x, y, z); me->GetMotionMaster()->MoveFall(); IntroPhaseTimer = 3500; ++IntroPhase; break; case 15: for(uint8 i = 0; i < 8; ++i) me->SetSpeed(UnitMoveType(i), 10.0); me->GetMotionMaster()->MoveCharge(MADRI_FLY_X-5, MADRI_FLY_Y-15, MADRI_FLY_Z); AddSpellToCast((Unit*)NULL, SPELL_INTRO_CHARGE); IntroPhaseTimer = 1000; ++IntroPhase; break; case 16: DoScriptText(YELL_MADR_DEATH, pMadrigosa); pMadrigosa->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH); pMadrigosa->SetFlag(UNIT_DYNAMIC_FLAGS, (UNIT_DYNFLAG_DEAD | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_PACIFIED)); pMadrigosa->CombatStop(); pMadrigosa->DeleteThreatList(); pMadrigosa->setFaction(35); me->CombatStop(); me->RemoveFlag(UNIT_FIELD_FLAGS, (UNIT_FLAG_PET_IN_COMBAT | UNIT_FLAG_PVP_ATTACKABLE)); IntroPhaseTimer = 4000; ++IntroPhase; break; case 17: if(pInstance) me->SetFacingToObject(GameObject::GetGameObject(*me, pInstance->GetData64(DATA_BRUTALLUS_TRIGGER))); for(uint8 i = 0; i < 8; ++i) me->SetSpeed(UnitMoveType(i), 2.0); IntroPhaseTimer = 6000; ++IntroPhase; break; case 18: DoScriptText(YELL_INTRO_KILL_MADRIGOSA, me); IntroPhaseTimer = 8000; ++IntroPhase; break; case 19: DoScriptText(YELL_INTRO_TAUNT, me); AddSpellToCast(me, SPELL_INTRO_BREAK_ICE); if(pInstance) pInstance->SetData(DATA_BRUTALLUS_INTRO_EVENT, DONE); else return; if(Unit *pTrigger = me->GetUnit(pInstance->GetData64(DATA_BRUTALLUS_TRIGGER))) pTrigger->CastSpell((Unit*)NULL, SPELL_INTRO_BREAK_ICE_KNOCKBACK, false); IntroPhaseTimer = 2000; ++IntroPhase; break; case 20: EnterEvadeMode(); ++IntroPhase; break; } }
void WorldSession::HandleMoveWorldportAckOpcode() { // ignore unexpected far teleports if (!GetPlayer()->IsBeingTeleportedFar()) return; GetPlayer()->SetSemaphoreTeleportFar(false); GetPlayer()->SetIgnoreMovementCount(5); // get the teleport destination WorldLocation const loc = GetPlayer()->GetTeleportDest(); // possible errors in the coordinate validity check if (!MapManager::IsValidMapCoord(loc)) { LogoutPlayer(false); return; } // get the destination map entry, not the current one, this will fix homebind and reset greeting MapEntry const* mEntry = sMapStore.LookupEntry(loc.GetMapId()); InstanceTemplate const* mInstance = sObjectMgr->GetInstanceTemplate(loc.GetMapId()); // reset instance validity, except if going to an instance inside an instance if (GetPlayer()->m_InstanceValid == false && !mInstance) GetPlayer()->m_InstanceValid = true; Map* oldMap = GetPlayer()->GetMap(); if (GetPlayer()->IsInWorld()) { sLog->outError(LOG_FILTER_NETWORKIO, "Player (Name %s) is still in world when teleported from map %u to new map %u", GetPlayer()->GetName(), oldMap->GetId(), loc.GetMapId()); oldMap->RemovePlayerFromMap(GetPlayer(), false); } // relocate the player to the teleport destination Map* newMap = sMapMgr->CreateMap(loc.GetMapId(), GetPlayer()); // the CanEnter checks are done in TeleporTo but conditions may change // while the player is in transit, for example the map may get full if (!newMap || !newMap->CanEnter(GetPlayer())) { sLog->outError(LOG_FILTER_NETWORKIO, "Map %d could not be created for player %d, porting player to homebind", loc.GetMapId(), GetPlayer()->GetGUIDLow()); GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation()); return; } else GetPlayer()->Relocate(&loc); GetPlayer()->ResetMap(); GetPlayer()->SetMap(newMap); GetPlayer()->SendInitialPacketsBeforeAddToMap(); if (!GetPlayer()->GetMap()->AddPlayerToMap(GetPlayer())) { sLog->outError(LOG_FILTER_NETWORKIO, "WORLD: failed to teleport player %s (%d) to map %d (%s) because of unknown reason!", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), loc.GetMapId(), newMap ? newMap->GetMapName() : "Unknown"); GetPlayer()->ResetMap(); GetPlayer()->SetMap(oldMap); GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation()); return; } // battleground state prepare (in case join to BG), at relogin/tele player not invited // only add to bg group and object, if the player was invited (else he entered through command) if (_player->InBattleground()) { // cleanup setting if outdated if (!mEntry->IsBattlegroundOrArena()) { // We're not in BG _player->SetBattlegroundId(0, BATTLEGROUND_TYPE_NONE); // reset destination bg team _player->SetBGTeam(0); _player->SetByteValue(PLAYER_BYTES_3, 3, 0); } // join to bg case else if (Battleground* bg = _player->GetBattleground()) if (_player->IsInvitedForBattlegroundInstance(_player->GetBattlegroundId())) bg->AddPlayer(_player); } GetPlayer()->SendInitialPacketsAfterAddToMap(); // Update position client-side to avoid undermap /*WorldPacket data(SMSG_MOVE_UPDATE); _player->m_movementInfo.pos.m_positionX = loc.m_positionX; _player->m_movementInfo.pos.m_positionY = loc.m_positionY; _player->m_movementInfo.pos.m_positionZ = loc.m_positionZ; uint32 mstime = getMSTime(); if (m_clientTimeDelay == 0) m_clientTimeDelay = mstime - _player->m_movementInfo.time; _player->m_movementInfo.time = _player->m_movementInfo.time + m_clientTimeDelay + MOVEMENT_PACKET_TIME_DELAY; _player->WriteMovementInfo(data); _player->GetSession()->SendPacket(&data);*/ // flight fast teleport case if (GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE) { if (!_player->InBattleground()) { // short preparations to continue flight FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top()); flight->Initialize(GetPlayer()); return; } // battleground state prepare, stop flight GetPlayer()->GetMotionMaster()->MovementExpired(); GetPlayer()->CleanupAfterTaxiFlight(); } // resurrect character at enter into instance where his corpse exist after add to map Corpse* corpse = GetPlayer()->GetCorpse(); if (corpse && corpse->GetType() != CORPSE_BONES && corpse->GetMapId() == GetPlayer()->GetMapId()) { if (mEntry->IsDungeon()) { GetPlayer()->ResurrectPlayer(0.5f, false); GetPlayer()->SpawnCorpseBones(); } } bool allowMount = !mEntry->IsDungeon() || mEntry->IsBattlegroundOrArena(); if (mInstance) { Difficulty diff = GetPlayer()->GetDifficulty(mEntry->IsRaid()); if (MapDifficulty const* mapDiff = GetMapDifficultyData(mEntry->MapID, diff)) { if (mapDiff->resetTime) { if (time_t timeReset = sInstanceSaveMgr->GetResetTimeFor(mEntry->MapID, diff)) { uint32 timeleft = uint32(timeReset - time(NULL)); GetPlayer()->SendInstanceResetWarning(mEntry->MapID, diff, timeleft); } } } allowMount = mInstance->AllowMount; } // mount allow check if (!allowMount) _player->RemoveAurasByType(SPELL_AURA_MOUNTED); // update zone immediately, otherwise leave channel will cause crash in mtmap uint32 newzone, newarea; GetPlayer()->GetZoneAndAreaId(newzone, newarea); GetPlayer()->UpdateZone(newzone, newarea); for (uint8 i = 0; i < 9; ++i) GetPlayer()->UpdateSpeed(UnitMoveType(i), true); // honorless target if (GetPlayer()->pvpInfo.inHostileArea) GetPlayer()->CastSpell(GetPlayer(), 2479, true); // in friendly area else if (GetPlayer()->IsPvP() && !GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP)) GetPlayer()->UpdatePvP(false, false); // resummon pet GetPlayer()->ResummonPetTemporaryUnSummonedIfAny(); //lets process all delayed operations on successful teleport GetPlayer()->ProcessDelayedOperations(); }
void AnticheatMgr::SpeedHackDetection(Player* player,MovementInfo movementInfo) { // ghosts move faster if (!player->isAlive()) return; if (player->isGameMaster()) return; // if (player->IsMounted()) // return; if (player->HasUnitState(UNIT_STAT_ONVEHICLE)) return; if (player->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) return; if (player->IsFalling() && player->GetMapId() == 607) //False segnalation in SOTA return; if (player->IsFalling()) return; if (player->HasAuraType(SPELL_AURA_FEATHER_FALL) || player->HasAuraType(SPELL_AURA_SAFE_FALL)) return; uint32 distance2D = (uint32)movementInfo.pos.GetExactDist2d(&player->anticheatData.lastMovementInfo.pos); uint8 moveType = 0; float auraspeed = 0.0f; int32 main_speed_mod = 0; int32 main_speed_mod_fly = 0; float stack_bonus = 0.0f; float stack_bonus_fly = 0.0f; float non_stack_bonus = 0.0f; float main_speed_mod_swim = 0.0f; // we need to know HOW is the player moving // TO-DO: Should we check the incoming movement flags? if (player->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING)) moveType = MOVE_SWIM; else if (player->IsFlying()) moveType = MOVE_FLIGHT; else if (player->HasUnitMovementFlag(MOVEMENTFLAG_WALKING)) moveType = MOVE_WALK; else moveType = MOVE_RUN; if (moveType == MOVE_SWIM) { // no need for mount check main_speed_mod_swim = player->GetMaxPositiveAuraModifier(SPELL_AURA_MOD_INCREASE_SWIM_SPEED); non_stack_bonus = (100.0f + player->GetMaxPositiveAuraModifier(SPELL_AURA_MOD_SPEED_NOT_STACK)) / 100.0f; auraspeed = main_speed_mod_swim + non_stack_bonus; } if (moveType == MOVE_RUN) { if (player->IsMounted()) { main_speed_mod = player->GetMaxPositiveAuraModifier(SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED); stack_bonus = player->GetTotalAuraMultiplier(SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS); non_stack_bonus = (100.0f + player->GetMaxPositiveAuraModifier(SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK)) / 100.0f; auraspeed += main_speed_mod + stack_bonus + non_stack_bonus; } else { main_speed_mod = player->GetMaxPositiveAuraModifier(SPELL_AURA_MOD_INCREASE_SPEED); stack_bonus = player->GetTotalAuraMultiplier(SPELL_AURA_MOD_SPEED_ALWAYS); non_stack_bonus = (100.0f + player->GetMaxPositiveAuraModifier(SPELL_AURA_MOD_SPEED_NOT_STACK)) / 100.0f; auraspeed += main_speed_mod + stack_bonus + non_stack_bonus; } } if (moveType == MOVE_FLIGHT) { // no need for mount check main_speed_mod_fly = player->GetMaxPositiveAuraModifier(SPELL_AURA_MOD_INCREASE_VEHICLE_FLIGHT_SPEED); stack_bonus_fly = player->GetTotalAuraMultiplier(SPELL_AURA_MOD_VEHICLE_SPEED_ALWAYS); non_stack_bonus = (100.0f + player->GetMaxPositiveAuraModifier(SPELL_AURA_MOD_SPEED_NOT_STACK)) / 100.0f; auraspeed += main_speed_mod_fly + stack_bonus_fly + non_stack_bonus; } // how many yards the player can do in one sec. uint32 speedRate = (uint32)(player->GetSpeed(UnitMoveType(moveType)) + movementInfo.j_xyspeed + auraspeed); // how long the player took to move to here. uint32 timeDiff = getMSTimeDiff(player->anticheatData.lastMovementInfo.time,movementInfo.time); if (timeDiff == 0) timeDiff = 1; // this is the distance doable by the player in 1 sec, using the time done to move to this point. //this has changed since 335a was 1000 uint32 clientSpeedRate = (distance2D * 1000 / timeDiff) + auraspeed; sLog->outError("fallxy %f fallz %f Distance2D %u clientSpeedRate %u speedRate %u auraspeed %u timeDiff %u ",movementInfo.j_xyspeed, movementInfo.j_zspeed,distance2D,clientSpeedRate,speedRate,auraspeed,timeDiff); // we did the (uint32) cast to accept a margin of tolerance if (clientSpeedRate > speedRate) { BuildReport(player,SPEED_HACK_REPORT); sLog->outError("Speed Hack Player LowGuid %u",player->GetGUIDLow()); std::string ircchana = sWorld->AntiCheatWarnChannel; std::stringstream ssa; ssa << player->GetName(); ssa << " <- Lagging or speed hack!"; if(sIRC.Active == 1) sIRC.Send_IRC_Channel(ircchana, sIRC.MakeMsg("\00304,08\037/!\\\037\017\00304 AntiCheat \00304,08\037/!\\\037\017 %s", "%s", ssa.str().c_str()), true); } }