diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/collision/Maps/MapTree.cpp | 3 | ||||
-rw-r--r-- | src/server/collision/Models/GameObjectModel.cpp | 3 | ||||
-rw-r--r-- | src/server/collision/Models/GameObjectModel.h | 3 | ||||
-rw-r--r-- | src/server/game/Entities/GameObject/GameObject.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 16 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 7 | ||||
-rw-r--r-- | src/server/game/Handlers/MiscHandler.cpp | 5 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.cpp | 57 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.h | 1 | ||||
-rw-r--r-- | src/server/shared/Packets/ByteBuffer.h | 5 |
10 files changed, 76 insertions, 28 deletions
diff --git a/src/server/collision/Maps/MapTree.cpp b/src/server/collision/Maps/MapTree.cpp index bb57079c389..d592d795125 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<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 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: 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; 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 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 850aecbf164..5d5e6afdd7b 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,19 +1303,27 @@ uint32 WorldSession::DosProtection::GetMaxPacketCounterAllowed(uint16 opcode) co uint32 maxPacketCounterAllowed; switch (opcode) { + // These opcodes are spammed by few addons so a very high limit is required + case CMSG_QUEST_QUERY: + case CMSG_MESSAGECHAT: case CMSG_ITEM_QUERY_SINGLE: case CMSG_ITEM_NAME_QUERY: - case CMSG_GUILD_QUERY: + case CMSG_GAMEOBJECT_QUERY: case CMSG_NAME_QUERY: case CMSG_PET_NAME_QUERY: - case CMSG_GAMEOBJECT_QUERY: case CMSG_CREATURE_QUERY: case CMSG_NPC_TEXT_QUERY: + { + maxPacketCounterAllowed = 5000; + break; + } + + case CMSG_ATTACKSTOP: + case CMSG_GUILD_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: @@ -1334,16 +1341,30 @@ uint32 WorldSession::DosProtection::GetMaxPacketCounterAllowed(uint16 opcode) co case MSG_QUERY_NEXT_MAIL_TIME: case MSG_GUILD_EVENT_LOG_QUERY: case MSG_MOVE_SET_FACING: + case CMSG_INSPECT: { - maxPacketCounterAllowed = 200; + maxPacketCounterAllowed = 500; break; } - case CMSG_MESSAGECHAT: + case CMSG_REQUEST_PARTY_MEMBER_STATS: case CMSG_WHO: + case CMSG_SETSHEATHED: + case CMSG_CONTACT_LIST: + { + maxPacketCounterAllowed = 50; + break; + } + + case CMSG_SPELLCLICK: case CMSG_GAMEOBJ_USE: case CMSG_GAMEOBJ_REPORT_USE: - case CMSG_SPELLCLICK: + case MSG_RAID_TARGET_UPDATE: + { + maxPacketCounterAllowed = 20; + break; + } + case CMSG_PLAYER_LOGOUT: case CMSG_LOGOUT_REQUEST: case CMSG_LOGOUT_CANCEL: @@ -1352,7 +1373,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: @@ -1419,14 +1439,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: @@ -1471,7 +1489,6 @@ uint32 WorldSession::DosProtection::GetMaxPacketCounterAllowed(uint16 opcode) co 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: { @@ -1479,9 +1496,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; } } 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<WorldPacket*, ACE_Thread_Mutex> _recvQueue; - time_t timeLastWhoCommand; rbac::RBACData* _RBACData; WorldSession(WorldSession const& right) = delete; diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h index dd0a9d5fdf4..9f766a72d19 100644 --- a/src/server/shared/Packets/ByteBuffer.h +++ b/src/server/shared/Packets/ByteBuffer.h @@ -31,6 +31,7 @@ #include <vector> #include <cstring> #include <time.h> +#include <math.h> // Root of ByteBuffer exception hierarchy class ByteBufferException : public std::exception @@ -241,12 +242,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; } |