Merge branch 'master' of github.com:TrinityCore/TrinityCore into 4.3.4

Conflicts:
	src/server/game/Entities/Item/Item.cpp
	src/server/game/Entities/Pet/Pet.cpp
	src/server/game/Entities/Player/Player.cpp
	src/server/game/Entities/Player/Player.h
	src/server/game/Handlers/MiscHandler.cpp
	src/server/game/Miscellaneous/SharedDefines.h
	src/server/game/Reputation/ReputationMgr.cpp
	src/server/game/Server/Protocol/Opcodes.h
	src/server/game/Server/WorldSession.cpp
	src/server/game/Server/WorldSession.h
	src/server/game/Spells/SpellEffects.cpp
	src/server/game/Weather/Weather.cpp
	src/server/game/Weather/WeatherMgr.cpp
	src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp
	src/server/scripts/Spells/spell_hunter.cpp
This commit is contained in:
Michael
2014-05-25 21:52:27 +02:00
31 changed files with 437 additions and 82 deletions
@@ -0,0 +1,3 @@
DELETE FROM `spell_script_names` WHERE `spell_id`=69232;
INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
(69232,'spell_tyrannus_rimefang_icy_blast');
@@ -0,0 +1,3 @@
DELETE FROM `trinity_string` WHERE `entry`=11008;
INSERT INTO `trinity_string` (`entry`, `content_default`) VALUES
(11008, 'InhabitType: %u');
+1 -2
View File
@@ -157,8 +157,7 @@ namespace VMAP
{
float maxDist = (pos2 - pos1).magnitude();
// return false if distance is over max float, in case of cheater teleporting to the end of the universe
if (maxDist == std::numeric_limits<float>::max() ||
maxDist == std::numeric_limits<float>::infinity())
if (maxDist == std::numeric_limits<float>::max() || !std::isfinite(maxDist))
return false;
// valid map coords should *never ever* produce float overflow, but this would produce NaNs too
@@ -140,6 +140,7 @@ bool GameObjectModel::initialize(const GameObject& go, const GameObjectDisplayIn
}
#endif
owner = &go;
return true;
}
@@ -161,7 +162,7 @@ GameObjectModel* GameObjectModel::Create(const GameObject& go)
bool GameObjectModel::intersectRay(const G3D::Ray& ray, float& MaxDist, bool StopAtFirstHit, uint32 ph_mask) const
{
if (!(phasemask & ph_mask))
if (!(phasemask & ph_mask) || !owner->isSpawned())
return false;
float time = ray.intersectionTime(iBound);
@@ -44,8 +44,9 @@ class GameObjectModel /*, public Intersectable*/
float iInvScale;
float iScale;
VMAP::WorldModel* iModel;
GameObject const* owner;
GameObjectModel() : phasemask(0), iInvScale(0), iScale(0), iModel(NULL) { }
GameObjectModel() : phasemask(0), iInvScale(0), iScale(0), iModel(NULL), owner(NULL) { }
bool initialize(const GameObject& go, const GameObjectDisplayInfoEntry& info);
public:
@@ -3461,16 +3461,10 @@ void SmartScript::OnInitialize(WorldObject* obj, AreaTriggerEntry const* at)
void SmartScript::OnMoveInLineOfSight(Unit* who)
{
ProcessEventsFor(SMART_EVENT_OOC_LOS, who);
if (!me)
return;
if (me->GetVictim())
return;
ProcessEventsFor(SMART_EVENT_IC_LOS, who);
ProcessEventsFor(me->IsInCombat() ? SMART_EVENT_IC_LOS : SMART_EVENT_OOC_LOS, who);
}
/*
+6 -6
View File
@@ -55,7 +55,7 @@ Battlefield::Battlefield()
m_uiKickAfkPlayersTimer = 1000;
m_LastResurectTimer = 30 * IN_MILLISECONDS;
m_LastResurrectTimer = 30 * IN_MILLISECONDS;
m_StartGroupingTimer = 0;
m_StartGrouping = false;
StalkerGuid = 0;
@@ -185,15 +185,15 @@ bool Battlefield::Update(uint32 diff)
}
if (m_LastResurectTimer <= diff)
if (m_LastResurrectTimer <= diff)
{
for (uint8 i = 0; i < m_GraveyardList.size(); i++)
if (GetGraveyardById(i))
m_GraveyardList[i]->Resurrect();
m_LastResurectTimer = RESURRECTION_INTERVAL;
m_LastResurrectTimer = RESURRECTION_INTERVAL;
}
else
m_LastResurectTimer -= diff;
m_LastResurrectTimer -= diff;
return objective_changed;
}
@@ -634,7 +634,7 @@ void Battlefield::RemovePlayerFromResurrectQueue(uint64 playerGuid)
void Battlefield::SendAreaSpiritHealerQueryOpcode(Player* player, uint64 guid)
{
WorldPacket data(SMSG_AREA_SPIRIT_HEALER_TIME, 12);
uint32 time = m_LastResurectTimer; // resurrect every 30 seconds
uint32 time = m_LastResurrectTimer; // resurrect every 30 seconds
data << guid << time;
ASSERT(player && player->GetSession());
@@ -713,7 +713,7 @@ void BfGraveyard::Resurrect()
if (Creature* spirit = m_Bf->GetCreature(m_SpiritGuide[m_ControlTeam]))
spirit->CastSpell(spirit, SPELL_SPIRIT_HEAL, true);
// Resurect player
// Resurrect player
player->CastSpell(player, SPELL_RESURRECTION_VISUAL, true);
player->ResurrectPlayer(1.0f);
player->CastSpell(player, 6962, true);
+2 -2
View File
@@ -174,7 +174,7 @@ class BfGraveyard
// Check if this graveyard has a spirit guide
bool HasNpc(uint64 guid);
// Check if a player is in this graveyard's ressurect queue
// Check if a player is in this graveyard's resurrect queue
bool HasPlayer(uint64 guid) { return m_ResurrectQueue.find(guid) != m_ResurrectQueue.end(); }
// Get the graveyard's ID.
@@ -387,7 +387,7 @@ class Battlefield : public ZoneScript
// Graveyard variables
GraveyardVect m_GraveyardList; // Vector witch contain the different GY of the battle
uint32 m_LastResurectTimer; // Timer for resurect player every 30 sec
uint32 m_LastResurrectTimer; // Timer for resurrect player every 30 sec
uint32 m_StartGroupingTimer; // Timer for invite players in area 15 minute before start battle
bool m_StartGrouping; // bool for know if all players in area has been invited
@@ -273,7 +273,7 @@ void Battleground::Update(uint32 diff)
}
else
{
_ProcessRessurect(diff);
_ProcessResurrect(diff);
if (sBattlegroundMgr->GetPrematureFinishTime() && (GetPlayersCountByTeam(ALLIANCE) < GetMinPlayersPerTeam() || GetPlayersCountByTeam(HORDE) < GetMinPlayersPerTeam()))
_ProcessProgress(diff);
else if (m_PrematureCountDown)
@@ -342,10 +342,10 @@ inline void Battleground::_ProcessOfflineQueue()
}
}
inline void Battleground::_ProcessRessurect(uint32 diff)
inline void Battleground::_ProcessResurrect(uint32 diff)
{
// *********************************************************
// *** BATTLEGROUND RESSURECTION SYSTEM ***
// *** BATTLEGROUND RESURRECTION SYSTEM ***
// *********************************************************
// this should be handled by spell system
m_LastResurrectTime += diff;
+1 -1
View File
@@ -561,7 +561,7 @@ class Battleground
Player* _GetPlayerForTeam(uint32 teamId, BattlegroundPlayerMap::const_iterator itr, const char* context) const;
void _ProcessOfflineQueue();
void _ProcessRessurect(uint32 diff);
void _ProcessResurrect(uint32 diff);
void _ProcessProgress(uint32 diff);
void _ProcessLeave(uint32 diff);
void _ProcessJoin(uint32 diff);
+1 -1
View File
@@ -25,7 +25,7 @@
#include "Common.h"
#include "Opcodes.h"
#include "WorldSession.h"
#include "WorldPacket.h"
class Player;
@@ -2014,6 +2014,10 @@ void GameObject::SetLootState(LootState state, Unit* unit)
m_lootStateUnitGUID = unit ? unit->GetGUID() : 0;
AI()->OnStateChanged(state, unit);
sScriptMgr->OnGameObjectLootStateChanged(this, state, unit);
if (GetGoType() == GAMEOBJECT_TYPE_DOOR) // only set collision for doors on SetGoState
return;
if (m_model)
{
bool collision = false;
+23 -4
View File
@@ -7804,6 +7804,19 @@ void Player::UpdateArea(uint32 newArea)
else
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY);
uint32 const areaRestFlag = (GetTeam() == ALLIANCE) ? AREA_FLAG_REST_ZONE_ALLIANCE : AREA_FLAG_REST_ZONE_HORDE;
if (area && area->flags & areaRestFlag)
{
SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING);
SetRestType(REST_TYPE_IN_FACTION_AREA);
InnEnter(time(0), GetMapId(), 0, 0, 0);
}
else if (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) && GetRestType() == REST_TYPE_IN_FACTION_AREA)
{
RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING);
SetRestType(REST_TYPE_NO);
}
phaseMgr.RemoveUpdateFlag(PHASE_UPDATE_FLAG_AREA_UPDATE);
}
@@ -7892,8 +7905,9 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
SetRestType(REST_TYPE_NO);
}
}
else // Recently left a capital city
else if (GetRestType() != REST_TYPE_IN_FACTION_AREA) // handled in UpdateArea
{
// Recently left a capital city
RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING);
SetRestType(REST_TYPE_NO);
}
@@ -8490,7 +8504,12 @@ void Player::_ApplyWeaponDependentAuraDamageMod(Item* item, WeaponAttackType att
{
HandleStatModifier(unitMod, unitModType, float(aura->GetAmount()), apply);
if (unitModType == TOTAL_VALUE)
ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS, aura->GetAmount(), apply);
{
if (aura->GetAmount() > 0)
ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS, aura->GetAmount(), apply);
else
ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG, aura->GetAmount(), apply);
}
}
}
@@ -22684,7 +22703,7 @@ void Player::UpdatePotionCooldown(Spell* spell)
void Player::SetResurrectRequestData(Unit* caster, uint32 health, uint32 mana, uint32 appliedAura)
{
ASSERT(!IsRessurectRequested());
ASSERT(!IsResurrectRequested());
_resurrectionData = new ResurrectionData();
_resurrectionData->GUID = caster->GetGUID();
_resurrectionData->Location.WorldRelocate(*caster);
@@ -24520,7 +24539,7 @@ bool Player::IsAtRecruitAFriendDistance(WorldObject const* pOther) const
return pOther->GetDistance(player) <= sWorld->getFloatConfig(CONFIG_MAX_RECRUIT_A_FRIEND_DISTANCE);
}
void Player::ResurectUsingRequestData()
void Player::ResurrectUsingRequestData()
{
/// Teleport before resurrecting by player, otherwise the player might get attacked from creatures near his corpse
float x, y, z, o;
+8 -7
View File
@@ -802,9 +802,10 @@ class InstanceSave;
enum RestType
{
REST_TYPE_NO = 0,
REST_TYPE_IN_TAVERN = 1,
REST_TYPE_IN_CITY = 2
REST_TYPE_NO = 0,
REST_TYPE_IN_TAVERN = 1,
REST_TYPE_IN_CITY = 2,
REST_TYPE_IN_FACTION_AREA = 3 // used with AREA_FLAG_REST_ZONE_*
};
enum TeleportToOptions
@@ -1869,16 +1870,16 @@ class Player : public Unit, public GridObject<Player>
_resurrectionData = NULL;
}
bool IsRessurectRequestedBy(uint64 guid) const
bool IsResurrectRequestedBy(uint64 guid) const
{
if (!IsRessurectRequested())
if (!IsResurrectRequested())
return false;
return _resurrectionData->GUID == guid;
}
bool IsRessurectRequested() const { return _resurrectionData != NULL; }
void ResurectUsingRequestData();
bool IsResurrectRequested() const { return _resurrectionData != NULL; }
void ResurrectUsingRequestData();
uint8 getCinematic() { return m_cinematic; }
void setCinematic(uint8 cine) { m_cinematic = cine; }
@@ -19,7 +19,7 @@
#include "SocialMgr.h"
#include "DatabaseEnv.h"
#include "Opcodes.h"
#include "WorldSession.h"
#include "WorldPacket.h"
#include "Player.h"
#include "ObjectMgr.h"
+2 -7
View File
@@ -187,11 +187,6 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData)
{
TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_WHO Message");
time_t now = time(NULL);
if (now - timeLastWhoCommand < 5)
return;
else timeLastWhoCommand = now;
uint32 matchcount = 0;
uint32 level_min, level_max, racemask, classmask, zones_count, str_count;
@@ -795,10 +790,10 @@ void WorldSession::HandleResurrectResponseOpcode(WorldPacket& recvData)
return;
}
if (!GetPlayer()->IsRessurectRequestedBy(guid))
if (!GetPlayer()->IsResurrectRequestedBy(guid))
return;
GetPlayer()->ResurectUsingRequestData();
GetPlayer()->ResurrectUsingRequestData();
}
void WorldSession::SendAreaTriggerMessage(const char* Text, ...)
+2
View File
@@ -1232,6 +1232,8 @@ enum TrinityStrings
LANG_BAN_ACCOUNT_YOUBANNEDMESSAGE_WORLD = 11006,
LANG_BAN_ACCOUNT_YOUPERMBANNEDMESSAGE_WORLD = 11007,
LANG_NPCINFO_INHABIT_TYPE = 11008
// NOT RESERVED IDS 12000-1999999999
// `db_script_string` table index 2000000000-2000009999 (MIN_DB_SCRIPT_STRING_ID-MAX_DB_SCRIPT_STRING_ID)
// For other tables maybe 2000010000-2147483647 (max index)
@@ -1282,7 +1282,7 @@ enum SpellCustomErrors
SPELL_CUSTOM_ERROR_REQUIRES_CONTROL_FIREWORKS = 95, // Requires Remote Control Fireworks. Return to Hobart Grapplehammer to get more.
SPELL_CUSTOM_ERROR_MAX_NUMBER_OF_RECRUITS = 96, // You already have the max number of recruits.
SPELL_CUSTOM_ERROR_MAX_NUMBER_OF_VOLUNTEERS = 97, // You already have the max number of volunteers.
SPELL_CUSTOM_ERROR_FROSTMOURNE_RENDERED_RESSURECT = 98, // Frostmourne has rendered you unable to ressurect.
SPELL_CUSTOM_ERROR_FROSTMOURNE_RENDERED_RESURRECT = 98, // Frostmourne has rendered you unable to resurrect.
SPELL_CUSTOM_ERROR_CANT_MOUNT_WITH_SHAPESHIFT = 99, // You can't mount while affected by that shapeshift.
SPELL_CUSTOM_ERROR_FAWNS_ALREADY_FOLLOWING = 100, // Three fawns are already following you!
SPELL_CUSTOM_ERROR_ALREADY_HAVE_RIVER_BOAT = 101, // You already have a River Boat.
+13
View File
@@ -1395,11 +1395,18 @@ enum PacketProcessing
PROCESS_THREADSAFE //packet is thread-safe - process it in Map::Update()
};
class WorldSession;
class WorldPacket;
class WorldSession;
typedef void(WorldSession::*pOpcodeHandler)(WorldPacket& recvPacket);
#if defined(__GNUC__)
#pragma pack(1)
#else
#pragma pack(push, 1)
#endif
struct OpcodeHandler
{
OpcodeHandler() {}
@@ -1446,6 +1453,12 @@ class OpcodeTable
extern OpcodeTable opcodeTable;
#if defined(__GNUC__)
#pragma pack()
#else
#pragma pack(pop)
#endif
void InitOpcodes();
/// Lookup opcode name for human understandable logging
+263 -8
View File
@@ -124,7 +124,6 @@ WorldSession::WorldSession(uint32 id, WorldSocket* sock, AccountTypes sec, uint8
_filterAddonMessages(false),
recruiterId(recruiter),
isRecruiter(isARecruiter),
timeLastWhoCommand(0),
_RBACData(NULL)
{
memset(m_Tutorials, 0, sizeof(m_Tutorials));
@@ -317,12 +316,13 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
//! loop caused by re-enqueueing the same packets over and over again, we stop updating this session
//! and continue updating others. The re-enqueued packets will be handled in the next Update call for this session.
uint32 processedPackets = 0;
time_t currentTime = time(NULL);
while (m_Socket && !m_Socket->IsClosed() &&
!_recvQueue.empty() && _recvQueue.peek(true) != firstDelayedPacket &&
_recvQueue.next(packet, updater))
{
if (!AntiDOS.EvaluateOpcode(*packet))
if (!AntiDOS.EvaluateOpcode(*packet, currentTime))
KickPlayer();
OpcodeHandler const* opHandle = opcodeTable[packet->GetOpcode()];
@@ -1176,14 +1176,38 @@ void WorldSession::InvalidateRBACData()
_RBACData = NULL;
}
bool WorldSession::DosProtection::EvaluateOpcode(WorldPacket& p) const
bool WorldSession::DosProtection::EvaluateOpcode(WorldPacket& p, time_t time) const
{
if (IsOpcodeAllowed(p.GetOpcode()))
return true;
PacketCounter& packetCounter = _PacketThrottlingMap[p.GetOpcode()];
if (packetCounter.lastReceiveTime != time)
{
packetCounter.lastReceiveTime = time;
packetCounter.amountCounter = 0;
}
// Opcode not allowed, let the punishment begin
TC_LOG_INFO("network", "AntiDOS: Account %u, IP: %s, sent unacceptable packet (opc: %u, size: %u)",
Session->GetAccountId(), Session->GetRemoteAddress().c_str(), p.GetOpcode(), (uint32)p.size());
uint32 maxPacketCounterAllowed = GetMaxPacketCounterAllowed(p.GetOpcode());
bool dosTriggered = false;
// Check if player is flooding some packets
if (++packetCounter.amountCounter > maxPacketCounterAllowed)
{
dosTriggered = true;
TC_LOG_WARN("network", "AntiDOS: Account %u, IP: %s, flooding packet (opc: %s, count: %u)",
Session->GetAccountId(), Session->GetRemoteAddress().c_str(), p.GetOpcode(), packetCounter.amountCounter);
}
// Then check if player is sending packets not allowed
if (!IsOpcodeAllowed(p.GetOpcode()))
{
dosTriggered = true;
// Opcode not allowed, let the punishment begin
TC_LOG_WARN("network", "AntiDOS: Account %u, IP: %s, sent unacceptable packet (opc: %u, size: %u)",
Session->GetAccountId(), Session->GetRemoteAddress().c_str(), p.GetOpcode(), (uint32)p.size());
}
// Return true if everything is fine, otherwise apply the configured policy
if (!dosTriggered)
return true;
switch (_policy)
{
@@ -1212,3 +1236,234 @@ bool WorldSession::DosProtection::EvaluateOpcode(WorldPacket& p) const
return true;
}
}
uint32 WorldSession::DosProtection::GetMaxPacketCounterAllowed(uint16 opcode) const
{
uint32 maxPacketCounterAllowed;
switch (opcode)
{
case CMSG_MESSAGECHAT_ADDON_BATTLEGROUND:
case CMSG_MESSAGECHAT_ADDON_GUILD:
case CMSG_MESSAGECHAT_ADDON_OFFICER:
case CMSG_MESSAGECHAT_ADDON_PARTY:
case CMSG_MESSAGECHAT_ADDON_RAID:
case CMSG_MESSAGECHAT_ADDON_WHISPER:
case CMSG_MESSAGECHAT_AFK:
case CMSG_MESSAGECHAT_BATTLEGROUND:
case CMSG_MESSAGECHAT_CHANNEL:
case CMSG_MESSAGECHAT_DND:
case CMSG_MESSAGECHAT_EMOTE:
case CMSG_MESSAGECHAT_GUILD:
case CMSG_MESSAGECHAT_OFFICER:
case CMSG_MESSAGECHAT_PARTY:
case CMSG_MESSAGECHAT_RAID:
case CMSG_MESSAGECHAT_RAID_WARNING:
case CMSG_MESSAGECHAT_SAY:
case CMSG_MESSAGECHAT_WHISPER:
case CMSG_MESSAGECHAT_YELL:
{
maxPacketCounterAllowed = 500;
break;
}
case CMSG_ATTACKSTOP:
case CMSG_GUILD_QUERY:
case CMSG_NAME_QUERY:
case CMSG_PET_NAME_QUERY:
case CMSG_GAMEOBJECT_QUERY:
case CMSG_CREATURE_QUERY:
case CMSG_NPC_TEXT_QUERY:
case CMSG_ARENA_TEAM_QUERY:
case CMSG_TAXINODE_STATUS_QUERY:
case CMSG_TAXIQUERYAVAILABLENODES:
case CMSG_QUESTGIVER_QUERY_QUEST:
case CMSG_QUEST_QUERY:
case CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY:
case CMSG_QUERY_QUESTS_COMPLETED:
case CMSG_QUEST_POI_QUERY:
case CMSG_QUERY_TIME:
case CMSG_PAGE_TEXT_QUERY:
case CMSG_PETITION_QUERY:
case CMSG_QUERY_INSPECT_ACHIEVEMENTS:
case CMSG_AREA_SPIRIT_HEALER_QUERY:
case CMSG_CORPSE_MAP_POSITION_QUERY:
case CMSG_MOVE_TIME_SKIPPED:
case CMSG_GUILD_BANK_QUERY_TAB:
case CMSG_GUILD_BANK_LOG_QUERY:
case CMSG_GUILD_EVENT_LOG_QUERY:
case MSG_CORPSE_QUERY:
case MSG_QUERY_NEXT_MAIL_TIME:
case MSG_MOVE_SET_FACING:
{
maxPacketCounterAllowed = 200;
break;
}
case CMSG_REQUEST_PARTY_MEMBER_STATS:
case CMSG_WHO:
{
maxPacketCounterAllowed = 50;
break;
}
case CMSG_SETSHEATHED:
case CMSG_CONTACT_LIST:
{
maxPacketCounterAllowed = 10;
break;
}
case CMSG_GAMEOBJ_USE:
case CMSG_GAMEOBJ_REPORT_USE:
case CMSG_SPELLCLICK:
case CMSG_PLAYER_LOGOUT:
case CMSG_LOGOUT_REQUEST:
case CMSG_LOGOUT_CANCEL:
case CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE:
case CMSG_REQUEST_VEHICLE_PREV_SEAT:
case CMSG_REQUEST_VEHICLE_NEXT_SEAT:
case CMSG_REQUEST_VEHICLE_SWITCH_SEAT:
case CMSG_TOGGLE_PVP:
case CMSG_ADD_FRIEND:
case CMSG_DEL_FRIEND:
case CMSG_SET_CONTACT_NOTES:
case CMSG_RESET_INSTANCES:
case CMSG_HEARTH_AND_RESURRECT:
case CMSG_CHAR_CREATE:
case CMSG_READY_FOR_ACCOUNT_DATA_TIMES:
case CMSG_CHAR_ENUM:
case CMSG_REALM_SPLIT:
case CMSG_CHAR_DELETE:
case CMSG_PLAYER_LOGIN:
case CMSG_PET_ABANDON:
case CMSG_PET_RENAME:
case CMSG_CHAR_RENAME:
case CMSG_CHAR_CUSTOMIZE:
case CMSG_CHAR_RACE_CHANGE:
case CMSG_CHAR_FACTION_CHANGE:
case CMSG_GMTICKET_CREATE:
case CMSG_GMTICKET_UPDATETEXT:
case CMSG_GMTICKET_DELETETICKET:
case CMSG_GMSURVEY_SUBMIT:
case CMSG_GM_REPORT_LAG:
case CMSG_BUG:
case CMSG_GMRESPONSE_RESOLVE:
case CMSG_ACTIVATETAXIEXPRESS:
case CMSG_ACTIVATETAXI:
case CMSG_SELF_RES:
case CMSG_INITIATE_TRADE:
case CMSG_BEGIN_TRADE:
case CMSG_UNLEARN_SKILL:
case CMSG_DISMISS_CONTROLLED_VEHICLE:
case CMSG_REQUEST_VEHICLE_EXIT:
case CMSG_LEARN_PREVIEW_TALENTS:
case CMSG_LEARN_PREVIEW_TALENTS_PET:
case CMSG_PLAYER_VEHICLE_ENTER:
case CMSG_EJECT_PASSENGER:
case CMSG_EQUIPMENT_SET_SAVE:
case CMSG_EQUIPMENT_SET_DELETE:
case CMSG_ALTER_APPEARANCE:
case CMSG_QUESTGIVER_ACCEPT_QUEST:
case CMSG_QUESTGIVER_CHOOSE_REWARD:
case CMSG_QUESTGIVER_REQUEST_REWARD:
//case CMSG_QUESTGIVER_CANCEL:
case CMSG_QUESTLOG_REMOVE_QUEST:
case CMSG_QUEST_CONFIRM_ACCEPT:
case CMSG_QUESTGIVER_COMPLETE_QUEST:
case CMSG_DISMISS_CRITTER:
case CMSG_REPOP_REQUEST:
case CMSG_PETITION_BUY:
case CMSG_PETITION_SIGN:
case CMSG_TURN_IN_PETITION:
case CMSG_COMPLETE_CINEMATIC:
case CMSG_ITEM_REFUND:
case CMSG_SOCKET_GEMS:
case CMSG_WRAP_ITEM:
case CMSG_BUY_BANK_SLOT:
case CMSG_GROUP_INVITE_RESPONSE:
//case CMSG_GROUP_UNINVITE:
case CMSG_GROUP_UNINVITE_GUID:
case CMSG_GROUP_SET_LEADER:
case CMSG_GROUP_DISBAND:
case CMSG_GROUP_RAID_CONVERT:
case CMSG_GROUP_CHANGE_SUB_GROUP:
case CMSG_GROUP_ASSISTANT_LEADER:
case CMSG_OPT_OUT_OF_LOOT:
case CMSG_BATTLEMASTER_JOIN_ARENA:
case CMSG_BATTLEFIELD_LEAVE:
case CMSG_REPORT_PVP_AFK:
case CMSG_DUEL_ACCEPTED:
case CMSG_DUEL_CANCELLED:
case CMSG_CALENDAR_GET_CALENDAR:
case CMSG_CALENDAR_ADD_EVENT:
case CMSG_CALENDAR_UPDATE_EVENT:
case CMSG_CALENDAR_REMOVE_EVENT:
case CMSG_CALENDAR_COPY_EVENT:
case CMSG_CALENDAR_EVENT_INVITE:
case CMSG_CALENDAR_EVENT_SIGNUP:
case CMSG_CALENDAR_EVENT_RSVP:
case CMSG_CALENDAR_EVENT_REMOVE_INVITE:
case CMSG_CALENDAR_EVENT_MODERATOR_STATUS:
case CMSG_CALENDAR_COMPLAIN:
case CMSG_ARENA_TEAM_INVITE:
case CMSG_ARENA_TEAM_ACCEPT:
case CMSG_ARENA_TEAM_DECLINE:
case CMSG_ARENA_TEAM_LEAVE:
case CMSG_ARENA_TEAM_DISBAND:
case CMSG_ARENA_TEAM_REMOVE:
case CMSG_ARENA_TEAM_LEADER:
case CMSG_LOOT_METHOD:
case CMSG_GUILD_INVITE:
case CMSG_GUILD_ACCEPT:
case CMSG_GUILD_DECLINE:
case CMSG_GUILD_LEAVE:
case CMSG_GUILD_DISBAND:
case CMSG_GUILD_SET_GUILD_MASTER:
case CMSG_GUILD_MOTD:
case SMSG_GUILD_NEWS_UPDATE:
case CMSG_GUILD_QUERY_RANKS:
case CMSG_GUILD_ADD_RANK:
case CMSG_GUILD_DEL_RANK:
case CMSG_GUILD_INFO_TEXT:
case CMSG_GUILD_BANK_DEPOSIT_MONEY:
case CMSG_GUILD_BANK_WITHDRAW_MONEY:
case CMSG_GUILD_BANK_BUY_TAB:
case CMSG_GUILD_BANK_UPDATE_TAB:
case CMSG_SET_GUILD_BANK_TEXT:
case MSG_SAVE_GUILD_EMBLEM:
case MSG_PETITION_RENAME:
case MSG_PETITION_DECLINE:
case MSG_TALENT_WIPE_CONFIRM:
case MSG_SET_DUNGEON_DIFFICULTY:
case MSG_SET_RAID_DIFFICULTY:
case MSG_RANDOM_ROLL:
case MSG_RAID_TARGET_UPDATE:
case MSG_PARTY_ASSIGNMENT:
case MSG_RAID_READY_CHECK:
{
maxPacketCounterAllowed = 3;
break;
}
case CMSG_SET_ACTION_BUTTON:
{
maxPacketCounterAllowed = MAX_ACTION_BUTTONS;
break;
}
case CMSG_ITEM_REFUND_INFO:
{
maxPacketCounterAllowed = PLAYER_SLOTS_COUNT;
break;
}
default:
{
maxPacketCounterAllowed = 100;
break;
}
}
return maxPacketCounterAllowed;
}
+13 -2
View File
@@ -28,6 +28,7 @@
#include "AddonMgr.h"
#include "DatabaseEnv.h"
#include "World.h"
#include "Opcodes.h"
#include "WorldPacket.h"
#include "Cryptography/BigNumber.h"
#include "Opcodes.h"
@@ -203,6 +204,12 @@ class CharacterCreateInfo
uint8 CharCount;
};
struct PacketCounter
{
time_t lastReceiveTime;
uint32 amountCounter;
};
/// Player session in the World
class WorldSession
{
@@ -985,7 +992,7 @@ class WorldSession
friend class World;
public:
DosProtection(WorldSession* s) : Session(s), _policy((Policy)sWorld->getIntConfig(CONFIG_PACKET_SPOOF_POLICY)) { }
bool EvaluateOpcode(WorldPacket& p) const;
bool EvaluateOpcode(WorldPacket& p, time_t time) const;
void AllowOpcode(uint16 opcode, bool allow) { _isOpcodeAllowed[opcode] = allow; }
protected:
enum Policy
@@ -1004,12 +1011,17 @@ class WorldSession
return itr->second;
}
uint32 GetMaxPacketCounterAllowed(uint16 opcode) const;
WorldSession* Session;
private:
typedef std::unordered_map<uint16, bool> OpcodeStatusMap;
OpcodeStatusMap _isOpcodeAllowed; // could be bool array, but wouldn't be practical for game versions with non-linear opcodes
Policy _policy;
typedef std::unordered_map<uint16, PacketCounter> PacketThrottlingMap;
// mark this member as "mutable" so it can be modified even in const functions
mutable PacketThrottlingMap _PacketThrottlingMap;
DosProtection(DosProtection const& right) = delete;
DosProtection& operator=(DosProtection const& right) = delete;
@@ -1066,7 +1078,6 @@ class WorldSession
uint32 recruiterId;
bool isRecruiter;
ACE_Based::LockedQueue<WorldPacket*, ACE_Thread_Mutex> _recvQueue;
time_t timeLastWhoCommand;
z_stream_s* _compressionStream;
rbac::RBACData* _RBACData;
+1 -1
View File
@@ -4223,7 +4223,7 @@ void Spell::SendChannelStart(uint32 duration)
void Spell::SendResurrectRequest(Player* target)
{
// get ressurector name for creature resurrections, otherwise packet will be not accepted
// get resurrector name for creature resurrections, otherwise packet will be not accepted
// for player resurrections the name is looked up by guid
std::string const sentName(m_caster->GetTypeId() == TYPEID_PLAYER
? ""
+3 -3
View File
@@ -280,7 +280,7 @@ void Spell::EffectResurrectNew(SpellEffIndex effIndex)
Player* target = unitTarget->ToPlayer();
if (target->IsRessurectRequested()) // already have one active request
if (target->IsResurrectRequested()) // already have one active request
return;
uint32 health = damage;
@@ -4254,7 +4254,7 @@ void Spell::EffectResurrect(SpellEffIndex effIndex)
Player* target = unitTarget->ToPlayer();
if (target->IsRessurectRequested()) // already have one active request
if (target->IsResurrectRequested()) // already have one active request
return;
uint32 health = target->CountPctFromMaxHealth(damage);
@@ -5713,7 +5713,7 @@ void Spell::EffectResurrectWithAura(SpellEffIndex effIndex)
if (unitTarget->IsAlive())
return;
if (target->IsRessurectRequested()) // already have one active request
if (target->IsResurrectRequested()) // already have one active request
return;
uint32 health = target->CountPctFromMaxHealth(damage);
+11 -2
View File
@@ -24,6 +24,7 @@
#include "Player.h"
#include "Battleground.h"
#include "Vehicle.h"
#include "Pet.h"
uint32 GetTargetFlagMask(SpellTargetObjectTypes objType)
{
@@ -1678,8 +1679,16 @@ SpellCastResult SpellInfo::CheckTarget(Unit const* caster, WorldObject const* ta
// creature/player specific target checks
if (unitTarget)
{
if (AttributesEx & SPELL_ATTR1_CANT_TARGET_IN_COMBAT && unitTarget->IsInCombat())
return SPELL_FAILED_TARGET_AFFECTING_COMBAT;
if (AttributesEx & SPELL_ATTR1_CANT_TARGET_IN_COMBAT)
{
if (unitTarget->IsInCombat())
return SPELL_FAILED_TARGET_AFFECTING_COMBAT;
// player with active pet counts as a player in combat
else if (Player const* player = unitTarget->ToPlayer())
if (Pet* pet = player->GetPet())
if (pet->GetVictim() && !pet->HasUnitState(UNIT_STATE_CONTROLLED))
return SPELL_FAILED_TARGET_AFFECTING_COMBAT;
}
// only spells with SPELL_ATTR3_ONLY_TARGET_GHOSTS can target ghosts
if (((AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_GHOSTS) != 0) != unitTarget->HasAuraType(SPELL_AURA_GHOST))
+1
View File
@@ -720,6 +720,7 @@ public:
handler->PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel());
handler->PSendSysMessage(LANG_NPCINFO_EQUIPMENT, target->GetCurrentEquipmentId(), target->GetOriginalEquipmentId());
handler->PSendSysMessage(LANG_NPCINFO_HEALTH, target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth());
handler->PSendSysMessage(LANG_NPCINFO_INHABIT_TYPE, cInfo->InhabitType);
handler->PSendSysMessage(LANG_NPCINFO_UNIT_FIELD_FLAGS, target->GetUInt32Value(UNIT_FIELD_FLAGS));
for (uint8 i = 0; i < MAX_UNIT_FLAGS; ++i)
@@ -99,7 +99,7 @@ public:
FlyBackTimer = 4500;
break;
case 2:
if (!player->IsRessurectRequested())
if (!player->IsResurrectRequested())
{
me->HandleEmoteCommand(EMOTE_ONESHOT_CUSTOM_SPELL_01);
DoCast(player, SPELL_REVIVE, true);
@@ -33,12 +33,12 @@ enum Says
//Mograine says
SAY_MO_AGGRO = 0,
SAY_MO_KILL = 1,
SAY_MO_RESSURECTED = 2,
SAY_MO_RESURRECTED = 2,
//Whitemane says
SAY_WH_INTRO = 0,
SAY_WH_KILL = 1,
SAY_WH_RESSURECT = 2,
SAY_WH_RESURRECT = 2,
};
enum Spells
@@ -157,10 +157,10 @@ public:
void SpellHit(Unit* /*who*/, const SpellInfo* spell) override
{
//When hit with ressurection say text
//When hit with resurrection say text
if (spell->Id == SPELL_SCARLETRESURRECTION)
{
Talk(SAY_MO_RESSURECTED);
Talk(SAY_MO_RESURRECTED);
_bFakeDeath = false;
instance->SetData(TYPE_MOGRAINE_AND_WHITE_EVENT, SPECIAL);
@@ -174,7 +174,7 @@ public:
if (_bHasDied && !_bHeal && instance->GetData(TYPE_MOGRAINE_AND_WHITE_EVENT) == SPECIAL)
{
//On ressurection, stop fake death and heal whitemane and resume fight
//On resurrection, stop fake death and heal whitemane and resume fight
if (Unit* Whitemane = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_WHITEMANE)))
{
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
@@ -294,7 +294,7 @@ public:
if (Creature* mograine = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_MOGRAINE)))
{
DoCast(mograine, SPELL_SCARLETRESURRECTION);
Talk(SAY_WH_RESSURECT);
Talk(SAY_WH_RESURRECT);
_bCanResurrect = false;
}
}
@@ -25,12 +25,12 @@
enum Yells
{
//Gorkun
// Gorkun
SAY_GORKUN_INTRO_2 = 0,
SAY_GORKUN_OUTRO_1 = 1,
SAY_GORKUN_OUTRO_2 = 2,
//Tyrannus
// Tyrannus
SAY_AMBUSH_1 = 3,
SAY_AMBUSH_2 = 4,
SAY_GAUNTLET_START = 5,
@@ -44,12 +44,12 @@ enum Yells
SAY_DARK_MIGHT_1 = 13,
SAY_DARK_MIGHT_2 = 14,
//Jaina
// Jaina
SAY_JAYNA_OUTRO_3 = 3,
SAY_JAYNA_OUTRO_4 = 4,
SAY_JAYNA_OUTRO_5 = 5,
//Sylvanas
// Sylvanas
SAY_SYLVANAS_OUTRO_3 = 3,
SAY_SYLVANAS_OUTRO_4 = 4
};
@@ -121,7 +121,7 @@ static const Position rimefangPos[10] =
{1012.601f, 142.4965f, 665.0453f, 0.000000f},
};
static const Position miscPos = {1018.376f, 167.2495f, 628.2811f, 0.000000f}; //tyrannus combat start position
static Position const miscPos = { 1018.376f, 167.2495f, 628.2811f, 0.000000f }; // tyrannus combat start position
class boss_tyrannus : public CreatureScript
{
@@ -490,6 +490,43 @@ class spell_tyrannus_mark_of_rimefang : public SpellScriptLoader
}
};
// 69232 - Icy Blast
class spell_tyrannus_rimefang_icy_blast : public SpellScriptLoader
{
public:
spell_tyrannus_rimefang_icy_blast() : SpellScriptLoader("spell_tyrannus_rimefang_icy_blast") { }
class spell_tyrannus_rimefang_icy_blast_SpellScript : public SpellScript
{
PrepareSpellScript(spell_tyrannus_rimefang_icy_blast_SpellScript);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
if (!sSpellMgr->GetSpellInfo(SPELL_ICY_BLAST_AURA))
return false;
return true;
}
void HandleTriggerMissile(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
if (Position const* pos = GetHitDest())
if (TempSummon* summon = GetCaster()->SummonCreature(NPC_ICY_BLAST, *pos, TEMPSUMMON_TIMED_DESPAWN, 60000))
summon->CastSpell(summon, SPELL_ICY_BLAST_AURA, true);
}
void Register() override
{
OnEffectHit += SpellEffectFn(spell_tyrannus_rimefang_icy_blast_SpellScript::HandleTriggerMissile, EFFECT_1, SPELL_EFFECT_TRIGGER_MISSILE);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_tyrannus_rimefang_icy_blast_SpellScript();
}
};
class at_tyrannus_event_starter : public AreaTriggerScript
{
public:
@@ -518,5 +555,6 @@ void AddSC_boss_tyrannus()
new boss_rimefang();
new spell_tyrannus_overlord_brand();
new spell_tyrannus_mark_of_rimefang();
new spell_tyrannus_rimefang_icy_blast();
new at_tyrannus_event_starter();
}
@@ -494,13 +494,13 @@ class spell_general_vezax_mark_of_the_faceless_leech : public SpellScriptLoader
FinishCast(SPELL_FAILED_NO_VALID_TARGETS);
}
void Register()
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_general_vezax_mark_of_the_faceless_leech_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ENEMY);
}
};
SpellScript* GetSpellScript() const
SpellScript* GetSpellScript() const override
{
return new spell_general_vezax_mark_of_the_faceless_leech_SpellScript();
}
+9 -8
View File
@@ -842,15 +842,16 @@ class spell_hun_sniper_training : public SpellScriptLoader
PreventDefaultAction();
if (aurEff->GetAmount() <= 0)
{
Unit* caster = GetCaster();
Unit* target = GetTarget();
uint32 spellId = SPELL_HUNTER_SNIPER_TRAINING_BUFF_R1 + GetId() - SPELL_HUNTER_SNIPER_TRAINING_R1;
if (Unit* target = GetTarget())
if (!target->HasAura(spellId))
{
SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(spellId);
Unit* triggerCaster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(GetSpellInfo()) ? caster : target;
triggerCaster->CastSpell(target, triggeredSpellInfo, true, 0, aurEff);
}
target->CastSpell(target, spellId, true, 0, aurEff);
if (Player* playerTarget = GetUnitOwner()->ToPlayer())
{
int32 baseAmount = aurEff->GetBaseAmount();
int32 amount = playerTarget->CalculateSpellDamage(playerTarget, GetSpellInfo(), aurEff->GetEffIndex(), &baseAmount);
GetEffect(EFFECT_0)->SetAmount(amount);
}
}
}
+5
View File
@@ -31,6 +31,7 @@
#include <vector>
#include <cstring>
#include <time.h>
#include <math.h>
// Root of ByteBuffer exception hierarchy
class ByteBufferException : public std::exception
@@ -340,12 +341,16 @@ class ByteBuffer
ByteBuffer &operator>>(float &value)
{
value = read<float>();
if (!std::isfinite(value))
throw ByteBufferException();
return *this;
}
ByteBuffer &operator>>(double &value)
{
value = read<double>();
if (!std::isfinite(value))
throw ByteBufferException();
return *this;
}