From c273f5368a4fbd8f6c42d0b45afb1028ec3b0898 Mon Sep 17 00:00:00 2001 From: Trisjdc Date: Sun, 18 May 2014 11:36:12 +0100 Subject: Core/Spells: Players with active pets count as if they were players in combat against spells with SPELL_ATTR1_CANT_TARGET_IN_COMBAT --- src/server/game/Spells/SpellInfo.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 21c36510a32..ba4c3deca85 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -24,6 +24,7 @@ #include "Player.h" #include "Battleground.h" #include "Vehicle.h" +#include "Pet.h" uint32 GetTargetFlagMask(SpellTargetObjectTypes objType) { @@ -1505,8 +1506,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)) -- cgit v1.2.3 From 3c977350569e4ee3872cb534661d241bc8d9ac79 Mon Sep 17 00:00:00 2001 From: joschiwald Date: Fri, 23 May 2014 16:16:31 +0200 Subject: Scripts/PoS: fixed rimefang icy blast Closes #632 --- .../2014_05_23_00_world_spell_script_names.sql | 3 ++ .../PitOfSaron/boss_scourgelord_tyrannus.cpp | 48 +++++++++++++++++++--- .../Northrend/Ulduar/Ulduar/boss_general_vezax.cpp | 4 +- 3 files changed, 48 insertions(+), 7 deletions(-) create mode 100644 sql/updates/world/2014_05_23_00_world_spell_script_names.sql (limited to 'src') diff --git a/sql/updates/world/2014_05_23_00_world_spell_script_names.sql b/sql/updates/world/2014_05_23_00_world_spell_script_names.sql new file mode 100644 index 00000000000..22d792e6f72 --- /dev/null +++ b/sql/updates/world/2014_05_23_00_world_spell_script_names.sql @@ -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'); diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp index f581f96e562..c4f46136bd9 100644 --- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp @@ -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(); } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp index a261d2f860a..011d1844adf 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp @@ -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(); } -- cgit v1.2.3 From 80daaf8d430fb9ecacc72e940c73fe292850cce7 Mon Sep 17 00:00:00 2001 From: Discover- Date: Fri, 23 May 2014 17:11:37 +0200 Subject: Core/SAI: SMART_EVENT_IC_LOS is now called when movement in LOS was made while the creature was in combat --- src/server/game/AI/SmartScripts/SmartScript.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'src') diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index a1302c1d93c..2647368559c 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -3462,16 +3462,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); } /* -- cgit v1.2.3 From 007e9037536c10a5d0ee0739d73b5d2e411e75b2 Mon Sep 17 00:00:00 2001 From: MitchesD Date: Fri, 23 May 2014 20:51:22 +0200 Subject: Scripts/Commands: added option to show InhabitType in .npc info command --- sql/updates/world/2014_05_23_01_world_trinity_string.sql | 3 +++ src/server/game/Miscellaneous/Language.h | 2 ++ src/server/scripts/Commands/cs_npc.cpp | 1 + 3 files changed, 6 insertions(+) create mode 100644 sql/updates/world/2014_05_23_01_world_trinity_string.sql (limited to 'src') diff --git a/sql/updates/world/2014_05_23_01_world_trinity_string.sql b/sql/updates/world/2014_05_23_01_world_trinity_string.sql new file mode 100644 index 00000000000..e05d36f601c --- /dev/null +++ b/sql/updates/world/2014_05_23_01_world_trinity_string.sql @@ -0,0 +1,3 @@ +DELETE FROM `trinity_string` WHERE `entry`=11008; +INSERT INTO `trinity_string` (`entry`, `content_default`) VALUES +(11008, 'InhabitType: %u'); diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index eabc15d6ee7..34871085157 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -1224,6 +1224,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) diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index a0df1292210..28d49fe11aa 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -715,6 +715,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) -- cgit v1.2.3 From f091713086eab1ef928bc2f79eb0dc3b0bc4ce2f Mon Sep 17 00:00:00 2001 From: jackpoz Date: Sat, 24 May 2014 18:25:53 +0200 Subject: Core/Misc: Fix typo Fix typos about the word "Resurrect" --- src/server/game/Battlefield/Battlefield.cpp | 12 ++++++------ src/server/game/Battlefield/Battlefield.h | 4 ++-- src/server/game/Battlegrounds/Battleground.cpp | 6 +++--- src/server/game/Battlegrounds/Battleground.h | 2 +- src/server/game/Entities/Player/Player.cpp | 2 +- src/server/game/Entities/Player/Player.h | 6 +++--- src/server/game/Handlers/MiscHandler.cpp | 4 ++-- src/server/game/Miscellaneous/SharedDefines.h | 2 +- src/server/game/Spells/Spell.cpp | 2 +- src/server/game/Spells/SpellEffects.cpp | 4 ++-- .../ScarletEnclave/zone_the_scarlet_enclave.cpp | 2 +- .../ScarletMonastery/boss_mograine_and_whitemane.cpp | 12 ++++++------ 12 files changed, 29 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp index 96f13dcd0ac..3f9c6cf0617 100644 --- a/src/server/game/Battlefield/Battlefield.cpp +++ b/src/server/game/Battlefield/Battlefield.cpp @@ -54,7 +54,7 @@ Battlefield::Battlefield() m_uiKickAfkPlayersTimer = 1000; - m_LastResurectTimer = 30 * IN_MILLISECONDS; + m_LastResurrectTimer = 30 * IN_MILLISECONDS; m_StartGroupingTimer = 0; m_StartGrouping = false; StalkerGuid = 0; @@ -184,15 +184,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; } @@ -632,7 +632,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()); @@ -711,7 +711,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); diff --git a/src/server/game/Battlefield/Battlefield.h b/src/server/game/Battlefield/Battlefield.h index 6c9e653c510..296c48b0697 100644 --- a/src/server/game/Battlefield/Battlefield.h +++ b/src/server/game/Battlefield/Battlefield.h @@ -173,7 +173,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. @@ -383,7 +383,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 diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 97320373e16..ca48ffb3a14 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -269,7 +269,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) @@ -334,10 +334,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; diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h index 2cbf8bd0918..4256e2fc094 100644 --- a/src/server/game/Battlegrounds/Battleground.h +++ b/src/server/game/Battlegrounds/Battleground.h @@ -556,7 +556,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); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 563d7fed107..71e37b1a256 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -23927,7 +23927,7 @@ uint32 Player::GetBaseWeaponSkillValue (WeaponAttackType attType) const return GetBaseSkillValue(skill); } -void Player::ResurectUsingRequestData() +void Player::ResurrectUsingRequestData() { /// Teleport before resurrecting by player, otherwise the player might get attacked from creatures near his corpse TeleportTo(m_resurrectMap, m_resurrectX, m_resurrectY, m_resurrectZ, GetOrientation()); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 0826f533df7..7e1d9be0f88 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1654,9 +1654,9 @@ class Player : public Unit, public GridObject void setResurrectRequestData(uint64 guid, uint32 mapId, float X, float Y, float Z, uint32 health, uint32 mana); void clearResurrectRequestData() { setResurrectRequestData(0, 0, 0.0f, 0.0f, 0.0f, 0, 0); } - bool isRessurectRequestedBy(uint64 guid) const { return m_resurrectGUID == guid; } - bool isRessurectRequested() const { return m_resurrectGUID != 0; } - void ResurectUsingRequestData(); + bool isResurrectRequestedBy(uint64 guid) const { return m_resurrectGUID == guid; } + bool isResurrectRequested() const { return m_resurrectGUID != 0; } + void ResurrectUsingRequestData(); uint8 getCinematic() { return m_cinematic; } void setCinematic(uint8 cine) { m_cinematic = cine; } diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 1b04c89b338..df86c9b4b83 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -793,10 +793,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, ...) diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index b52e640afc7..0704c4eb9fe 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -1129,7 +1129,7 @@ enum SpellCustomErrors SPELL_CUSTOM_ERROR_95 = 95, // "" 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. }; diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 768c0b7e818..efdc3ca532f 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -4188,7 +4188,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 ? "" diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 65530b4b282..5b68d244457 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -259,7 +259,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; @@ -4542,7 +4542,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); diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp index e5be2cb6eb7..43dee1338ef 100644 --- a/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp @@ -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); diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp index 5891de9acf9..25bb08620a1 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp @@ -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; } } -- cgit v1.2.3 From ea1c4a355ca56b4edd431bf4c3d9dd932b8af770 Mon Sep 17 00:00:00 2001 From: Trisjdc Date: Sat, 24 May 2014 18:57:26 +0100 Subject: Core/Spells: Sniper Training should refresh every 6 seconds if all conditions are met --- src/server/scripts/Spells/spell_hunter.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index 2739a8453df..725312eafce 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -744,8 +744,13 @@ class spell_hun_sniper_training : public SpellScriptLoader { Unit* target = GetTarget(); uint32 spellId = SPELL_HUNTER_SNIPER_TRAINING_BUFF_R1 + GetId() - SPELL_HUNTER_SNIPER_TRAINING_R1; - if (!target->HasAura(spellId)) - target->CastSpell(target, spellId, 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); + } } } -- cgit v1.2.3 From 51b782a91e84be4ef80281c917e670cfab032978 Mon Sep 17 00:00:00 2001 From: Trisjdc Date: Sat, 24 May 2014 19:01:05 +0100 Subject: Core/Auras: Solve exploit involving SPELL_AURA_MOD_DAMAGE_DONE and weapon swapping --- src/server/game/Entities/Player/Player.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 71e37b1a256..f1a1524f504 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -8201,7 +8201,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); + } } } -- cgit v1.2.3 From a4ba54fbdbb690377c873ea34f1d3541002872b5 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Sat, 24 May 2014 22:04:03 +0200 Subject: Core/NetworkIO: Improve packet spam solution Implement an improved packet Anti-DoS by counting how many times the same opcode has been sent in the last second and applying the policy specified in the configs if the amount of packets exceeds a reasonable amount. Credits to the original author who decided to share this with TrinityCore team. --- src/server/game/Chat/Channels/Channel.h | 2 +- src/server/game/Entities/Item/Item.cpp | 2 +- src/server/game/Entities/Pet/Pet.cpp | 2 +- src/server/game/Entities/Player/SocialMgr.cpp | 2 +- src/server/game/Reputation/ReputationMgr.cpp | 2 +- src/server/game/Server/Protocol/Opcodes.h | 19 ++- src/server/game/Server/WorldSession.cpp | 230 +++++++++++++++++++++++++- src/server/game/Server/WorldSession.h | 14 +- src/server/game/Weather/Weather.cpp | 2 +- src/server/game/Weather/WeatherMgr.cpp | 2 +- 10 files changed, 256 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/server/game/Chat/Channels/Channel.h b/src/server/game/Chat/Channels/Channel.h index 9ad6877d929..115e340762e 100644 --- a/src/server/game/Chat/Channels/Channel.h +++ b/src/server/game/Chat/Channels/Channel.h @@ -25,7 +25,7 @@ #include "Common.h" -#include "Opcodes.h" +#include "WorldSession.h" #include "WorldPacket.h" class Player; diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index ee389ed7311..4573b85c7f3 100644 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -27,7 +27,7 @@ #include "ScriptMgr.h" #include "ConditionMgr.h" #include "Player.h" -#include "Opcodes.h" +#include "WorldSession.h" void AddItemsSetItem(Player* player, Item* item) { diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index eb4e2fcf2ee..768f5907c19 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -30,7 +30,7 @@ #include "Unit.h" #include "Util.h" #include "Group.h" -#include "Opcodes.h" +#include "WorldSession.h" #define PET_XP_FACTOR 0.05f diff --git a/src/server/game/Entities/Player/SocialMgr.cpp b/src/server/game/Entities/Player/SocialMgr.cpp index 8c8e470f80b..25315a30da1 100644 --- a/src/server/game/Entities/Player/SocialMgr.cpp +++ b/src/server/game/Entities/Player/SocialMgr.cpp @@ -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" diff --git a/src/server/game/Reputation/ReputationMgr.cpp b/src/server/game/Reputation/ReputationMgr.cpp index 69e677bd89d..46b73e74068 100644 --- a/src/server/game/Reputation/ReputationMgr.cpp +++ b/src/server/game/Reputation/ReputationMgr.cpp @@ -24,7 +24,7 @@ #include "World.h" #include "ObjectMgr.h" #include "ScriptMgr.h" -#include "Opcodes.h" +#include "WorldSession.h" const int32 ReputationMgr::PointsInRank[MAX_REPUTATION_RANK] = {36000, 3000, 3000, 3000, 6000, 12000, 21000, 1000}; diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h index e581d7d1544..7b07abdf962 100644 --- a/src/server/game/Server/Protocol/Opcodes.h +++ b/src/server/game/Server/Protocol/Opcodes.h @@ -25,12 +25,6 @@ #include "Common.h" -// Note: this include need for be sure have full definition of class WorldSession -// if this class definition not complete then VS for x64 release use different size for -// struct OpcodeHandler in this header and Opcode.cpp and get totally wrong data from -// table opcodeTable in source when Opcode.h included but WorldSession.h not included -#include "WorldSession.h" - /// List of Opcodes enum Opcodes { @@ -1366,8 +1360,15 @@ enum PacketProcessing PROCESS_THREADSAFE //packet is thread-safe - process it in Map::Update() }; +class WorldSession; class WorldPacket; +#if defined(__GNUC__) +#pragma pack(1) +#else +#pragma pack(push, 1) +#endif + struct OpcodeHandler { char const* name; @@ -1378,6 +1379,12 @@ struct OpcodeHandler extern OpcodeHandler opcodeTable[NUM_MSG_TYPES]; +#if defined(__GNUC__) +#pragma pack() +#else +#pragma pack(pop) +#endif + /// Lookup opcode name for human understandable logging inline const char* LookupOpcodeName(uint16 id) { diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 89242bada6e..850aecbf164 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -277,12 +277,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(); } @@ -1236,14 +1237,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; + } + + 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: %u, size: %u)", + Session->GetAccountId(), Session->GetRemoteAddress().c_str(), p.GetOpcode(), (uint32)p.size()); + } + + // 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()); + } - // 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()); + // Return true if everything is fine, otherwise apply the configured policy + if (!dosTriggered) + return true; switch (_policy) { @@ -1272,3 +1297,194 @@ bool WorldSession::DosProtection::EvaluateOpcode(WorldPacket& p) const return true; } } + + +uint32 WorldSession::DosProtection::GetMaxPacketCounterAllowed(uint16 opcode) const +{ + uint32 maxPacketCounterAllowed; + switch (opcode) + { + case CMSG_ITEM_QUERY_SINGLE: + case CMSG_ITEM_NAME_QUERY: + 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 MSG_GUILD_BANK_LOG_QUERY: + case MSG_QUERY_GUILD_BANK_TEXT: + case MSG_CORPSE_QUERY: + case MSG_QUERY_NEXT_MAIL_TIME: + case MSG_GUILD_EVENT_LOG_QUERY: + case MSG_MOVE_SET_FACING: + { + maxPacketCounterAllowed = 200; + break; + } + + case CMSG_MESSAGECHAT: + case CMSG_WHO: + 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_CONTACT_LIST: + 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_CONTROLLER_EJECT_PASSENGER: + case CMSG_EQUIPMENT_SET_SAVE: + case CMSG_DELETEEQUIPMENT_SET: + case CMSG_REMOVE_GLYPH: + 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_ACCEPT: + case CMSG_GROUP_DECLINE: + case CMSG_GROUP_UNINVITE_GUID: + case CMSG_GROUP_UNINVITE: + 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_REQUEST_PARTY_MEMBER_STATS: + case CMSG_OPT_OUT_OF_LOOT: + case CMSG_BATTLEMASTER_JOIN_ARENA: + case CMSG_LEAVE_BATTLEFIELD: + case CMSG_REPORT_PVP_AFK: + case CMSG_DUEL_ACCEPTED: + case CMSG_DUEL_CANCELLED: + case CMSG_SETSHEATHED: + 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_LEADER: + case CMSG_GUILD_MOTD: + case CMSG_GUILD_SET_PUBLIC_NOTE: + case CMSG_GUILD_SET_OFFICER_NOTE: + case CMSG_GUILD_RANK: + 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; + } + + default: + { + maxPacketCounterAllowed = 30; + break; + } + } + + return maxPacketCounterAllowed; +} diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 9d1a05ae753..7bea0ef9a85 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -28,6 +28,7 @@ #include "AddonMgr.h" #include "DatabaseEnv.h" #include "World.h" +#include "Opcodes.h" #include "WorldPacket.h" #include "Cryptography/BigNumber.h" #include "AccountMgr.h" @@ -196,6 +197,12 @@ class CharacterCreateInfo uint8 CharCount; }; +struct PacketCounter +{ + time_t lastReceiveTime; + uint32 amountCounter; +}; + /// Player session in the World class WorldSession { @@ -929,7 +936,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 @@ -948,12 +955,17 @@ class WorldSession return itr->second; } + uint32 GetMaxPacketCounterAllowed(uint16 opcode) const; + WorldSession* Session; private: typedef std::unordered_map 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 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; diff --git a/src/server/game/Weather/Weather.cpp b/src/server/game/Weather/Weather.cpp index cb332df9a41..8d39f553910 100644 --- a/src/server/game/Weather/Weather.cpp +++ b/src/server/game/Weather/Weather.cpp @@ -28,7 +28,7 @@ #include "ObjectMgr.h" #include "Util.h" #include "ScriptMgr.h" -#include "Opcodes.h" +#include "WorldSession.h" /// Create the Weather object Weather::Weather(uint32 zone, WeatherData const* weatherChances) diff --git a/src/server/game/Weather/WeatherMgr.cpp b/src/server/game/Weather/WeatherMgr.cpp index 59dc591ccd0..5cf5cde75fd 100644 --- a/src/server/game/Weather/WeatherMgr.cpp +++ b/src/server/game/Weather/WeatherMgr.cpp @@ -27,7 +27,7 @@ #include "AutoPtr.h" #include "Player.h" #include "WorldPacket.h" -#include "Opcodes.h" +#include "WorldSession.h" namespace WeatherMgr { -- cgit v1.2.3 From 45fcc2ff9d7df9b86b53fbfea106b827c4ac46de Mon Sep 17 00:00:00 2001 From: Trisjdc Date: Sun, 25 May 2014 11:34:26 +0100 Subject: Core/Collision: Solve collision issues with non spawned GOs --- src/server/collision/Models/GameObjectModel.cpp | 3 ++- src/server/collision/Models/GameObjectModel.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/collision/Models/GameObjectModel.cpp b/src/server/collision/Models/GameObjectModel.cpp index 1b99e282132..de97943bb37 100644 --- a/src/server/collision/Models/GameObjectModel.cpp +++ b/src/server/collision/Models/GameObjectModel.cpp @@ -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); diff --git a/src/server/collision/Models/GameObjectModel.h b/src/server/collision/Models/GameObjectModel.h index 6088b924343..99c9b1337b3 100644 --- a/src/server/collision/Models/GameObjectModel.h +++ b/src/server/collision/Models/GameObjectModel.h @@ -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: -- cgit v1.2.3 From 0ce6824a86bdd5020cf272d70747fedbd64d4828 Mon Sep 17 00:00:00 2001 From: Trisjdc Date: Sun, 25 May 2014 11:35:51 +0100 Subject: Core/Collision: Solve collision issues with GAMEOBJECT_TYPE_DOOR GOs --- src/server/game/Entities/GameObject/GameObject.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index e0374db3ece..4cf7d34cc11 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -2013,6 +2013,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; -- cgit v1.2.3 From 5e66253de230ef3f9236ba71e94296d60b05aa3f Mon Sep 17 00:00:00 2001 From: jackpoz Date: Sun, 25 May 2014 14:42:22 +0200 Subject: Core/Misc: Throw an exception if client sends invalid float/double data Throw a ByteBufferException if client sends 1.#INF0000, 1.#QNAN000, 1.#IND0000 or other invalid float/double values. Handle this invalid values in StaticMapTree::isInLineOfSight() to avoid triggering an assert. Fixes #12126 --- src/server/collision/Maps/MapTree.cpp | 3 +-- src/server/shared/Packets/ByteBuffer.h | 4 ++++ 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/collision/Maps/MapTree.cpp b/src/server/collision/Maps/MapTree.cpp index bb57079c389..60069b5c81f 100644 --- a/src/server/collision/Maps/MapTree.cpp +++ b/src/server/collision/Maps/MapTree.cpp @@ -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::max() || - maxDist == std::numeric_limits::infinity()) + if (maxDist == std::numeric_limits::max() || !isfinite(maxDist)) return false; // valid map coords should *never ever* produce float overflow, but this would produce NaNs too diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h index dd0a9d5fdf4..e06556423aa 100644 --- a/src/server/shared/Packets/ByteBuffer.h +++ b/src/server/shared/Packets/ByteBuffer.h @@ -241,12 +241,16 @@ class ByteBuffer ByteBuffer &operator>>(float &value) { value = read(); + if (!isfinite(value)) + throw ByteBufferException(); return *this; } ByteBuffer &operator>>(double &value) { value = read(); + if (!isfinite(value)) + throw ByteBufferException(); return *this; } -- cgit v1.2.3 From 2f0f8f8018f4786b9e3e3eab9a9ec17c02668923 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Sun, 25 May 2014 15:26:49 +0200 Subject: Core/NetworkIO: Adjust packet throttling values Adjust packet throttling values to avoid false positive. In case you are experiencing random kicks change the PacketSpoof.Policy setting in worldserver configs and report which packets are triggering the anti-dos system. --- src/server/game/Server/WorldSession.cpp | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 850aecbf164..81d33d30a35 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -1340,6 +1340,17 @@ uint32 WorldSession::DosProtection::GetMaxPacketCounterAllowed(uint16 opcode) co } case CMSG_MESSAGECHAT: + { + maxPacketCounterAllowed = 50; + break; + } + + case CMSG_CONTACT_LIST: + { + maxPacketCounterAllowed = 10; + break; + } + case CMSG_WHO: case CMSG_GAMEOBJ_USE: case CMSG_GAMEOBJ_REPORT_USE: @@ -1352,7 +1363,6 @@ uint32 WorldSession::DosProtection::GetMaxPacketCounterAllowed(uint16 opcode) co case CMSG_REQUEST_VEHICLE_NEXT_SEAT: case CMSG_REQUEST_VEHICLE_SWITCH_SEAT: case CMSG_TOGGLE_PVP: - case CMSG_CONTACT_LIST: case CMSG_ADD_FRIEND: case CMSG_DEL_FRIEND: case CMSG_SET_CONTACT_NOTES: @@ -1479,9 +1489,21 @@ uint32 WorldSession::DosProtection::GetMaxPacketCounterAllowed(uint16 opcode) co break; } + case CMSG_SET_ACTION_BUTTON: + { + maxPacketCounterAllowed = MAX_ACTION_BUTTONS; + break; + } + + case CMSG_ITEM_REFUND_INFO: + { + maxPacketCounterAllowed = PLAYER_SLOTS_COUNT; + break; + } + default: { - maxPacketCounterAllowed = 30; + maxPacketCounterAllowed = 100; break; } } -- cgit v1.2.3 From b4327bfc69ce7e1243f53256b8a55f8c5c0ac2f1 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Sun, 25 May 2014 15:33:56 +0200 Subject: Core/Misc: Fix no-pch build --- src/server/collision/Maps/MapTree.cpp | 2 +- src/server/shared/Packets/ByteBuffer.h | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/server/collision/Maps/MapTree.cpp b/src/server/collision/Maps/MapTree.cpp index 60069b5c81f..d592d795125 100644 --- a/src/server/collision/Maps/MapTree.cpp +++ b/src/server/collision/Maps/MapTree.cpp @@ -157,7 +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::max() || !isfinite(maxDist)) + if (maxDist == std::numeric_limits::max() || !std::isfinite(maxDist)) return false; // valid map coords should *never ever* produce float overflow, but this would produce NaNs too diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h index e06556423aa..9f766a72d19 100644 --- a/src/server/shared/Packets/ByteBuffer.h +++ b/src/server/shared/Packets/ByteBuffer.h @@ -31,6 +31,7 @@ #include #include #include +#include // Root of ByteBuffer exception hierarchy class ByteBufferException : public std::exception @@ -241,7 +242,7 @@ class ByteBuffer ByteBuffer &operator>>(float &value) { value = read(); - if (!isfinite(value)) + if (!std::isfinite(value)) throw ByteBufferException(); return *this; } @@ -249,7 +250,7 @@ class ByteBuffer ByteBuffer &operator>>(double &value) { value = read(); - if (!isfinite(value)) + if (!std::isfinite(value)) throw ByteBufferException(); return *this; } -- cgit v1.2.3 From fd753a61052480d9d25c4484846d6b1e8ddd334d Mon Sep 17 00:00:00 2001 From: Trisjdc Date: Sun, 25 May 2014 15:05:15 +0100 Subject: Core/Players: Implement resting for areas with AREA_FLAG_REST_ZONE_ALLIANCE or AREA_FLAG_REST_ZONE_HORDE --- src/server/game/Entities/Player/Player.cpp | 16 +++++++++++++++- src/server/game/Entities/Player/Player.h | 7 ++++--- 2 files changed, 19 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index f1a1524f504..f30c98957a7 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7480,6 +7480,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); + } } void Player::UpdateZone(uint32 newZone, uint32 newArea) @@ -7565,8 +7578,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); } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 7e1d9be0f88..48a2209cc14 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -729,9 +729,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 -- cgit v1.2.3 From c06dc7d37aa8c795ff505550a7bc388d2a66ecac Mon Sep 17 00:00:00 2001 From: jackpoz Date: Sun, 25 May 2014 20:14:59 +0200 Subject: Core/NetworkIO: Adjust more packet throttling values Adjust some more packet throttling values. Revert b35f831f2b386685bb3eaaad340208e293ba16a7 since it's no longer needed. Modify the AntiDoS log to specify in a more readable way which opcode triggered the system and how many packets have been received. --- src/server/game/Handlers/MiscHandler.cpp | 5 ----- src/server/game/Server/WorldSession.cpp | 19 ++++++++++++------- src/server/game/Server/WorldSession.h | 1 - 3 files changed, 12 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index df86c9b4b83..2748c0317cc 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -186,11 +186,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; diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 81d33d30a35..a784a5d636d 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -121,7 +121,6 @@ WorldSession::WorldSession(uint32 id, WorldSocket* sock, AccountTypes sec, uint8 m_TutorialsChanged(false), recruiterId(recruiter), isRecruiter(isARecruiter), - timeLastWhoCommand(0), _RBACData(NULL) { memset(m_Tutorials, 0, sizeof(m_Tutorials)); @@ -1253,8 +1252,8 @@ bool WorldSession::DosProtection::EvaluateOpcode(WorldPacket& p, time_t time) co if (++packetCounter.amountCounter > maxPacketCounterAllowed) { dosTriggered = true; - TC_LOG_WARN("network", "AntiDOS: Account %u, IP: %s, flooding packet (opc: %u, size: %u)", - Session->GetAccountId(), Session->GetRemoteAddress().c_str(), p.GetOpcode(), (uint32)p.size()); + TC_LOG_WARN("network", "AntiDOS: Account %u, IP: %s, flooding packet (opc: %s (0x%X), count: %u)", + Session->GetAccountId(), Session->GetRemoteAddress().c_str(), opcodeTable[p.GetOpcode()].name, p.GetOpcode(), packetCounter.amountCounter); } // Then check if player is sending packets not allowed @@ -1304,6 +1303,13 @@ uint32 WorldSession::DosProtection::GetMaxPacketCounterAllowed(uint16 opcode) co uint32 maxPacketCounterAllowed; switch (opcode) { + case CMSG_MESSAGECHAT: + { + maxPacketCounterAllowed = 500; + break; + } + + case CMSG_ATTACKSTOP: case CMSG_ITEM_QUERY_SINGLE: case CMSG_ITEM_NAME_QUERY: case CMSG_GUILD_QUERY: @@ -1339,19 +1345,20 @@ uint32 WorldSession::DosProtection::GetMaxPacketCounterAllowed(uint16 opcode) co break; } - case CMSG_MESSAGECHAT: + case CMSG_REQUEST_PARTY_MEMBER_STATS: + case CMSG_WHO: { maxPacketCounterAllowed = 50; break; } + case CMSG_SETSHEATHED: case CMSG_CONTACT_LIST: { maxPacketCounterAllowed = 10; break; } - case CMSG_WHO: case CMSG_GAMEOBJ_USE: case CMSG_GAMEOBJ_REPORT_USE: case CMSG_SPELLCLICK: @@ -1429,14 +1436,12 @@ uint32 WorldSession::DosProtection::GetMaxPacketCounterAllowed(uint16 opcode) co case CMSG_GROUP_RAID_CONVERT: case CMSG_GROUP_CHANGE_SUB_GROUP: case CMSG_GROUP_ASSISTANT_LEADER: - case CMSG_REQUEST_PARTY_MEMBER_STATS: case CMSG_OPT_OUT_OF_LOOT: case CMSG_BATTLEMASTER_JOIN_ARENA: case CMSG_LEAVE_BATTLEFIELD: case CMSG_REPORT_PVP_AFK: case CMSG_DUEL_ACCEPTED: case CMSG_DUEL_CANCELLED: - case CMSG_SETSHEATHED: case CMSG_CALENDAR_GET_CALENDAR: case CMSG_CALENDAR_ADD_EVENT: case CMSG_CALENDAR_UPDATE_EVENT: diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 7bea0ef9a85..1b16ce88052 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -1020,7 +1020,6 @@ class WorldSession uint32 recruiterId; bool isRecruiter; ACE_Based::LockedQueue _recvQueue; - time_t timeLastWhoCommand; rbac::RBACData* _RBACData; WorldSession(WorldSession const& right) = delete; -- cgit v1.2.3