/* * Copyright (C) 2008-2011 TrinityCore * Copyright (C) 2005-2009 MaNGOS * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "Common.h" #include "DatabaseEnv.h" #include "DBCStores.h" #include "ObjectMgr.h" #include "Player.h" #include "Item.h" #include "GameObject.h" #include "Opcodes.h" #include "Chat.h" #include "MapManager.h" #include "Language.h" #include "World.h" #include "GameEventMgr.h" #include "SpellMgr.h" #include "PoolMgr.h" #include "AccountMgr.h" #include "WaypointManager.h" #include "Util.h" #include #include #include #include #include "OutdoorPvPMgr.h" #include "Transport.h" #include "TargetedMovementGenerator.h" // for HandleNpcUnFollowCommand #include "CreatureGroups.h" //mute player for some times bool ChatHandler::HandleMuteCommand(const char* args) { char* nameStr; char* delayStr; extractOptFirstArg((char*)args, &nameStr, &delayStr); if (!delayStr) return false; char *mutereason = strtok(NULL, "\r"); std::string mutereasonstr = "No reason"; if (mutereason != NULL) mutereasonstr = mutereason; Player* target; uint64 target_guid; std::string target_name; if (!extractPlayerTarget(nameStr, &target, &target_guid, &target_name)) return false; uint32 accountId = target ? target->GetSession()->GetAccountId() : sObjectMgr->GetPlayerAccountIdByGUID(target_guid); // find only player from same account if any if (!target) if (WorldSession* session = sWorld->FindSession(accountId)) target = session->GetPlayer(); uint32 notspeaktime = (uint32) atoi(delayStr); // must have strong lesser security level if (HasLowerSecurity (target, target_guid, true)) return false; PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME); if (target) { // Target is online, mute will be in effect right away. int64 muteTime = time(NULL) + notspeaktime * MINUTE; target->GetSession()->m_muteTime = muteTime; stmt->setInt64(0, muteTime); ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notspeaktime, mutereasonstr.c_str()); } else { // Target is offline, mute will be in effect starting from the next login. int32 muteTime = -int32(notspeaktime * MINUTE); stmt->setInt64(0, muteTime); } stmt->setUInt32(1, accountId); LoginDatabase.Execute(stmt); std::string nameLink = playerLink(target_name); PSendSysMessage(target ? LANG_YOU_DISABLE_CHAT : LANG_COMMAND_DISABLE_CHAT_DELAYED, nameLink.c_str(), notspeaktime, mutereasonstr.c_str()); return true; } //unmute player bool ChatHandler::HandleUnmuteCommand(const char* args) { Player* target; uint64 target_guid; std::string target_name; if (!extractPlayerTarget((char*)args, &target, &target_guid, &target_name)) return false; uint32 accountId = target ? target->GetSession()->GetAccountId() : sObjectMgr->GetPlayerAccountIdByGUID(target_guid); // find only player from same account if any if (!target) if (WorldSession* session = sWorld->FindSession(accountId)) target = session->GetPlayer(); // must have strong lesser security level if (HasLowerSecurity (target, target_guid, true)) return false; if (target) { if (target->CanSpeak()) { SendSysMessage(LANG_CHAT_ALREADY_ENABLED); SetSentErrorMessage(true); return false; } target->GetSession()->m_muteTime = 0; } PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME); stmt->setInt64(0, 0); stmt->setUInt32(1, accountId); LoginDatabase.Execute(stmt); if (target) ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_ENABLED); std::string nameLink = playerLink(target_name); PSendSysMessage(LANG_YOU_ENABLE_CHAT, nameLink.c_str()); return true; } bool ChatHandler::HandleGUIDCommand(const char* /*args*/) { uint64 guid = m_session->GetPlayer()->GetSelection(); if (guid == 0) { SendSysMessage(LANG_NO_SELECTION); SetSentErrorMessage(true); return false; } PSendSysMessage(LANG_OBJECT_GUID, GUID_LOPART(guid), GUID_HIPART(guid)); return true; } //move item to other slot bool ChatHandler::HandleItemMoveCommand(const char* args) { if (!*args) return false; uint8 srcslot, dstslot; char* pParam1 = strtok((char*)args, " "); if (!pParam1) return false; char* pParam2 = strtok(NULL, " "); if (!pParam2) return false; srcslot = (uint8)atoi(pParam1); dstslot = (uint8)atoi(pParam2); if (srcslot == dstslot) return true; if (!m_session->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0, srcslot, true)) return false; if (!m_session->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0, dstslot, false)) return false; uint16 src = ((INVENTORY_SLOT_BAG_0 << 8) | srcslot); uint16 dst = ((INVENTORY_SLOT_BAG_0 << 8) | dstslot); m_session->GetPlayer()->SwapItem(src, dst); return true; } //demorph player or unit bool ChatHandler::HandleDeMorphCommand(const char* /*args*/) { Unit* target = getSelectedUnit(); if (!target) target = m_session->GetPlayer(); // check online security else if (target->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player*)target, 0)) return false; target->DeMorph(); return true; } //kick player bool ChatHandler::HandleKickPlayerCommand(const char *args) { Player* target = NULL; std::string playerName; if (!extractPlayerTarget((char*)args, &target, NULL, &playerName)) return false; if (m_session && target == m_session->GetPlayer()) { SendSysMessage(LANG_COMMAND_KICKSELF); SetSentErrorMessage(true); return false; } // check online security if (HasLowerSecurity(target, 0)) return false; if (sWorld->getBoolConfig(CONFIG_SHOW_KICK_IN_WORLD)) sWorld->SendWorldText(LANG_COMMAND_KICKMESSAGE, playerName.c_str()); else PSendSysMessage(LANG_COMMAND_KICKMESSAGE, playerName.c_str()); target->GetSession()->KickPlayer(); return true; } //show info of player bool ChatHandler::HandlePInfoCommand(const char* args) { Player* target; uint64 target_guid; std::string target_name; uint32 parseGUID = MAKE_NEW_GUID(atol((char*)args), 0, HIGHGUID_PLAYER); if (sObjectMgr->GetPlayerNameByGUID(parseGUID, target_name)) { target = sObjectMgr->GetPlayerByLowGUID(parseGUID); target_guid = parseGUID; } else if (!extractPlayerTarget((char*)args, &target, &target_guid, &target_name)) return false; uint32 accId = 0; uint32 money = 0; uint32 total_player_time = 0; uint8 level = 0; uint32 latency = 0; uint8 race; uint8 Class; int64 muteTime = 0; int64 banTime = -1; uint32 mapId; uint32 areaId; uint32 phase = 0; // get additional information from Player object if (target) { // check online security if (HasLowerSecurity(target, 0)) return false; accId = target->GetSession()->GetAccountId(); money = target->GetMoney(); total_player_time = target->GetTotalPlayedTime(); level = target->getLevel(); latency = target->GetSession()->GetLatency(); race = target->getRace(); Class = target->getClass(); muteTime = target->GetSession()->m_muteTime; mapId = target->GetMapId(); areaId = target->GetAreaId(); phase = target->GetPhaseMask(); } // get additional information from DB else { // check offline security if (HasLowerSecurity(NULL, target_guid)) return false; // 0 1 2 3 4 5 6 7 QueryResult result = CharacterDatabase.PQuery("SELECT totaltime, level, money, account, race, class, map, zone FROM characters " "WHERE guid = '%u'", GUID_LOPART(target_guid)); if (!result) return false; Field* fields = result->Fetch(); total_player_time = fields[0].GetUInt32(); level = fields[1].GetUInt32(); money = fields[2].GetUInt32(); accId = fields[3].GetUInt32(); race = fields[4].GetUInt8(); Class = fields[5].GetUInt8(); mapId = fields[6].GetUInt16(); areaId = fields[7].GetUInt16(); } std::string username = GetTrinityString(LANG_ERROR); std::string email = GetTrinityString(LANG_ERROR); std::string last_ip = GetTrinityString(LANG_ERROR); uint32 security = 0; std::string last_login = GetTrinityString(LANG_ERROR); QueryResult result = LoginDatabase.PQuery("SELECT a.username, aa.gmlevel, a.email, a.last_ip, a.last_login, a.mutetime " "FROM account a " "LEFT JOIN account_access aa " "ON (a.id = aa.id) " "WHERE a.id = '%u'", accId); if (result) { Field* fields = result->Fetch(); username = fields[0].GetString(); security = fields[1].GetUInt32(); email = fields[2].GetString(); muteTime = fields[5].GetUInt64(); if (email.empty()) email = "-"; if (!m_session || m_session->GetSecurity() >= AccountTypes(security)) { last_ip = fields[3].GetString(); last_login = fields[4].GetString(); } else { last_ip = "-"; last_login = "-"; } } std::string nameLink = playerLink(target_name); PSendSysMessage(LANG_PINFO_ACCOUNT, (target?"":GetTrinityString(LANG_OFFLINE)), nameLink.c_str(), GUID_LOPART(target_guid), username.c_str(), accId, email.c_str(), security, last_ip.c_str(), last_login.c_str(), latency); std::string bannedby = "unknown"; std::string banreason = ""; if (QueryResult result2 = LoginDatabase.PQuery("SELECT unbandate, bandate = unbandate, bannedby, banreason FROM account_banned " "WHERE id = '%u' AND active ORDER BY bandate ASC LIMIT 1", accId)) { Field* fields = result2->Fetch(); banTime = fields[1].GetBool() ? 0 : fields[0].GetUInt64(); bannedby = fields[2].GetString(); banreason = fields[3].GetString(); } else if (QueryResult result3 = CharacterDatabase.PQuery("SELECT unbandate, bandate = unbandate, bannedby, banreason FROM character_banned " "WHERE guid = '%u' AND active ORDER BY bandate ASC LIMIT 1", GUID_LOPART(target_guid))) { Field* fields = result3->Fetch(); banTime = fields[1].GetBool() ? 0 : fields[0].GetUInt64(); bannedby = fields[2].GetString(); banreason = fields[3].GetString(); } if (muteTime > 0) PSendSysMessage(LANG_PINFO_MUTE, secsToTimeString(muteTime - time(NULL), true).c_str()); if (banTime >= 0) PSendSysMessage(LANG_PINFO_BAN, banTime > 0 ? secsToTimeString(banTime - time(NULL), true).c_str() : "permanently", bannedby.c_str(), banreason.c_str()); std::string race_s, Class_s; switch (race) { case RACE_HUMAN: race_s = "Human"; break; case RACE_ORC: race_s = "Orc"; break; case RACE_DWARF: race_s = "Dwarf"; break; case RACE_NIGHTELF: race_s = "Night Elf"; break; case RACE_UNDEAD_PLAYER: race_s = "Undead"; break; case RACE_TAUREN: race_s = "Tauren"; break; case RACE_GNOME: race_s = "Gnome"; break; case RACE_TROLL: race_s = "Troll"; break; case RACE_BLOODELF: race_s = "Blood Elf"; break; case RACE_DRAENEI: race_s = "Draenei"; break; } switch (Class) { case CLASS_WARRIOR: Class_s = "Warrior"; break; case CLASS_PALADIN: Class_s = "Paladin"; break; case CLASS_HUNTER: Class_s = "Hunter"; break; case CLASS_ROGUE: Class_s = "Rogue"; break; case CLASS_PRIEST: Class_s = "Priest"; break; case CLASS_DEATH_KNIGHT: Class_s = "Death Knight"; break; case CLASS_SHAMAN: Class_s = "Shaman"; break; case CLASS_MAGE: Class_s = "Mage"; break; case CLASS_WARLOCK: Class_s = "Warlock"; break; case CLASS_DRUID: Class_s = "Druid"; break; } std::string timeStr = secsToTimeString(total_player_time, true, true); uint32 gold = money /GOLD; uint32 silv = (money % GOLD) / SILVER; uint32 copp = (money % GOLD) % SILVER; PSendSysMessage(LANG_PINFO_LEVEL, race_s.c_str(), Class_s.c_str(), timeStr.c_str(), level, gold, silv, copp); // Add map, zone, subzone and phase to output int locale = GetSessionDbcLocale(); std::string areaName = ""; std::string zoneName = ""; MapEntry const* map = sMapStore.LookupEntry(mapId); AreaTableEntry const* area = GetAreaEntryByAreaID(areaId); if (area) { areaName = area->area_name[locale]; AreaTableEntry const* zone = GetAreaEntryByAreaID(area->zone); if (zone) zoneName = zone->area_name[locale]; } if (target) { if (!zoneName.empty()) PSendSysMessage(LANG_PINFO_MAP_ONLINE, map->name[locale], zoneName.c_str(), areaName.c_str(), phase); else PSendSysMessage(LANG_PINFO_MAP_ONLINE, map->name[locale], areaName.c_str(), "", phase); } else PSendSysMessage(LANG_PINFO_MAP_OFFLINE, map->name[locale], areaName.c_str()); return true; } //rename characters bool ChatHandler::HandleCharacterRenameCommand(const char* args) { Player* target; uint64 targetGuid; std::string targetName; if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) return false; if (target) { // check online security if (HasLowerSecurity(target, 0)) return false; PSendSysMessage(LANG_RENAME_PLAYER, GetNameLink(target).c_str()); target->SetAtLoginFlag(AT_LOGIN_RENAME); } else { // check offline security if (HasLowerSecurity(NULL, targetGuid)) return false; std::string oldNameLink = playerLink(targetName); PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid)); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); stmt->setUInt16(0, uint16(AT_LOGIN_RENAME)); stmt->setUInt32(1, GUID_LOPART(targetGuid)); CharacterDatabase.Execute(stmt); } return true; } // customize characters bool ChatHandler::HandleCharacterCustomizeCommand(const char* args) { Player* target; uint64 targetGuid; std::string targetName; if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) return false; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); stmt->setUInt16(0, uint16(AT_LOGIN_CUSTOMIZE)); if (target) { PSendSysMessage(LANG_CUSTOMIZE_PLAYER, GetNameLink(target).c_str()); target->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE); stmt->setUInt32(1, target->GetGUIDLow()); } else { std::string oldNameLink = playerLink(targetName); stmt->setUInt32(1, GUID_LOPART(targetGuid)); PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid)); } CharacterDatabase.Execute(stmt); return true; } bool ChatHandler::HandleCharacterChangeFactionCommand(const char* args) { Player* target; uint64 targetGuid; std::string targetName; if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) return false; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); stmt->setUInt16(0, uint16(AT_LOGIN_CHANGE_FACTION)); if (target) { PSendSysMessage(LANG_CUSTOMIZE_PLAYER, GetNameLink(target).c_str()); target->SetAtLoginFlag(AT_LOGIN_CHANGE_FACTION); stmt->setUInt32(1, target->GetGUIDLow()); } else { std::string oldNameLink = playerLink(targetName); PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid)); stmt->setUInt32(1, GUID_LOPART(targetGuid)); } CharacterDatabase.Execute(stmt); return true; } bool ChatHandler::HandleCharacterChangeRaceCommand(const char * args) { Player* target; uint64 targetGuid; std::string targetName; if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) return false; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); stmt->setUInt16(0, uint16(AT_LOGIN_CHANGE_FACTION)); if (target) { // TODO : add text into database PSendSysMessage(LANG_CUSTOMIZE_PLAYER, GetNameLink(target).c_str()); target->SetAtLoginFlag(AT_LOGIN_CHANGE_RACE); stmt->setUInt32(1, target->GetGUIDLow()); } else { std::string oldNameLink = playerLink(targetName); // TODO : add text into database PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid)); stmt->setUInt32(1, GUID_LOPART(targetGuid)); } CharacterDatabase.Execute(stmt); return true; } bool ChatHandler::HandleCharacterReputationCommand(const char* args) { Player* target; if (!extractPlayerTarget((char*)args, &target)) return false; LocaleConstant loc = GetSessionDbcLocale(); FactionStateList const& targetFSL = target->GetReputationMgr().GetStateList(); for (FactionStateList::const_iterator itr = targetFSL.begin(); itr != targetFSL.end(); ++itr) { const FactionState& faction = itr->second; FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction.ID); char const* factionName = factionEntry ? factionEntry->name[loc] : "#Not found#"; ReputationRank rank = target->GetReputationMgr().GetRank(factionEntry); std::string rankName = GetTrinityString(ReputationRankStrIndex[rank]); std::ostringstream ss; if (m_session) ss << faction.ID << " - |cffffffff|Hfaction:" << faction.ID << "|h[" << factionName << ' ' << localeNames[loc] << "]|h|r"; else ss << faction.ID << " - " << factionName << ' ' << localeNames[loc]; ss << ' ' << rankName << " (" << target->GetReputationMgr().GetReputation(factionEntry) << ')'; if (faction.Flags & FACTION_FLAG_VISIBLE) ss << GetTrinityString(LANG_FACTION_VISIBLE); if (faction.Flags & FACTION_FLAG_AT_WAR) ss << GetTrinityString(LANG_FACTION_ATWAR); if (faction.Flags & FACTION_FLAG_PEACE_FORCED) ss << GetTrinityString(LANG_FACTION_PEACE_FORCED); if (faction.Flags & FACTION_FLAG_HIDDEN) ss << GetTrinityString(LANG_FACTION_HIDDEN); if (faction.Flags & FACTION_FLAG_INVISIBLE_FORCED) ss << GetTrinityString(LANG_FACTION_INVISIBLE_FORCED); if (faction.Flags & FACTION_FLAG_INACTIVE) ss << GetTrinityString(LANG_FACTION_INACTIVE); SendSysMessage(ss.str().c_str()); } return true; } bool ChatHandler::HandleLookupEventCommand(const char* args) { if (!*args) return false; std::string namepart = args; std::wstring wnamepart; // converting string that we try to find to lower case if (!Utf8toWStr(namepart, wnamepart)) return false; wstrToLower(wnamepart); bool found = false; uint32 count = 0; uint32 maxResults = sWorld->getIntConfig(CONFIG_MAX_RESULTS_LOOKUP_COMMANDS); GameEventMgr::GameEventDataMap const& events = sGameEventMgr->GetEventMap(); GameEventMgr::ActiveEvents const& activeEvents = sGameEventMgr->GetActiveEventList(); for (uint32 id = 0; id < events.size(); ++id) { GameEventData const& eventData = events[id]; std::string descr = eventData.description; if (descr.empty()) continue; if (Utf8FitTo(descr, wnamepart)) { if (maxResults && count++ == maxResults) { PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); return true; } char const* active = activeEvents.find(id) != activeEvents.end() ? GetTrinityString(LANG_ACTIVE) : ""; if (m_session) PSendSysMessage(LANG_EVENT_ENTRY_LIST_CHAT, id, id, eventData.description.c_str(), active); else PSendSysMessage(LANG_EVENT_ENTRY_LIST_CONSOLE, id, eventData.description.c_str(), active); if (!found) found = true; } } if (!found) SendSysMessage(LANG_NOEVENTFOUND); return true; } bool ChatHandler::HandleCombatStopCommand(const char* args) { Player* target; if (!extractPlayerTarget((char*)args, &target)) return false; // check online security if (HasLowerSecurity(target, 0)) return false; target->CombatStop(); target->getHostileRefManager().deleteReferences(); return true; } bool ChatHandler::HandleLookupPlayerIpCommand(const char* args) { std::string ip; int32 limit; char* limit_str; Player *chr = getSelectedPlayer(); if (chr == NULL) { if (!*args) return false; ip = strtok ((char*)args, " "); limit_str = strtok (NULL, " "); limit = limit_str ? atoi (limit_str) : -1; } else { ip = chr->GetSession()->GetRemoteAddress(); limit = -1; } LoginDatabase.EscapeString(ip); QueryResult result = LoginDatabase.PQuery("SELECT id, username FROM account WHERE last_ip = '%s'", ip.c_str()); return LookupPlayerSearchCommand(result, limit); } bool ChatHandler::HandleLookupPlayerAccountCommand(const char* args) { if (!*args) return false; std::string account = strtok ((char*)args, " "); char* limit_str = strtok (NULL, " "); int32 limit = limit_str ? atoi (limit_str) : -1; if (!AccountMgr::normalizeString (account)) return false; LoginDatabase.EscapeString (account); QueryResult result = LoginDatabase.PQuery ("SELECT id, username FROM account WHERE username = '%s'", account.c_str ()); return LookupPlayerSearchCommand (result, limit); } bool ChatHandler::HandleLookupPlayerEmailCommand(const char* args) { if (!*args) return false; std::string email = strtok ((char*)args, " "); char* limit_str = strtok (NULL, " "); int32 limit = limit_str ? atoi (limit_str) : -1; LoginDatabase.EscapeString (email); QueryResult result = LoginDatabase.PQuery ("SELECT id, username FROM account WHERE email = '%s'", email.c_str ()); return LookupPlayerSearchCommand (result, limit); } bool ChatHandler::LookupPlayerSearchCommand(QueryResult result, int32 limit) { if (!result) { PSendSysMessage(LANG_NO_PLAYERS_FOUND); SetSentErrorMessage(true); return false; } int i = 0; uint32 count = 0; uint32 maxResults = sWorld->getIntConfig(CONFIG_MAX_RESULTS_LOOKUP_COMMANDS); do { if (maxResults && count++ == maxResults) { PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); return true; } Field* fields = result->Fetch(); uint32 acc_id = fields[0].GetUInt32(); std::string acc_name = fields[1].GetString(); QueryResult chars = CharacterDatabase.PQuery("SELECT guid, name FROM characters WHERE account = '%u'", acc_id); if (chars) { PSendSysMessage(LANG_LOOKUP_PLAYER_ACCOUNT, acc_name.c_str(), acc_id); uint64 guid = 0; std::string name; do { Field* charfields = chars->Fetch(); guid = charfields[0].GetUInt64(); name = charfields[1].GetString(); PSendSysMessage(LANG_LOOKUP_PLAYER_CHARACTER, name.c_str(), guid); ++i; } while (chars->NextRow() && (limit == -1 || i < limit)); } } while (result->NextRow()); if (i == 0) // empty accounts only { PSendSysMessage(LANG_NO_PLAYERS_FOUND); SetSentErrorMessage(true); return false; } return true; } /// Triggering corpses expire check in world bool ChatHandler::HandleServerCorpsesCommand(const char* /*args*/) { sObjectAccessor->RemoveOldCorpses(); return true; } bool ChatHandler::HandleRepairitemsCommand(const char* args) { Player* target; if (!extractPlayerTarget((char*)args, &target)) return false; // check online security if (HasLowerSecurity(target, 0)) return false; // Repair items target->DurabilityRepairAll(false, 0, false); PSendSysMessage(LANG_YOU_REPAIR_ITEMS, GetNameLink(target).c_str()); if (needReportToTarget(target)) ChatHandler(target).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED, GetNameLink().c_str()); return true; } bool ChatHandler::HandleWaterwalkCommand(const char* args) { if (!*args) return false; Player* player = getSelectedPlayer(); if (!player) { PSendSysMessage(LANG_NO_CHAR_SELECTED); SetSentErrorMessage(true); return false; } // check online security if (HasLowerSecurity(player, 0)) return false; if (strncmp(args, "on", 3) == 0) player->SetMovement(MOVE_WATER_WALK); // ON else if (strncmp(args, "off", 4) == 0) player->SetMovement(MOVE_LAND_WALK); // OFF else { SendSysMessage(LANG_USE_BOL); return false; } PSendSysMessage(LANG_YOU_SET_WATERWALK, args, GetNameLink(player).c_str()); if (needReportToTarget(player)) ChatHandler(player).PSendSysMessage(LANG_YOUR_WATERWALK_SET, args, GetNameLink().c_str()); return true; } bool ChatHandler::HandleCreatePetCommand(const char* /*args*/) { Player* player = m_session->GetPlayer(); Creature* creatureTarget = getSelectedCreature(); if (!creatureTarget || creatureTarget->isPet() || creatureTarget->GetTypeId() == TYPEID_PLAYER) { PSendSysMessage(LANG_SELECT_CREATURE); SetSentErrorMessage(true); return false; } CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creatureTarget->GetEntry()); // Creatures with family 0 crashes the server if (cInfo->family == 0) { PSendSysMessage("This creature cannot be tamed. (family id: 0)."); SetSentErrorMessage(true); return false; } if (player->GetPetGUID()) { PSendSysMessage("You already have a pet"); SetSentErrorMessage(true); return false; } // Everything looks OK, create new pet Pet* pet = new Pet(player, HUNTER_PET); if (!pet->CreateBaseAtCreature(creatureTarget)) { delete pet; PSendSysMessage("Error 1"); return false; } creatureTarget->setDeathState(JUST_DIED); creatureTarget->RemoveCorpse(); creatureTarget->SetHealth(0); // just for nice GM-mode view pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, player->GetGUID()); pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, player->getFaction()); if (!pet->InitStatsForLevel(creatureTarget->getLevel())) { sLog->outError("InitStatsForLevel() in EffectTameCreature failed! Pet deleted."); PSendSysMessage("Error 2"); delete pet; return false; } // prepare visual effect for levelup pet->SetUInt32Value(UNIT_FIELD_LEVEL, creatureTarget->getLevel()-1); pet->GetCharmInfo()->SetPetNumber(sObjectMgr->GeneratePetNumber(), true); // this enables pet details window (Shift+P) pet->InitPetCreateSpells(); pet->SetFullHealth(); pet->GetMap()->AddToMap(pet->ToCreature()); // visual effect for levelup pet->SetUInt32Value(UNIT_FIELD_LEVEL, creatureTarget->getLevel()); player->SetMinion(pet, true); pet->SavePetToDB(PET_SAVE_AS_CURRENT); player->PetSpellInitialize(); return true; } bool ChatHandler::HandlePetLearnCommand(const char* args) { if (!*args) return false; Player* player = m_session->GetPlayer(); Pet* pet = player->GetPet(); if (!pet) { PSendSysMessage("You have no pet"); SetSentErrorMessage(true); return false; } uint32 spellId = extractSpellIdFromLink((char*)args); if (!spellId || !sSpellMgr->GetSpellInfo(spellId)) return false; // Check if pet already has it if (pet->HasSpell(spellId)) { PSendSysMessage("Pet already has spell: %u", spellId); SetSentErrorMessage(true); return false; } // Check if spell is valid SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo)) { PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spellId); SetSentErrorMessage(true); return false; } pet->learnSpell(spellId); PSendSysMessage("Pet has learned spell %u", spellId); return true; } bool ChatHandler::HandlePetUnlearnCommand(const char *args) { if (!*args) return false; Player* player = m_session->GetPlayer(); Pet* pet = player->GetPet(); if (!pet) { PSendSysMessage("You have no pet"); SetSentErrorMessage(true); return false; } uint32 spellId = extractSpellIdFromLink((char*)args); if (pet->HasSpell(spellId)) pet->removeSpell(spellId, false); else PSendSysMessage("Pet doesn't have that spell"); return true; } bool ChatHandler::HandleLookupTitleCommand(const char* args) { if (!*args) return false; // can be NULL in console call Player* target = getSelectedPlayer(); // title name have single string arg for player name char const* targetName = target ? target->GetName() : "NAME"; std::string namepart = args; std::wstring wnamepart; if (!Utf8toWStr(namepart, wnamepart)) return false; // converting string that we try to find to lower case wstrToLower(wnamepart); uint32 counter = 0; // Counter for figure out that we found smth. uint32 maxResults = sWorld->getIntConfig(CONFIG_MAX_RESULTS_LOOKUP_COMMANDS); // Search in CharTitles.dbc for (uint32 id = 0; id < sCharTitlesStore.GetNumRows(); id++) { CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(id); if (titleInfo) { int loc = GetSessionDbcLocale(); std::string name = titleInfo->name[loc]; if (name.empty()) continue; if (!Utf8FitTo(name, wnamepart)) { loc = 0; for (; loc < TOTAL_LOCALES; ++loc) { if (loc == GetSessionDbcLocale()) continue; name = titleInfo->name[loc]; if (name.empty()) continue; if (Utf8FitTo(name, wnamepart)) break; } } if (loc < TOTAL_LOCALES) { if (maxResults && counter == maxResults) { PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); return true; } char const* knownStr = target && target->HasTitle(titleInfo) ? GetTrinityString(LANG_KNOWN) : ""; char const* activeStr = target && target->GetUInt32Value(PLAYER_CHOSEN_TITLE) == titleInfo->bit_index ? GetTrinityString(LANG_ACTIVE) : ""; char titleNameStr[80]; snprintf(titleNameStr, 80, name.c_str(), targetName); // send title in "id (idx:idx) - [namedlink locale]" format if (m_session) PSendSysMessage(LANG_TITLE_LIST_CHAT, id, titleInfo->bit_index, id, titleNameStr, localeNames[loc], knownStr, activeStr); else PSendSysMessage(LANG_TITLE_LIST_CONSOLE, id, titleInfo->bit_index, titleNameStr, localeNames[loc], knownStr, activeStr); ++counter; } } } if (counter == 0) // if counter == 0 then we found nth SendSysMessage(LANG_COMMAND_NOTITLEFOUND); return true; } bool ChatHandler::HandleCharacterTitlesCommand(const char* args) { if (!*args) return false; Player* target; if (!extractPlayerTarget((char*)args, &target)) return false; LocaleConstant loc = GetSessionDbcLocale(); char const* targetName = target->GetName(); char const* knownStr = GetTrinityString(LANG_KNOWN); // Search in CharTitles.dbc for (uint32 id = 0; id < sCharTitlesStore.GetNumRows(); id++) { CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(id); if (titleInfo && target->HasTitle(titleInfo)) { std::string name = titleInfo->name[loc]; if (name.empty()) continue; char const* activeStr = target && target->GetUInt32Value(PLAYER_CHOSEN_TITLE) == titleInfo->bit_index ? GetTrinityString(LANG_ACTIVE) : ""; char titleNameStr[80]; snprintf(titleNameStr, 80, name.c_str(), targetName); // send title in "id (idx:idx) - [namedlink locale]" format if (m_session) PSendSysMessage(LANG_TITLE_LIST_CHAT, id, titleInfo->bit_index, id, titleNameStr, localeNames[loc], knownStr, activeStr); else PSendSysMessage(LANG_TITLE_LIST_CONSOLE, id, titleInfo->bit_index, name.c_str(), localeNames[loc], knownStr, activeStr); } } return true; }