Update PINFO command, show character details like TrinityCore. (#1097)

Closes #1067
This commit is contained in:
Amin.MasterkinG
2018-12-12 08:38:12 +03:30
committed by Nefertumm
parent 8906d1ea26
commit 8c753dc04e
6 changed files with 264 additions and 123 deletions

View File

@@ -1785,7 +1785,8 @@ public:
Player* target;
uint64 targetGuid;
std::string targetName;
PreparedStatement* stmt = nullptr;
uint32 parseGUID = MAKE_NEW_GUID(atol((char*)args), 0, HIGHGUID_PLAYER);
if (sObjectMgr->GetPlayerNameByGUID(parseGUID, targetName))
@@ -1796,35 +1797,57 @@ public:
else if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
return false;
uint32 accId = 0;
uint32 money = 0;
uint32 totalPlayerTime = 0;
uint8 level = 0;
uint32 latency = 0;
uint8 race;
uint8 Class;
int64 muteTime = 0;
int64 banTime = -1;
// Account data print variables
std::string userName = handler->GetTrinityString(LANG_ERROR);
uint32 accId = 0;
std::string eMail = handler->GetTrinityString(LANG_ERROR);
std::string regMail = handler->GetTrinityString(LANG_ERROR);
uint32 security = 0;
std::string lastIp = handler->GetTrinityString(LANG_ERROR);
uint8 locked = 0;
std::string lastLogin = handler->GetTrinityString(LANG_ERROR);
uint32 failedLogins = 0;
uint32 latency = 0;
std::string OS = handler->GetTrinityString(LANG_UNKNOWN);
// Mute data print variables
int64 muteTime = -1;
std::string muteReason = handler->GetTrinityString(LANG_NO_REASON);
std::string muteBy = handler->GetTrinityString(LANG_UNKNOWN);
// Ban data print variables
int64 banTime = -1;
std::string banType = handler->GetTrinityString(LANG_UNKNOWN);
std::string banReason = handler->GetTrinityString(LANG_NO_REASON);
std::string bannedBy = handler->GetTrinityString(LANG_UNKNOWN);
// Character data print variables
uint8 raceid, classid = 0; //RACE_NONE, CLASS_NONE
std::string raceStr, classStr = handler->GetTrinityString(LANG_UNKNOWN);
uint8 gender = 0;
int8 locale = handler->GetSessionDbcLocale();
uint32 totalPlayerTime = 0;
uint8 level = 0;
std::string alive = handler->GetTrinityString(LANG_ERROR);
uint32 money = 0;
uint32 xp = 0;
uint32 xptotal = 0;
// Position data print
uint32 mapId;
uint32 areaId;
uint32 phase = 0;
// pussywizard: guild info
std::string guildName = "";
bool guildIsLeader = false;
uint64 guildMoney = 0;
uint32 guildMemberCount = 0;
if (const GlobalPlayerData* gpd = sWorld->GetGlobalPlayerData(targetGuid))
if (gpd->guildId)
if (Guild* targetGuild = sGuildMgr->GetGuildById(gpd->guildId))
{
guildName = targetGuild->GetName();
guildMoney = targetGuild->GetTotalBankMoney();
guildMemberCount = targetGuild->GetMemberCount();
if (targetGuild->GetLeaderGUID() == targetGuid)
guildIsLeader = true;
}
char const* areaName = nullptr;
char const* zoneName = nullptr;
// Guild data print variables defined so that they exist, but are not necessarily used
uint32 guildId = 0;
uint8 guildRankId = 0;
std::string guildName;
std::string guildRank;
std::string note;
std::string officeNote;
// get additional information from Player object
if (target)
{
@@ -1837,11 +1860,13 @@ public:
totalPlayerTime = target->GetTotalPlayedTime();
level = target->getLevel();
latency = target->GetSession()->GetLatency();
race = target->getRace();
Class = target->getClass();
raceid = target->getRace();
classid = target->getClass();
muteTime = target->GetSession()->m_muteTime;
mapId = target->GetMapId();
areaId = target->GetAreaId();
alive = target->IsAlive() ? handler->GetTrinityString(LANG_YES) : handler->GetTrinityString(LANG_NO);
gender = target->getGender();
phase = target->GetPhaseMask();
}
// get additional information from DB
@@ -1851,33 +1876,35 @@ public:
if (handler->HasLowerSecurity(nullptr, targetGuid))
return false;
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PINFO);
// Query informations from the DB
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PINFO);
stmt->setUInt32(0, GUID_LOPART(targetGuid));
PreparedQueryResult result = CharacterDatabase.Query(stmt);
if (!result)
return false;
Field* fields = result->Fetch();
totalPlayerTime = fields[0].GetUInt32();
level = fields[1].GetUInt8();
money = fields[2].GetUInt32();
accId = fields[3].GetUInt32();
race = fields[4].GetUInt8();
Class = fields[5].GetUInt8();
mapId = fields[6].GetUInt16();
areaId = fields[7].GetUInt16();
Field* fields = result->Fetch();
totalPlayerTime = fields[0].GetUInt32();
level = fields[1].GetUInt8();
money = fields[2].GetUInt32();
accId = fields[3].GetUInt32();
raceid = fields[4].GetUInt8();
classid = fields[5].GetUInt8();
mapId = fields[6].GetUInt16();
areaId = fields[7].GetUInt16();
gender = fields[8].GetUInt8();
uint32 health = fields[9].GetUInt32();
uint32 playerFlags = fields[10].GetUInt32();
if (!health || playerFlags & PLAYER_FLAGS_GHOST)
alive = handler->GetTrinityString(LANG_NO);
else
alive = handler->GetTrinityString(LANG_YES);
}
std::string userName = handler->GetTrinityString(LANG_ERROR);
std::string eMail = handler->GetTrinityString(LANG_ERROR);
std::string muteReason = "";
std::string muteBy = "";
std::string lastIp = handler->GetTrinityString(LANG_ERROR);
uint32 security = 0;
std::string lastLogin = handler->GetTrinityString(LANG_ERROR);
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO);
// Query the prepared statement for login data
stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO);
stmt->setInt32(0, int32(realmID));
stmt->setUInt32(1, accId);
PreparedQueryResult result = LoginDatabase.Query(stmt);
@@ -1887,24 +1914,27 @@ public:
Field* fields = result->Fetch();
userName = fields[0].GetString();
security = fields[1].GetUInt8();
eMail = fields[2].GetString();
muteTime = fields[5].GetUInt64();
muteReason = fields[6].GetString();
muteBy = fields[7].GetString();
if (eMail.empty())
eMail = "-";
// Only fetch these fields if commander has sufficient rights)
if (!handler->GetSession() || handler->GetSession()->GetSecurity() >= AccountTypes(security))
{
lastIp = fields[3].GetString();
lastLogin = fields[4].GetString();
eMail = fields[2].GetString();
regMail = fields[3].GetString();
lastIp = fields[4].GetString();
lastLogin = fields[5].GetString();
uint32 ip = inet_addr(lastIp.c_str());
/** if (IpLocationRecord const* location = sIPLocation->GetLocationRecord(lastIp))
{
lastIp.append(" (");
lastIp.append(location->CountryName);
lastIp.append(")");
} **/
uint32 ip = inet_addr(lastIp.c_str());
#if TRINITY_ENDIAN == BIGENDIAN
EndianConvertReverse(ip);
#endif
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP2NATION_COUNTRY);
stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP2NATION_COUNTRY);
stmt->setUInt32(0, ip);
@@ -1920,23 +1950,29 @@ public:
}
else
{
lastIp = "-";
lastLogin = "-";
eMail = handler->GetTrinityString(LANG_UNAUTHORIZED);
regMail = handler->GetTrinityString(LANG_UNAUTHORIZED);
lastIp = handler->GetTrinityString(LANG_UNAUTHORIZED);
lastLogin = handler->GetTrinityString(LANG_UNAUTHORIZED);
}
muteTime = fields[6].GetUInt64();
muteReason = fields[7].GetString();
muteBy = fields[8].GetString();
failedLogins = fields[9].GetUInt32();
locked = fields[10].GetUInt8();
OS = fields[11].GetString();
}
// Creates a chat link to the character. Returns nameLink
std::string nameLink = handler->playerLink(targetName);
handler->PSendSysMessage(LANG_PINFO_ACCOUNT, (target ? "" : handler->GetTrinityString(LANG_OFFLINE)), nameLink.c_str(), GUID_LOPART(targetGuid), userName.c_str(), accId, eMail.c_str(), security, lastIp.c_str(), lastLogin.c_str(), latency);
std::string bannedby = "unknown";
std::string banreason = "";
stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO_BANS);
stmt->setUInt32(0, accId);
PreparedQueryResult result2 = LoginDatabase.Query(stmt);
// Returns banType, banTime, bannedBy, banreason
PreparedStatement* stmt2 = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO_BANS);
stmt2->setUInt32(0, accId);
PreparedQueryResult result2 = LoginDatabase.Query(stmt2);
if (!result2)
{
banType = handler->GetTrinityString(LANG_CHARACTER);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PINFO_BANS);
stmt->setUInt32(0, GUID_LOPART(targetGuid));
result2 = CharacterDatabase.Query(stmt);
@@ -1946,18 +1982,49 @@ public:
{
Field* fields = result2->Fetch();
banTime = int64(fields[1].GetUInt64() ? 0 : fields[0].GetUInt32());
bannedby = fields[2].GetString();
banreason = fields[3].GetString();
bannedBy = fields[2].GetString();
banReason = fields[3].GetString();
}
if (muteTime > 0 && muteTime > time(nullptr))
handler->PSendSysMessage(LANG_PINFO_MUTE, secsToTimeString(muteTime - time(nullptr), true).c_str(), muteBy.c_str(), muteReason.c_str());
// Initiate output
// Output I. LANG_PINFO_PLAYER
handler->PSendSysMessage(LANG_PINFO_PLAYER, target ? "" : handler->GetTrinityString(LANG_OFFLINE), nameLink.c_str(), GUID_LOPART(targetGuid));
// Output II. LANG_PINFO_GM_ACTIVE if character is gamemaster
if (target && target->IsGameMaster())
handler->PSendSysMessage(LANG_PINFO_GM_ACTIVE);
// Output III. LANG_PINFO_BANNED if ban exists and is applied
if (banTime >= 0)
handler->PSendSysMessage(LANG_PINFO_BAN, banTime > 0 ? secsToTimeString(banTime - time(nullptr), true).c_str() : "permanently", bannedby.c_str(), banreason.c_str());
handler->PSendSysMessage(LANG_PINFO_BANNED, banType.c_str(), banReason.c_str(), banTime > 0 ? secsToTimeString(banTime - time(nullptr), true).c_str() : handler->GetTrinityString(LANG_PERMANENTLY), bannedBy.c_str());
// Output IV. LANG_PINFO_MUTED if mute is applied
if (muteTime > 0)
handler->PSendSysMessage(LANG_PINFO_MUTED, muteReason.c_str(), secsToTimeString(muteTime - time(nullptr), true).c_str(), muteBy.c_str());
std::string raceStr, ClassStr;
switch (race)
// Output V. LANG_PINFO_ACC_ACCOUNT
handler->PSendSysMessage(LANG_PINFO_ACC_ACCOUNT, userName.c_str(), accId, security);
// Output VI. LANG_PINFO_ACC_LASTLOGIN
handler->PSendSysMessage(LANG_PINFO_ACC_LASTLOGIN, lastLogin.c_str(), failedLogins);
// Output VII. LANG_PINFO_ACC_OS
handler->PSendSysMessage(LANG_PINFO_ACC_OS, OS.c_str(), latency);
// Output VIII. LANG_PINFO_ACC_REGMAILS
handler->PSendSysMessage(LANG_PINFO_ACC_REGMAILS, regMail.c_str(), eMail.c_str());
// Output IX. LANG_PINFO_ACC_IP
handler->PSendSysMessage(LANG_PINFO_ACC_IP, lastIp.c_str(), locked ? handler->GetTrinityString(LANG_YES) : handler->GetTrinityString(LANG_NO));
// Output X. LANG_PINFO_CHR_LEVEL
if (level != sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
handler->PSendSysMessage(LANG_PINFO_CHR_LEVEL_LOW, level, xp, xptotal, (xptotal - xp));
else
handler->PSendSysMessage(LANG_PINFO_CHR_LEVEL_HIGH, level);
// Output XI. LANG_PINFO_CHR_RACE
switch (raceid)
{
case RACE_HUMAN:
raceStr = "Human";
@@ -1991,79 +2058,107 @@ public:
break;
}
switch (Class)
switch (classid)
{
case CLASS_WARRIOR:
ClassStr = "Warrior";
classStr = "Warrior";
break;
case CLASS_PALADIN:
ClassStr = "Paladin";
classStr = "Paladin";
break;
case CLASS_HUNTER:
ClassStr = "Hunter";
classStr = "Hunter";
break;
case CLASS_ROGUE:
ClassStr = "Rogue";
classStr = "Rogue";
break;
case CLASS_PRIEST:
ClassStr = "Priest";
classStr = "Priest";
break;
case CLASS_DEATH_KNIGHT:
ClassStr = "Death Knight";
classStr = "Death Knight";
break;
case CLASS_SHAMAN:
ClassStr = "Shaman";
classStr = "Shaman";
break;
case CLASS_MAGE:
ClassStr = "Mage";
classStr = "Mage";
break;
case CLASS_WARLOCK:
ClassStr = "Warlock";
classStr = "Warlock";
break;
case CLASS_DRUID:
ClassStr = "Druid";
classStr = "Druid";
break;
}
handler->PSendSysMessage(LANG_PINFO_CHR_RACE, (gender == 0 ? handler->GetTrinityString(LANG_CHARACTER_GENDER_MALE) : handler->GetTrinityString(LANG_CHARACTER_GENDER_FEMALE)), raceStr.c_str(), classStr.c_str());
std::string timeStr = secsToTimeString(totalPlayerTime, true);
uint32 gold = money /GOLD;
uint32 silv = (money % GOLD) / SILVER;
uint32 copp = (money % GOLD) % SILVER;
handler->PSendSysMessage(LANG_PINFO_LEVEL, raceStr.c_str(), ClassStr.c_str(), timeStr.c_str(), level, gold, silv, copp);
// Output XII. LANG_PINFO_CHR_ALIVE
handler->PSendSysMessage(LANG_PINFO_CHR_ALIVE, alive.c_str());
// Add map, zone, subzone and phase to output
int locale = handler->GetSessionDbcLocale();
std::string areaName = "<unknown>";
std::string zoneName = "";
// Output XIII. LANG_PINFO_CHR_PHASE if player is not in GM mode (GM is in every phase)
if (target && !target->IsGameMaster()) // IsInWorld() returns false on loadingscreen, so it's more
handler->PSendSysMessage(LANG_PINFO_CHR_PHASE, phase); // precise than just target (safer ?).
// However, as we usually just require a target here, we use target instead.
// Output XIV. LANG_PINFO_CHR_MONEY
uint32 gold = money / GOLD;
uint32 silv = (money % GOLD) / SILVER;
uint32 copp = (money % GOLD) % SILVER;
handler->PSendSysMessage(LANG_PINFO_CHR_MONEY, gold, silv, copp);
// Position data
MapEntry const* map = sMapStore.LookupEntry(mapId);
AreaTableEntry const* area = sAreaTableStore.LookupEntry(areaId);
if (area)
{
areaName = area->area_name[locale];
zoneName = area->area_name[locale];
AreaTableEntry const* zone = sAreaTableStore.LookupEntry(area->zone);
if (zone)
{
areaName = zoneName;
zoneName = zone->area_name[locale];
}
}
if (target)
{
if (!zoneName.empty())
handler->PSendSysMessage(LANG_PINFO_MAP_ONLINE, map->name[locale], zoneName.c_str(), areaName.c_str(), phase);
else
handler->PSendSysMessage(LANG_PINFO_MAP_ONLINE, map->name[locale], areaName.c_str(), "<unknown>", phase);
}
if (!zoneName)
zoneName = handler->GetTrinityString(LANG_UNKNOWN);
if (areaName)
handler->PSendSysMessage(LANG_PINFO_CHR_MAP_WITH_AREA, map->name[locale], zoneName, areaName);
else
handler->PSendSysMessage(LANG_PINFO_MAP_OFFLINE, map->name[locale], areaName.c_str());
handler->PSendSysMessage(LANG_PINFO_CHR_MAP, map->name[locale], zoneName);
// Output XVII. - XVIX. if they are not empty
if (!guildName.empty())
{
uint32 gold = guildMoney /GOLD;
uint32 silv = (guildMoney % GOLD) / SILVER;
uint32 copp = (guildMoney % GOLD) % SILVER;
handler->PSendSysMessage("Guild: %s, members: %u, gb money: %ug %us %uc, is guild leader: %s", guildName.c_str(), guildMemberCount, gold, silv, copp, guildIsLeader ? "yes" : "no");
handler->PSendSysMessage(LANG_PINFO_CHR_GUILD, guildName.c_str(), guildId);
handler->PSendSysMessage(LANG_PINFO_CHR_GUILD_RANK, guildRank.c_str(), uint32(guildRankId));
if (!note.empty())
handler->PSendSysMessage(LANG_PINFO_CHR_GUILD_NOTE, note.c_str());
if (!officeNote.empty())
handler->PSendSysMessage(LANG_PINFO_CHR_GUILD_ONOTE, officeNote.c_str());
}
// Output XX. LANG_PINFO_CHR_PLAYEDTIME
handler->PSendSysMessage(LANG_PINFO_CHR_PLAYEDTIME, (secsToTimeString(totalPlayerTime, true)).c_str());
// Mail Data - an own query, because it may or may not be useful.
// SQL: "SELECT SUM(CASE WHEN (checked & 1) THEN 1 ELSE 0 END) AS 'readmail', COUNT(*) AS 'totalmail' FROM mail WHERE `receiver` = ?"
PreparedStatement* stmt4 = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PINFO_MAILS);
stmt4->setUInt32(0, GUID_LOPART(targetGuid));
PreparedQueryResult result6 = CharacterDatabase.Query(stmt4);
if (result6)
{
Field* fields = result6->Fetch();
uint32 readmail = uint32(fields[0].GetDouble());
uint32 totalmail = uint32(fields[1].GetUInt64());
// Output XXI. LANG_INFO_CHR_MAILS if at least one mail is given
if (totalmail >= 1)
handler->PSendSysMessage(LANG_PINFO_CHR_MAILS, readmail, totalmail);
}
return true;