feat(Core/Packet): Implement AntiDOS protection from Trinity (#2789)

* Implement AntiDOS protection from Trinity


Co-authored-by: jackpoz <giacomopoz@gmail.com>
Co-authored-by: Shauren <shauren.trinity@gmail.com>
Co-authored-by: Vincent-Michael <trinity.michael_vincent@gmx.eu>
This commit is contained in:
Nefertumm
2020-03-23 15:46:00 -03:00
committed by GitHub
parent c5a7497f4d
commit 846f7862d8
13 changed files with 473 additions and 80 deletions

View File

@@ -41,7 +41,7 @@
namespace {
std::string const DefaultPlayerName = "<none>";
std::string const DefaultPlayerName = "<none>";
} // namespace
@@ -86,17 +86,18 @@ bool WorldSessionFilter::Process(WorldPacket* packet)
}
/// WorldSession constructor
WorldSession::WorldSession(uint32 id, WorldSocket* sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale, uint32 recruiter, bool isARecruiter, bool skipQueue, uint32 TotalTime):
WorldSession::WorldSession(uint32 id, WorldSocket* sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale, uint32 recruiter, bool isARecruiter, bool skipQueue, uint32 TotalTime) :
m_muteTime(mute_time),
m_timeOutTime(0),
_lastAuctionListItemsMSTime(0),
_lastAuctionListOwnerItemsMSTime(0),
AntiDOS(this),
m_GUIDLow(0),
_player(NULL),
m_Socket(sock),
_security(sec),
_skipQueue(skipQueue),
_accountId(id),
_accountId(id),
m_expansion(expansion),
m_total_time(TotalTime),
_logoutTime(0),
@@ -109,7 +110,7 @@ WorldSession::WorldSession(uint32 id, WorldSocket* sock, AccountTypes sec, uint8
m_latency(0),
m_clientTimeDelay(0),
m_TutorialsChanged(false),
recruiterId(recruiter),
recruiterId(recruiter),
isRecruiter(isARecruiter),
m_currentBankerGUID(0),
timeWhoCommandAllowed(0)
@@ -139,7 +140,7 @@ WorldSession::~WorldSession()
///- unload player if not unloaded
if (_player)
LogoutPlayer (true);
LogoutPlayer(true);
/// - If have unclosed socket, close it
if (m_Socket)
@@ -174,8 +175,8 @@ std::string WorldSession::GetPlayerInfo() const
std::ostringstream ss;
ss << "[Player: " << GetPlayerName()
<< " (Guid: " << (_player != NULL ? _player->GetGUID() : 0)
<< ", Account: " << GetAccountId() << ")]";
<< " (Guid: " << (_player != NULL ? _player->GetGUID() : 0)
<< ", Account: " << GetAccountId() << ")]";
return ss.str();
}
@@ -207,20 +208,20 @@ void WorldSession::SendPacket(WorldPacket const* packet)
if ((cur_time - lastTime) < 60)
{
sendPacketCount+=1;
sendPacketBytes+=packet->size();
sendPacketCount += 1;
sendPacketBytes += packet->size();
sendLastPacketCount+=1;
sendLastPacketBytes+=packet->size();
sendLastPacketCount += 1;
sendLastPacketBytes += packet->size();
}
else
{
uint64 minTime = uint64(cur_time - lastTime);
uint64 fullTime = uint64(lastTime - firstTime);
sLog->outDetail("Send all time packets count: " UI64FMTD " bytes: " UI64FMTD " avr.count/sec: %f avr.bytes/sec: %f time: %u", sendPacketCount, sendPacketBytes, float(sendPacketCount)/fullTime, float(sendPacketBytes)/fullTime, uint32(fullTime));
sLog->outDetail("Send all time packets count: " UI64FMTD " bytes: " UI64FMTD " avr.count/sec: %f avr.bytes/sec: %f time: %u", sendPacketCount, sendPacketBytes, float(sendPacketCount) / fullTime, float(sendPacketBytes) / fullTime, uint32(fullTime));
sLog->outDetail("Send last min packets count: " UI64FMTD " bytes: " UI64FMTD " avr.count/sec: %f avr.bytes/sec: %f", sendLastPacketCount, sendLastPacketBytes, float(sendLastPacketCount)/minTime, float(sendLastPacketBytes)/minTime);
sLog->outDetail("Send last min packets count: " UI64FMTD " bytes: " UI64FMTD " avr.count/sec: %f avr.bytes/sec: %f", sendLastPacketCount, sendLastPacketBytes, float(sendLastPacketCount) / minTime, float(sendLastPacketBytes) / minTime);
lastTime = cur_time;
sendLastPacketCount = 1;
@@ -251,7 +252,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
if (updater.ProcessLogout())
{
UpdateTimeOutTime(diff);
/// If necessary, kick the player because the client didn't send anything for too long
/// (or they've been idling in character select)
if (sWorld->getBoolConfig(CONFIG_CLOSE_IDLE_CONNECTIONS) && IsConnectionIdle() && m_Socket)
@@ -266,12 +267,13 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
bool deletePacket = true;
WorldPacket* firstDelayedPacket = NULL;
uint32 processedPackets = 0;
time_t currentTime = time(nullptr);
while (m_Socket && !m_Socket->IsClosed() && !_recvQueue.empty() && _recvQueue.peek(true) != firstDelayedPacket && _recvQueue.next(packet, updater))
{
if (packet->GetOpcode() >= NUM_MSG_TYPES)
{
sLog->outError("WorldSession Packet filter: received non-existent opcode %s (0x%.4X)",LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode());
sLog->outError("WorldSession Packet filter: received non-existent opcode %s (0x%.4X)", LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode());
}
else
{
@@ -299,24 +301,24 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
QueuePacket(packet);
}*/
}
else
else if (_player->IsInWorld() && AntiDOS.EvaluateOpcode(*packet, currentTime))
{
if (movementPacket)
{
HandleMovementOpcodes(*movementPacket);
delete movementPacket;
movementPacket = NULL;
}
sScriptMgr->OnPacketReceive(this, *packet);
#ifdef ELUNA
if (!sEluna->OnPacketReceive(this, *packet))
break;
#endif
(this->*opHandle.handler)(*packet);
if (movementPacket)
{
HandleMovementOpcodes(*movementPacket);
delete movementPacket;
movementPacket = NULL;
}
sScriptMgr->OnPacketReceive(this, *packet);
#ifdef ELUNA
if (!sEluna->OnPacketReceive(this, *packet))
break;
#endif
(this->*opHandle.handler)(*packet);
}
break;
case STATUS_TRANSFER:
if (_player && !_player->IsInWorld())
if (_player && !_player->IsInWorld() && AntiDOS.EvaluateOpcode(*packet, currentTime))
{
if (movementPacket)
{
@@ -324,10 +326,10 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
movementPacket = NULL;
}
sScriptMgr->OnPacketReceive(this, *packet);
#ifdef ELUNA
#ifdef ELUNA
if (!sEluna->OnPacketReceive(this, *packet))
break;
#endif
#endif
(this->*opHandle.handler)(*packet);
}
break;
@@ -335,12 +337,15 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
if (m_inQueue) // prevent cheating
break;
sScriptMgr->OnPacketReceive(this, *packet);
#ifdef ELUNA
if (!sEluna->OnPacketReceive(this, *packet))
break;
#endif
(this->*opHandle.handler)(*packet);
if (AntiDOS.EvaluateOpcode(*packet, currentTime))
{
sScriptMgr->OnPacketReceive(this, *packet);
#ifdef ELUNA
if (!sEluna->OnPacketReceive(this, *packet))
break;
#endif
(this->*opHandle.handler)(*packet);
}
break;
case STATUS_NEVER:
break;
@@ -348,7 +353,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
break;
}
}
catch(ByteBufferException const&)
catch (ByteBufferException const&)
{
sLog->outError("WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i. Skipped packet.", packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId());
if (sLog->IsOutDebug())
@@ -361,8 +366,8 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
if (deletePacket)
delete packet;
else
deletePacket = true;
deletePacket = true;
if (++processedPackets >= 150) // limit (by count) packets processed in one update, prevent DDoS
break;
@@ -423,13 +428,13 @@ void WorldSession::HandleTeleportTimeout(bool updateInSessions)
time_t currTime = time(NULL);
if (updateInSessions) // session update from World::UpdateSessions
{
if (GetPlayer()->IsBeingTeleportedFar() && GetPlayer()->GetSemaphoreTeleportFar()+sWorld->getIntConfig(CONFIG_TELEPORT_TIMEOUT_FAR) < currTime)
if (GetPlayer()->IsBeingTeleportedFar() && GetPlayer()->GetSemaphoreTeleportFar() + sWorld->getIntConfig(CONFIG_TELEPORT_TIMEOUT_FAR) < currTime)
while (GetPlayer() && GetPlayer()->IsBeingTeleportedFar())
HandleMoveWorldportAckOpcode();
}
else // session update from Map::Update
{
if (GetPlayer()->IsBeingTeleportedNear() && GetPlayer()->GetSemaphoreTeleportNear()+sWorld->getIntConfig(CONFIG_TELEPORT_TIMEOUT_NEAR) < currTime)
if (GetPlayer()->IsBeingTeleportedNear() && GetPlayer()->GetSemaphoreTeleportNear() + sWorld->getIntConfig(CONFIG_TELEPORT_TIMEOUT_NEAR) < currTime)
while (GetPlayer() && GetPlayer()->IsInWorld() && GetPlayer()->IsBeingTeleportedNear())
{
Player* plMover = GetPlayer()->m_mover->ToPlayer();
@@ -493,13 +498,13 @@ void WorldSession::LogoutPlayer(bool save)
sOutdoorPvPMgr->HandlePlayerLeaveZone(_player, _player->GetZoneId());
// pussywizard: remove from battleground queues on logout
for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
for (int i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
if (BattlegroundQueueTypeId bgQueueTypeId = _player->GetBattlegroundQueueTypeId(i))
{
_player->RemoveBattlegroundQueueId(bgQueueTypeId);
sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId).RemovePlayer(_player->GetGUID(), false, i);
// track if player logs out after invited to join BG
if(_player->IsInvitedForBattlegroundInstance() && sWorld->getBoolConfig(CONFIG_BATTLEGROUND_TRACK_DESERTERS))
if (_player->IsInvitedForBattlegroundInstance() && sWorld->getBoolConfig(CONFIG_BATTLEGROUND_TRACK_DESERTERS))
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_DESERTER_TRACK);
stmt->setUInt32(0, _player->GetGUIDLow());
@@ -560,7 +565,7 @@ void WorldSession::LogoutPlayer(bool save)
{
_player->GetGroup()->SendUpdate();
_player->GetGroup()->ResetMaxEnchantingLevel();
Map::PlayerList const &playerList = _player->GetMap()->GetPlayers();
if (_player->GetMap()->IsDungeon() || _player->GetMap()->IsRaidOrHeroicDungeon())
@@ -732,8 +737,7 @@ void WorldSession::LoadAccountData(PreparedQueryResult result, uint32 mask)
m_accountData[type].Time = time_t(fields[1].GetUInt32());
m_accountData[type].Data = fields[2].GetString();
}
while (result->NextRow());
} while (result->NextRow());
}
void WorldSession::SetAccountData(AccountDataType type, time_t tm, std::string const& data)
@@ -757,7 +761,7 @@ void WorldSession::SetAccountData(AccountDataType type, time_t tm, std::string c
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(index);
stmt->setUInt32(0, id);
stmt->setUInt8 (1, type);
stmt->setUInt8(1, type);
stmt->setUInt32(2, uint32(tm));
stmt->setString(3, data);
CharacterDatabase.Execute(stmt);
@@ -855,8 +859,8 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo* mi)
//! Anti-cheat checks. Please keep them in seperate if() blocks to maintain a clear overview.
//! Might be subject to latency, so just remove improper flags.
#ifdef ACORE_DEBUG
#define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \
#ifdef ACORE_DEBUG
#define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \
{ \
if (check) \
{ \
@@ -866,17 +870,17 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo* mi)
mi->RemoveMovementFlag((maskToRemove)); \
} \
}
#else
#define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \
#else
#define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \
if (check) \
mi->RemoveMovementFlag((maskToRemove));
#endif
#endif
/*! This must be a packet spoofing attempt. MOVEMENTFLAG_ROOT sent from the client is not valid
in conjunction with any of the moving movement flags such as MOVEMENTFLAG_FORWARD.
It will freeze clients that receive this player's movement info.
*/
/*! This must be a packet spoofing attempt. MOVEMENTFLAG_ROOT sent from the client is not valid
in conjunction with any of the moving movement flags such as MOVEMENTFLAG_FORWARD.
It will freeze clients that receive this player's movement info.
*/
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_ROOT),
MOVEMENTFLAG_ROOT);
@@ -920,7 +924,7 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo* mi)
e.g. aerial combat.
*/
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FLYING | MOVEMENTFLAG_CAN_FLY) && GetSecurity() == SEC_PLAYER && !GetPlayer()->m_mover->HasAuraType(SPELL_AURA_FLY) && !GetPlayer()->m_mover->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED),
MOVEMENTFLAG_FLYING | MOVEMENTFLAG_CAN_FLY);
@@ -932,7 +936,7 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo* mi)
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_SPLINE_ENABLED) &&
(!GetPlayer()->movespline->Initialized() || GetPlayer()->movespline->Finalized()), MOVEMENTFLAG_SPLINE_ENABLED);
#undef REMOVE_VIOLATING_FLAGS
#undef REMOVE_VIOLATING_FLAGS
}
void WorldSession::WriteMovementInfo(WorldPacket* data, MovementInfo* mi)
@@ -946,14 +950,14 @@ void WorldSession::WriteMovementInfo(WorldPacket* data, MovementInfo* mi)
if (mi->HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
{
data->appendPackGUID(mi->transport.guid);
data->appendPackGUID(mi->transport.guid);
*data << mi->transport.pos.PositionXYZOStream();
*data << mi->transport.time;
*data << mi->transport.seat;
*data << mi->transport.pos.PositionXYZOStream();
*data << mi->transport.time;
*data << mi->transport.seat;
if (mi->HasExtraMovementFlag(MOVEMENTFLAG2_INTERPOLATED_MOVEMENT))
*data << mi->transport.time2;
if (mi->HasExtraMovementFlag(MOVEMENTFLAG2_INTERPOLATED_MOVEMENT))
*data << mi->transport.time2;
}
if (mi->HasMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || mi->HasExtraMovementFlag(MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING))
@@ -1126,7 +1130,7 @@ void WorldSession::SendAddonsInfo()
data << uint32(bannedAddons->size());
for (AddonMgr::BannedAddonList::const_iterator itr = bannedAddons->begin(); itr != bannedAddons->end(); ++itr)
{
data << uint32(itr->Id);
data << uint32(itr->Id);
data.append(itr->NameMD5, sizeof(itr->NameMD5));
data.append(itr->VersionMD5, sizeof(itr->VersionMD5));
data << uint32(itr->Timestamp);
@@ -1282,7 +1286,7 @@ void WorldSession::ProcessQueryCallbackPet()
_loadPetFromDBSecondCallback.get(param);
HandleLoadPetFromDBSecondCallback((LoadPetFromDBQueryHolder*)param);
delete param;
_loadPetFromDBSecondCallback.cancel();
_loadPetFromDBSecondCallback.cancel();
}
return;
}
@@ -1331,3 +1335,299 @@ void WorldSession::InitWarden(BigNumber* k, std::string const& os)
// _warden->Init(this, k);
}
}
bool WorldSession::DosProtection::EvaluateOpcode(WorldPacket& p, time_t time) const
{
uint32 maxPacketCounterAllowed = GetMaxPacketCounterAllowed(p.GetOpcode());
// Return true if there no limit for the opcode
if (!maxPacketCounterAllowed)
return true;
PacketCounter& packetCounter = _PacketThrottlingMap[p.GetOpcode()];
if (packetCounter.lastReceiveTime != time)
{
packetCounter.lastReceiveTime = time;
packetCounter.amountCounter = 0;
}
// Check if player is flooding some packets
if (++packetCounter.amountCounter <= maxPacketCounterAllowed)
return true;
sLog->outString("AntiDOS: Account %u, IP: %s, Ping: %u, Character %s, flooding packet (opc: %s (0x%X), count: %u)",
Session->GetAccountId(), Session->GetRemoteAddress().c_str(), Session->GetLatency(),
Session->GetPlayerName().c_str(), opcodeTable[p.GetOpcode()].name, p.GetOpcode(), packetCounter.amountCounter);
switch (_policy)
{
case POLICY_LOG:
return true;
case POLICY_KICK:
{
sLog->outString("AntiDOS: Player %s kicked!", Session->GetPlayerName().c_str());
Session->KickPlayer();
return false;
}
case POLICY_BAN:
{
uint32 bm = sWorld->getIntConfig(CONFIG_PACKET_SPOOF_BANMODE);
uint32 duration = sWorld->getIntConfig(CONFIG_PACKET_SPOOF_BANDURATION); // in seconds
std::string nameOrIp = "";
switch (bm)
{
case 0: // Ban account
(void)AccountMgr::GetName(Session->GetAccountId(), nameOrIp);
sBan->BanAccount(nameOrIp, std::to_string(duration), "DOS (Packet Flooding/Spoofing", "Server: AutoDOS");
break;
case 1: // Ban ip
nameOrIp = Session->GetRemoteAddress();
sBan->BanIP(nameOrIp, std::to_string(duration), "DOS (Packet Flooding/Spoofing", "Server: AutoDOS");
break;
}
sLog->outString("AntiDOS: Player automatically banned for %u seconds.", duration);
return false;
}
default: // invalid policy
return true;
}
}
uint32 WorldSession::DosProtection::GetMaxPacketCounterAllowed(uint16 opcode) const
{
uint32 maxPacketCounterAllowed;
switch (opcode)
{
// CPU usage sending 2000 packets/second on a 3.70 GHz 4 cores on Win x64
// [% CPU mysqld] [%CPU worldserver RelWithDebInfo]
case CMSG_PLAYER_LOGIN: // 0 0.5
case CMSG_NAME_QUERY: // 0 1
case CMSG_PET_NAME_QUERY: // 0 1
case CMSG_NPC_TEXT_QUERY: // 0 1
case CMSG_ATTACKSTOP: // 0 1
case CMSG_QUERY_QUESTS_COMPLETED: // 0 1
case CMSG_QUERY_TIME: // 0 1
case CMSG_CORPSE_MAP_POSITION_QUERY: // 0 1
case CMSG_MOVE_TIME_SKIPPED: // 0 1
case MSG_QUERY_NEXT_MAIL_TIME: // 0 1
case CMSG_SETSHEATHED: // 0 1
case MSG_RAID_TARGET_UPDATE: // 0 1
case CMSG_PLAYER_LOGOUT: // 0 1
case CMSG_LOGOUT_REQUEST: // 0 1
case CMSG_PET_RENAME: // 0 1
case CMSG_QUESTGIVER_CANCEL: // 0 1
case CMSG_QUESTGIVER_REQUEST_REWARD: // 0 1
case CMSG_COMPLETE_CINEMATIC: // 0 1
case CMSG_BANKER_ACTIVATE: // 0 1
case CMSG_BUY_BANK_SLOT: // 0 1
case CMSG_OPT_OUT_OF_LOOT: // 0 1
case CMSG_DUEL_ACCEPTED: // 0 1
case CMSG_DUEL_CANCELLED: // 0 1
case CMSG_CALENDAR_COMPLAIN: // 0 1
case CMSG_QUEST_QUERY: // 0 1.5
case CMSG_ITEM_QUERY_SINGLE: // 0 1.5
case CMSG_ITEM_NAME_QUERY: // 0 1.5
case CMSG_GAMEOBJECT_QUERY: // 0 1.5
case CMSG_CREATURE_QUERY: // 0 1.5
case CMSG_QUESTGIVER_STATUS_QUERY: // 0 1.5
case CMSG_GUILD_QUERY: // 0 1.5
case CMSG_ARENA_TEAM_QUERY: // 0 1.5
case CMSG_TAXINODE_STATUS_QUERY: // 0 1.5
case CMSG_TAXIQUERYAVAILABLENODES: // 0 1.5
case CMSG_QUESTGIVER_QUERY_QUEST: // 0 1.5
case CMSG_PAGE_TEXT_QUERY: // 0 1.5
case MSG_QUERY_GUILD_BANK_TEXT: // 0 1.5
case MSG_CORPSE_QUERY: // 0 1.5
case MSG_MOVE_SET_FACING: // 0 1.5
case CMSG_REQUEST_PARTY_MEMBER_STATS: // 0 1.5
case CMSG_QUESTGIVER_COMPLETE_QUEST: // 0 1.5
case CMSG_SET_ACTION_BUTTON: // 0 1.5
case CMSG_RESET_INSTANCES: // 0 1.5
case CMSG_HEARTH_AND_RESURRECT: // 0 1.5
case CMSG_TOGGLE_PVP: // 0 1.5
case CMSG_PET_ABANDON: // 0 1.5
case CMSG_ACTIVATETAXIEXPRESS: // 0 1.5
case CMSG_ACTIVATETAXI: // 0 1.5
case CMSG_SELF_RES: // 0 1.5
case CMSG_UNLEARN_SKILL: // 0 1.5
case CMSG_EQUIPMENT_SET_SAVE: // 0 1.5
case CMSG_DELETEEQUIPMENT_SET: // 0 1.5
case CMSG_DISMISS_CRITTER: // 0 1.5
case CMSG_REPOP_REQUEST: // 0 1.5
case CMSG_GROUP_INVITE: // 0 1.5
case CMSG_GROUP_DECLINE: // 0 1.5
case CMSG_GROUP_ACCEPT: // 0 1.5
case CMSG_GROUP_UNINVITE_GUID: // 0 1.5
case CMSG_GROUP_UNINVITE: // 0 1.5
case CMSG_GROUP_DISBAND: // 0 1.5
case CMSG_BATTLEMASTER_JOIN_ARENA: // 0 1.5
case CMSG_LEAVE_BATTLEFIELD: // 0 1.5
case MSG_GUILD_BANK_LOG_QUERY: // 0 2
case CMSG_LOGOUT_CANCEL: // 0 2
case CMSG_REALM_SPLIT: // 0 2
case CMSG_ALTER_APPEARANCE: // 0 2
case CMSG_QUEST_CONFIRM_ACCEPT: // 0 2
case MSG_GUILD_EVENT_LOG_QUERY: // 0 2.5
case CMSG_READY_FOR_ACCOUNT_DATA_TIMES: // 0 2.5
case CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY: // 0 2.5
case CMSG_BEGIN_TRADE: // 0 2.5
case CMSG_INITIATE_TRADE: // 0 3
case CMSG_MESSAGECHAT: // 0 3.5
case CMSG_INSPECT: // 0 3.5
case CMSG_AREA_SPIRIT_HEALER_QUERY: // not profiled
case CMSG_STANDSTATECHANGE: // not profiled
case MSG_RANDOM_ROLL: // not profiled
case CMSG_TIME_SYNC_RESP: // not profiled
case CMSG_TRAINER_BUY_SPELL: // not profiled
case CMSG_FORCE_RUN_SPEED_CHANGE_ACK: // not profiled
{
// "0" is a magic number meaning there's no limit for the opcode.
// All the opcodes above must cause little CPU usage and no sync/async database queries at all
maxPacketCounterAllowed = 0;
break;
}
case CMSG_QUESTGIVER_ACCEPT_QUEST: // 0 4
case CMSG_QUESTLOG_REMOVE_QUEST: // 0 4
case CMSG_QUESTGIVER_CHOOSE_REWARD: // 0 4
case CMSG_CONTACT_LIST: // 0 5
case CMSG_LEARN_PREVIEW_TALENTS: // 0 6
case CMSG_AUTOBANK_ITEM: // 0 6
case CMSG_AUTOSTORE_BANK_ITEM: // 0 6
case CMSG_WHO: // 0 7
case CMSG_PLAYER_VEHICLE_ENTER: // 0 8
case CMSG_LEARN_PREVIEW_TALENTS_PET: // not profiled
case MSG_MOVE_HEARTBEAT:
{
maxPacketCounterAllowed = 200;
break;
}
case CMSG_GUILD_SET_PUBLIC_NOTE: // 1 2 1 async db query
case CMSG_GUILD_SET_OFFICER_NOTE: // 1 2 1 async db query
case CMSG_SET_CONTACT_NOTES: // 1 2.5 1 async db query
case CMSG_CALENDAR_GET_CALENDAR: // 0 1.5 medium upload bandwidth usage
case CMSG_GUILD_BANK_QUERY_TAB: // 0 3.5 medium upload bandwidth usage
case CMSG_QUERY_INSPECT_ACHIEVEMENTS: // 0 13 high upload bandwidth usage
case CMSG_GAMEOBJ_REPORT_USE: // not profiled
case CMSG_GAMEOBJ_USE: // not profiled
case MSG_PETITION_DECLINE: // not profiled
{
maxPacketCounterAllowed = 50;
break;
}
case CMSG_QUEST_POI_QUERY: // 0 25 very high upload bandwidth usage
{
maxPacketCounterAllowed = MAX_QUEST_LOG_SIZE;
break;
}
case CMSG_GM_REPORT_LAG: // 1 3 1 async db query
case CMSG_SPELLCLICK: // not profiled
case CMSG_REMOVE_GLYPH: // not profiled
case CMSG_DISMISS_CONTROLLED_VEHICLE: // not profiled
{
maxPacketCounterAllowed = 20;
break;
}
case CMSG_PETITION_SIGN: // 9 4 2 sync 1 async db queries
case CMSG_TURN_IN_PETITION: // 8 5.5 2 sync db query
case CMSG_GROUP_CHANGE_SUB_GROUP: // 6 5 1 sync 1 async db queries
case CMSG_PETITION_QUERY: // 4 3.5 1 sync db query
case CMSG_CHAR_RACE_CHANGE: // 5 4 1 sync db query
case CMSG_CHAR_CUSTOMIZE: // 5 5 1 sync db query
case CMSG_CHAR_FACTION_CHANGE: // 5 5 1 sync db query
case CMSG_CHAR_DELETE: // 4 4 1 sync db query
case CMSG_DEL_FRIEND: // 7 5 1 async db query
case CMSG_ADD_FRIEND: // 6 4 1 async db query
case CMSG_CHAR_RENAME: // 5 3 1 async db query
case CMSG_GMSURVEY_SUBMIT: // 2 3 1 async db query
case CMSG_BUG: // 1 1 1 async db query
case CMSG_GROUP_SET_LEADER: // 1 2 1 async db query
case CMSG_GROUP_RAID_CONVERT: // 1 5 1 async db query
case CMSG_GROUP_ASSISTANT_LEADER: // 1 2 1 async db query
case CMSG_PETITION_BUY: // not profiled 1 sync 1 async db queries
case CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE: // not profiled
case CMSG_REQUEST_VEHICLE_PREV_SEAT: // not profiled
case CMSG_REQUEST_VEHICLE_NEXT_SEAT: // not profiled
case CMSG_REQUEST_VEHICLE_SWITCH_SEAT: // not profiled
case CMSG_REQUEST_VEHICLE_EXIT: // not profiled
case CMSG_CONTROLLER_EJECT_PASSENGER: // not profiled
case CMSG_ITEM_REFUND: // not profiled
case CMSG_SOCKET_GEMS: // not profiled
case CMSG_WRAP_ITEM: // not profiled
case CMSG_REPORT_PVP_AFK: // not profiled
{
maxPacketCounterAllowed = 10;
break;
}
case CMSG_CHAR_CREATE: // 7 5 3 async db queries
case CMSG_CHAR_ENUM: // 22 3 2 async db queries
case CMSG_GMTICKET_CREATE: // 1 25 1 async db query
case CMSG_GMTICKET_UPDATETEXT: // 0 15 1 async db query
case CMSG_GMTICKET_DELETETICKET: // 1 25 1 async db query
case CMSG_GMRESPONSE_RESOLVE: // 1 25 1 async db query
case CMSG_CALENDAR_ADD_EVENT: // 21 10 2 async db query
case CMSG_CALENDAR_UPDATE_EVENT: // not profiled
case CMSG_CALENDAR_REMOVE_EVENT: // not profiled
case CMSG_CALENDAR_COPY_EVENT: // not profiled
case CMSG_CALENDAR_EVENT_INVITE: // not profiled
case CMSG_CALENDAR_EVENT_SIGNUP: // not profiled
case CMSG_CALENDAR_EVENT_RSVP: // not profiled
case CMSG_CALENDAR_EVENT_REMOVE_INVITE: // not profiled
case CMSG_CALENDAR_EVENT_MODERATOR_STATUS: // not profiled
case CMSG_ARENA_TEAM_INVITE: // not profiled
case CMSG_ARENA_TEAM_ACCEPT: // not profiled
case CMSG_ARENA_TEAM_DECLINE: // not profiled
case CMSG_ARENA_TEAM_LEAVE: // not profiled
case CMSG_ARENA_TEAM_DISBAND: // not profiled
case CMSG_ARENA_TEAM_REMOVE: // not profiled
case CMSG_ARENA_TEAM_LEADER: // not profiled
case CMSG_LOOT_METHOD: // not profiled
case CMSG_GUILD_INVITE: // not profiled
case CMSG_GUILD_ACCEPT: // not profiled
case CMSG_GUILD_DECLINE: // not profiled
case CMSG_GUILD_LEAVE: // not profiled
case CMSG_GUILD_DISBAND: // not profiled
case CMSG_GUILD_LEADER: // not profiled
case CMSG_GUILD_MOTD: // not profiled
case CMSG_GUILD_RANK: // not profiled
case CMSG_GUILD_ADD_RANK: // not profiled
case CMSG_GUILD_DEL_RANK: // not profiled
case CMSG_GUILD_INFO_TEXT: // not profiled
case CMSG_GUILD_BANK_DEPOSIT_MONEY: // not profiled
case CMSG_GUILD_BANK_WITHDRAW_MONEY: // not profiled
case CMSG_GUILD_BANK_BUY_TAB: // not profiled
case CMSG_GUILD_BANK_UPDATE_TAB: // not profiled
case CMSG_SET_GUILD_BANK_TEXT: // not profiled
case MSG_SAVE_GUILD_EMBLEM: // not profiled
case MSG_PETITION_RENAME: // not profiled
case MSG_TALENT_WIPE_CONFIRM: // not profiled
case MSG_SET_DUNGEON_DIFFICULTY: // not profiled
case MSG_SET_RAID_DIFFICULTY: // not profiled
case MSG_PARTY_ASSIGNMENT: // not profiled
case MSG_RAID_READY_CHECK: // not profiled
{
maxPacketCounterAllowed = 3;
break;
}
case CMSG_ITEM_REFUND_INFO: // not profiled
{
maxPacketCounterAllowed = PLAYER_SLOTS_COUNT;
break;
}
default:
{
maxPacketCounterAllowed = 100;
break;
}
}
return maxPacketCounterAllowed;
}