aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Handlers/MiscHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Handlers/MiscHandler.cpp')
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp244
1 files changed, 108 insertions, 136 deletions
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 6af14d53d50..c1045e63364 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -61,6 +61,7 @@
#include "ClientConfigPackets.h"
#include "MiscPackets.h"
#include "AchievementPackets.h"
+#include "WhoPackets.h"
void WorldSession::HandleRepopRequest(WorldPackets::Misc::RepopRequest& packet)
{
@@ -186,78 +187,63 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket& recvData)
}
}
-void WorldSession::HandleWhoOpcode(WorldPacket& recvData)
+void WorldSession::HandleWhoOpcode(WorldPackets::Who::WhoRequestPkt& whoRequest)
{
- TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_WHO Message");
+ WorldPackets::Who::WhoRequest& request = whoRequest.Request;
- uint32 matchcount = 0;
+ TC_LOG_DEBUG("network", "WorldSession::HandleWhoOpcode: MinLevel: %u, MaxLevel: %u, Name: %s (VirtualRealmName: %s), Guild: %s (GuildVirtualRealmName: %s), RaceFilter: %d, ClassFilter: %d, Areas: " SZFMTD ", Words: " SZFMTD ".",
+ request.MinLevel, request.MaxLevel, request.Name.c_str(), request.VirtualRealmName.c_str(), request.Guild.c_str(), request.GuildVirtualRealmName.c_str(),
+ request.RaceFilter, request.ClassFilter, whoRequest.Areas.size(), request.Words.size());
- uint32 level_min, level_max, racemask, classmask, zones_count, str_count;
- uint32 zoneids[10]; // 10 is client limit
- std::string player_name, guild_name;
-
- recvData >> level_min; // maximal player level, default 0
- recvData >> level_max; // minimal player level, default 100 (MAX_LEVEL)
- recvData >> player_name; // player name, case sensitive...
-
- recvData >> guild_name; // guild name, case sensitive...
-
- recvData >> racemask; // race mask
- recvData >> classmask; // class mask
- recvData >> zones_count; // zones count, client limit = 10 (2.0.10)
-
- if (zones_count > 10)
- return; // can't be received from real client or broken packet
-
- for (uint32 i = 0; i < zones_count; ++i)
- {
- uint32 temp;
- recvData >> temp; // zone id, 0 if zone is unknown...
- zoneids[i] = temp;
- TC_LOG_DEBUG("network", "Zone %u: %u", i, zoneids[i]);
- }
-
- recvData >> str_count; // user entered strings count, client limit=4 (checked on 2.0.10)
+ // zones count, client limit = 10 (2.0.10)
+ // can't be received from real client or broken packet
+ if (whoRequest.Areas.size() > 10)
+ return;
- if (str_count > 4)
- return; // can't be received from real client or broken packet
+ // user entered strings count, client limit=4 (checked on 2.0.10)
+ // can't be received from real client or broken packet
+ if (request.Words.size() > 4)
+ return;
- TC_LOG_DEBUG("network", "Minlvl %u, maxlvl %u, name %s, guild %s, racemask %u, classmask %u, zones %u, strings %u", level_min, level_max, player_name.c_str(), guild_name.c_str(), racemask, classmask, zones_count, str_count);
+ /// @todo: handle following packet values
+ /// VirtualRealmNames
+ /// ShowEnemies
+ /// ShowArenaPlayers
+ /// ExactName
+ /// ServerInfo
- std::wstring str[4]; // 4 is client limit
- for (uint32 i = 0; i < str_count; ++i)
+ std::vector<std::wstring> wWords;
+ wWords.resize(request.Words.size());
+ for (size_t i = 0; i < request.Words.size(); ++i)
{
- std::string temp;
- recvData >> temp; // user entered string, it used as universal search pattern(guild+player name)?
+ TC_LOG_DEBUG("network", "WorldSession::HandleWhoOpcode: Word: %s", request.Words[i].Word);
- if (!Utf8toWStr(temp, str[i]))
+ // user entered string, it used as universal search pattern(guild+player name)?
+ if (!Utf8toWStr(request.Words[i].Word, wWords[i]))
continue;
- wstrToLower(str[i]);
-
- TC_LOG_DEBUG("network", "String %u: %s", i, temp.c_str());
+ wstrToLower(wWords[i]);
}
- std::wstring wplayer_name;
- std::wstring wguild_name;
- if (!(Utf8toWStr(player_name, wplayer_name) && Utf8toWStr(guild_name, wguild_name)))
+ std::wstring wPlayerName;
+ std::wstring wGuildName;
+
+ if (!(Utf8toWStr(request.Name, wPlayerName) && Utf8toWStr(request.Guild, wGuildName)))
return;
- wstrToLower(wplayer_name);
- wstrToLower(wguild_name);
+
+ wstrToLower(wPlayerName);
+ wstrToLower(wGuildName);
// client send in case not set max level value 100 but Trinity supports 255 max level,
// update it to show GMs with characters after 100 level
- if (level_max >= MAX_LEVEL)
- level_max = STRONG_MAX_LEVEL;
+ if (whoRequest.Request.MaxLevel >= MAX_LEVEL)
+ whoRequest.Request.MaxLevel = STRONG_MAX_LEVEL;
uint32 team = _player->GetTeam();
uint32 gmLevelInWhoList = sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST);
- uint32 displaycount = 0;
- WorldPacket data(SMSG_WHO, 50); // guess size
- data << uint32(matchcount); // placeholder, count of players matching criteria
- data << uint32(displaycount); // placeholder, count of players displayed
+ WorldPackets::Who::WhoResponsePkt response;
boost::shared_lock<boost::shared_mutex> lock(*HashMapHolder<Player>::GetLock());
@@ -265,12 +251,12 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData)
for (HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr)
{
Player* target = itr->second;
- // player can see member of other team only if CONFIG_ALLOW_TWO_SIDE_WHO_LIST
+ // player can see member of other team only if has RBAC_PERM_TWO_SIDE_WHO_LIST
if (target->GetTeam() != team && !HasPermission(rbac::RBAC_PERM_TWO_SIDE_WHO_LIST))
continue;
- // player can see MODERATOR, GAME MASTER, ADMINISTRATOR only if CONFIG_GM_IN_WHO_LIST
- if (!HasPermission(rbac::RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS) && target->GetSession()->GetSecurity() > AccountTypes(gmLevelInWhoList))
+ // player can see MODERATOR, GAME MASTER, ADMINISTRATOR only if has RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS
+ if (target->GetSession()->GetSecurity() > AccountTypes(gmLevelInWhoList) && !HasPermission(rbac::RBAC_PERM_WHO_SEE_ALL_SEC_LEVELS))
continue;
// do not process players which are not in world
@@ -283,97 +269,92 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData)
// check if target's level is in level range
uint8 lvl = target->getLevel();
- if (lvl < level_min || lvl > level_max)
+ if (lvl < request.MinLevel || lvl > request.MaxLevel)
continue;
// check if class matches classmask
- uint8 class_ = target->getClass();
- if (!(classmask & (1 << class_)))
+ if (request.ClassFilter >= 0 && !(request.ClassFilter & (1 << target->getClass())))
continue;
// check if race matches racemask
- uint32 race = target->getRace();
- if (!(racemask & (1 << race)))
+ if (request.RaceFilter >= 0 && !(request.RaceFilter & (1 << target->getRace())))
continue;
- uint32 pzoneid = target->GetZoneId();
- uint8 gender = target->getGender();
-
- bool z_show = true;
- for (uint32 i = 0; i < zones_count; ++i)
+ if (!whoRequest.Areas.empty())
{
- if (zoneids[i] == pzoneid)
- {
- z_show = true;
- break;
- }
-
- z_show = false;
+ if (std::find(whoRequest.Areas.begin(), whoRequest.Areas.end(), target->GetZoneId()) == whoRequest.Areas.end())
+ continue;
}
- if (!z_show)
- continue;
- std::string pname = target->GetName();
- std::wstring wpname;
- if (!Utf8toWStr(pname, wpname))
- continue;
- wstrToLower(wpname);
+ std::wstring wTargetName;
- if (!(wplayer_name.empty() || wpname.find(wplayer_name) != std::wstring::npos))
+ if (!Utf8toWStr(target->GetName(), wTargetName))
continue;
- std::string gname = sGuildMgr->GetGuildNameById(target->GetGuildId());
- std::wstring wgname;
- if (!Utf8toWStr(gname, wgname))
+ wstrToLower(wTargetName);
+
+ if (!wPlayerName.empty() && wTargetName.find(wPlayerName) == std::wstring::npos)
continue;
- wstrToLower(wgname);
- if (!(wguild_name.empty() || wgname.find(wguild_name) != std::wstring::npos))
+ Guild* targetGuild = target->GetGuild();
+ std::wstring wTargetGuildName;
+
+ if (!Utf8toWStr(targetGuild ? targetGuild->GetName() : "", wTargetGuildName))
continue;
- std::string aname;
- if (AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(pzoneid))
- aname = areaEntry->ZoneName;
+ wstrToLower(wTargetGuildName);
+
+ if (!wGuildName.empty() && wTargetGuildName.find(wGuildName) == std::wstring::npos)
+ continue;
- bool s_show = true;
- for (uint32 i = 0; i < str_count; ++i)
+ if (!wWords.empty())
{
- if (!str[i].empty())
+ std::string aName;
+ if (AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(target->GetZoneId()))
+ aName = areaEntry->ZoneName;
+
+ bool show = false;
+ for (size_t i = 0; i < wWords.size(); ++i)
{
- if (wgname.find(str[i]) != std::wstring::npos ||
- wpname.find(str[i]) != std::wstring::npos ||
- Utf8FitTo(aname, str[i]))
+ if (!wWords[i].empty())
{
- s_show = true;
- break;
+ if (wTargetName.find(wWords[i]) != std::wstring::npos ||
+ wTargetGuildName.find(wWords[i]) != std::wstring::npos ||
+ Utf8FitTo(aName, wWords[i]))
+ {
+ show = true;
+ break;
+ }
}
- s_show = false;
}
+
+ if (!show)
+ continue;
}
- if (!s_show)
- continue;
- // 49 is maximum player count sent to client - can be overridden
- // through config, but is unstable
- if ((matchcount++) >= sWorld->getIntConfig(CONFIG_MAX_WHO))
+ WorldPackets::Who::WhoEntry whoEntry;
+ if (!whoEntry.PlayerData.Initialize(target->GetGUID(), target))
continue;
- data << pname; // player name
- data << gname; // guild name
- data << uint32(lvl); // player level
- data << uint32(class_); // player class
- data << uint32(race); // player race
- data << uint8(gender); // player gender
- data << uint32(pzoneid); // player zone id
+ if (targetGuild)
+ {
+ whoEntry.GuildGUID = targetGuild->GetGUID();
+ whoEntry.GuildVirtualRealmAddress = GetVirtualRealmAddress();
+ whoEntry.GuildName = targetGuild->GetName();
+ }
- ++displaycount;
- }
+ whoEntry.AreaID = target->GetZoneId();
+ whoEntry.IsGM = target->IsGameMaster();
- data.put(0, displaycount); // insert right count, count displayed
- data.put(4, matchcount); // insert right count, count of matches
+ response.Response.Entries.push_back(whoEntry);
- SendPacket(&data);
- TC_LOG_DEBUG("network", "WORLD: Send SMSG_WHO Message");
+ // 50 is maximum player count sent to client - can be overridden
+ // through config, but is unstable
+ if (response.Response.Entries.size() >= sWorld->getIntConfig(CONFIG_MAX_WHO))
+ break;
+ }
+
+ SendPacket(response.Write());
}
void WorldSession::HandleLogoutRequestOpcode(WorldPackets::Character::LogoutRequest& /*logoutRequest*/)
@@ -1217,11 +1198,10 @@ void WorldSession::HandleWorldTeleportOpcode(WorldPacket& recvData)
SendNotification(LANG_YOU_NOT_HAVE_PERMISSION);
}
-void WorldSession::HandleWhoisOpcode(WorldPacket& recvData)
+void WorldSession::HandleWhoisOpcode(WorldPackets::Who::WhoIsRequest& packet)
{
- TC_LOG_DEBUG("network", "Received opcode CMSG_WHOIS");
- std::string charname;
- recvData >> charname;
+ TC_LOG_DEBUG("network", "Received whois command from player %s for character %s",
+ GetPlayer()->GetName().c_str(), packet.CharName.c_str());
if (!HasPermission(rbac::RBAC_PERM_OPCODE_WHOIS))
{
@@ -1229,31 +1209,26 @@ void WorldSession::HandleWhoisOpcode(WorldPacket& recvData)
return;
}
- if (charname.empty() || !normalizePlayerName (charname))
+ if (packet.CharName.empty() || !normalizePlayerName(packet.CharName))
{
SendNotification(LANG_NEED_CHARACTER_NAME);
return;
}
- Player* player = ObjectAccessor::FindConnectedPlayerByName(charname);
-
+ Player* player = ObjectAccessor::FindConnectedPlayerByName(packet.CharName);
if (!player)
{
- SendNotification(LANG_PLAYER_NOT_EXIST_OR_OFFLINE, charname.c_str());
+ SendNotification(LANG_PLAYER_NOT_EXIST_OR_OFFLINE, packet.CharName.c_str());
return;
}
- uint32 accid = player->GetSession()->GetAccountId();
-
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_WHOIS);
-
- stmt->setUInt32(0, accid);
+ stmt->setUInt32(0, player->GetSession()->GetAccountId());
PreparedQueryResult result = LoginDatabase.Query(stmt);
-
if (!result)
{
- SendNotification(LANG_ACCOUNT_FOR_PLAYER_NOT_FOUND, charname.c_str());
+ SendNotification(LANG_ACCOUNT_FOR_PLAYER_NOT_FOUND, packet.CharName.c_str());
return;
}
@@ -1261,21 +1236,18 @@ void WorldSession::HandleWhoisOpcode(WorldPacket& recvData)
std::string acc = fields[0].GetString();
if (acc.empty())
acc = "Unknown";
+
std::string email = fields[1].GetString();
if (email.empty())
email = "Unknown";
+
std::string lastip = fields[2].GetString();
if (lastip.empty())
lastip = "Unknown";
- std::string msg = charname + "'s " + "account is " + acc + ", e-mail: " + email + ", last ip: " + lastip;
-
- WorldPacket data(SMSG_WHOIS, msg.size()+1);
- data << msg;
- SendPacket(&data);
-
- TC_LOG_DEBUG("network", "Received whois command from player %s for character %s",
- GetPlayer()->GetName().c_str(), charname.c_str());
+ WorldPackets::Who::WhoIsResponse response;
+ response.AccountName = packet.CharName + "'s " + "account is " + acc + ", e-mail: " + email + ", last ip: " + lastip;
+ SendPacket(response.Write());
}
void WorldSession::HandleComplainOpcode(WorldPacket& recvData)