aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/collision/Maps/MapTree.cpp3
-rw-r--r--src/server/collision/Models/GameObjectModel.cpp3
-rw-r--r--src/server/collision/Models/GameObjectModel.h3
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp4
-rw-r--r--src/server/game/Entities/Player/Player.cpp16
-rw-r--r--src/server/game/Entities/Player/Player.h7
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp5
-rw-r--r--src/server/game/Server/WorldSession.cpp57
-rw-r--r--src/server/game/Server/WorldSession.h1
-rw-r--r--src/server/shared/Packets/ByteBuffer.h5
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;
}