diff options
author | Yehonal <yehonal.azeroth@gmail.com> | 2016-08-12 00:46:43 +0200 |
---|---|---|
committer | Yehonal <yehonal.azeroth@gmail.com> | 2016-08-12 02:38:26 +0200 |
commit | b0c8eceb08b9a7688893991e5ba4a3350617e6ed (patch) | |
tree | 39a52f0bea8e1ed803dc4298fdeb8b6bd808b67d /src/scripts/Commands/cs_misc.cpp | |
parent | a73ad5cd6eefd619e9371d9b26c7e6317cacd7f7 (diff) |
Refactoring part 2 [W.I.P]
Diffstat (limited to 'src/scripts/Commands/cs_misc.cpp')
-rw-r--r-- | src/scripts/Commands/cs_misc.cpp | 3173 |
1 files changed, 3173 insertions, 0 deletions
diff --git a/src/scripts/Commands/cs_misc.cpp b/src/scripts/Commands/cs_misc.cpp new file mode 100644 index 0000000000..f2353f6f31 --- /dev/null +++ b/src/scripts/Commands/cs_misc.cpp @@ -0,0 +1,3173 @@ +/* + * Copyright (C) + * + * 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 <http://www.gnu.org/licenses/>. + */ + +#include "Chat.h" +#include "ScriptMgr.h" +#include "AccountMgr.h" +#include "ArenaTeamMgr.h" +#include "CellImpl.h" +#include "GridNotifiers.h" +#include "Group.h" +#include "GuildMgr.h" +#include "InstanceSaveMgr.h" +#include "Language.h" +#include "MovementGenerator.h" +#include "ObjectAccessor.h" +#include "Opcodes.h" +#include "SpellAuras.h" +#include "TargetedMovementGenerator.h" +#include "WeatherMgr.h" +#include "ace/INET_Addr.h" +#include "Player.h" +#include "Pet.h" +#include "LFG.h" +#include "GroupMgr.h" +#include "BattlegroundMgr.h" +#include "MapManager.h" + +class misc_commandscript : public CommandScript +{ +public: + misc_commandscript() : CommandScript("misc_commandscript") { } + + ChatCommand* GetCommands() const + { + static ChatCommand groupCommandTable[] = + { + { "leader", SEC_ADMINISTRATOR, false, &HandleGroupLeaderCommand, "", NULL }, + { "disband", SEC_ADMINISTRATOR, false, &HandleGroupDisbandCommand, "", NULL }, + { "remove", SEC_ADMINISTRATOR, false, &HandleGroupRemoveCommand, "", NULL }, + { "join", SEC_ADMINISTRATOR, false, &HandleGroupJoinCommand, "", NULL }, + { "list", SEC_ADMINISTRATOR, false, &HandleGroupListCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand petCommandTable[] = + { + { "create", SEC_GAMEMASTER, false, &HandleCreatePetCommand, "", NULL }, + { "learn", SEC_GAMEMASTER, false, &HandlePetLearnCommand, "", NULL }, + { "unlearn", SEC_GAMEMASTER, false, &HandlePetUnlearnCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand sendCommandTable[] = + { + { "items", SEC_ADMINISTRATOR, true, &HandleSendItemsCommand, "", NULL }, + { "mail", SEC_GAMEMASTER, true, &HandleSendMailCommand, "", NULL }, + { "message", SEC_ADMINISTRATOR, true, &HandleSendMessageCommand, "", NULL }, + { "money", SEC_ADMINISTRATOR, true, &HandleSendMoneyCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand commandTable[] = + { + { "dev", SEC_ADMINISTRATOR, false, &HandleDevCommand, "", NULL }, + { "gps", SEC_ADMINISTRATOR, false, &HandleGPSCommand, "", NULL }, + { "aura", SEC_ADMINISTRATOR, false, &HandleAuraCommand, "", NULL }, + { "unaura", SEC_ADMINISTRATOR, false, &HandleUnAuraCommand, "", NULL }, + { "appear", SEC_GAMEMASTER, false, &HandleAppearCommand, "", NULL }, + { "summon", SEC_GAMEMASTER, false, &HandleSummonCommand, "", NULL }, + { "groupsummon", SEC_GAMEMASTER, false, &HandleGroupSummonCommand, "", NULL }, + { "commands", SEC_PLAYER, true, &HandleCommandsCommand, "", NULL }, + { "die", SEC_ADMINISTRATOR, false, &HandleDieCommand, "", NULL }, + { "revive", SEC_ADMINISTRATOR, true, &HandleReviveCommand, "", NULL }, + { "dismount", SEC_PLAYER, false, &HandleDismountCommand, "", NULL }, + { "guid", SEC_GAMEMASTER, false, &HandleGUIDCommand, "", NULL }, + { "help", SEC_PLAYER, true, &HandleHelpCommand, "", NULL }, + { "itemmove", SEC_GAMEMASTER, false, &HandleItemMoveCommand, "", NULL }, + { "cooldown", SEC_ADMINISTRATOR, false, &HandleCooldownCommand, "", NULL }, + { "distance", SEC_ADMINISTRATOR, false, &HandleGetDistanceCommand, "", NULL }, + { "recall", SEC_GAMEMASTER, false, &HandleRecallCommand, "", NULL }, + { "save", SEC_PLAYER, false, &HandleSaveCommand, "", NULL }, + { "saveall", SEC_GAMEMASTER, true, &HandleSaveAllCommand, "", NULL }, + { "kick", SEC_GAMEMASTER, true, &HandleKickPlayerCommand, "", NULL }, + { "unstuck", SEC_GAMEMASTER, true, &HandleUnstuckCommand, "", NULL }, + { "taxicheat", SEC_GAMEMASTER, false, &HandleTaxiCheatCommand, "", NULL }, + { "linkgrave", SEC_ADMINISTRATOR, false, &HandleLinkGraveCommand, "", NULL }, + { "neargrave", SEC_ADMINISTRATOR, false, &HandleNearGraveCommand, "", NULL }, + { "explorecheat", SEC_ADMINISTRATOR, false, &HandleExploreCheatCommand, "", NULL }, + { "showarea", SEC_ADMINISTRATOR, false, &HandleShowAreaCommand, "", NULL }, + { "hidearea", SEC_ADMINISTRATOR, false, &HandleHideAreaCommand, "", NULL }, + { "additem", SEC_ADMINISTRATOR, false, &HandleAddItemCommand, "", NULL }, + { "additemset", SEC_ADMINISTRATOR, false, &HandleAddItemSetCommand, "", NULL }, + { "bank", SEC_ADMINISTRATOR, false, &HandleBankCommand, "", NULL }, + { "wchange", SEC_ADMINISTRATOR, false, &HandleChangeWeather, "", NULL }, + { "maxskill", SEC_ADMINISTRATOR, false, &HandleMaxSkillCommand, "", NULL }, + { "setskill", SEC_ADMINISTRATOR, false, &HandleSetSkillCommand, "", NULL }, + { "pinfo", SEC_GAMEMASTER, true, &HandlePInfoCommand, "", NULL }, + { "respawn", SEC_ADMINISTRATOR, false, &HandleRespawnCommand, "", NULL }, + { "send", SEC_GAMEMASTER, true, NULL, "", sendCommandTable }, + { "pet", SEC_GAMEMASTER, false, NULL, "", petCommandTable }, + { "mute", SEC_GAMEMASTER, true, &HandleMuteCommand, "", NULL }, + { "unmute", SEC_GAMEMASTER, true, &HandleUnmuteCommand, "", NULL }, + { "movegens", SEC_ADMINISTRATOR, false, &HandleMovegensCommand, "", NULL }, + { "cometome", SEC_ADMINISTRATOR, false, &HandleComeToMeCommand, "", NULL }, + { "damage", SEC_ADMINISTRATOR, false, &HandleDamageCommand, "", NULL }, + { "combatstop", SEC_GAMEMASTER, true, &HandleCombatStopCommand, "", NULL }, + { "flusharenapoints", SEC_ADMINISTRATOR, false, &HandleFlushArenaPointsCommand, "", NULL }, + { "repairitems", SEC_GAMEMASTER, true, &HandleRepairitemsCommand, "", NULL }, + { "waterwalk", SEC_GAMEMASTER, false, &HandleWaterwalkCommand, "", NULL }, + { "freeze", SEC_GAMEMASTER, false, &HandleFreezeCommand, "", NULL }, + { "unfreeze", SEC_GAMEMASTER, false, &HandleUnFreezeCommand, "", NULL }, + { "group", SEC_ADMINISTRATOR, false, NULL, "", groupCommandTable }, + { "possess", SEC_ADMINISTRATOR, false, HandlePossessCommand, "", NULL }, + { "unpossess", SEC_ADMINISTRATOR, false, HandleUnPossessCommand, "", NULL }, + { "bindsight", SEC_ADMINISTRATOR, false, HandleBindSightCommand, "", NULL }, + { "unbindsight", SEC_ADMINISTRATOR, false, HandleUnbindSightCommand, "", NULL }, + { "playall", SEC_GAMEMASTER, false, HandlePlayAllCommand, "", NULL }, + { "skirmish", SEC_ADMINISTRATOR, false, HandleSkirmishCommand, "", NULL }, + { "mailbox", SEC_ADMINISTRATOR, false, &HandleMailBoxCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + return commandTable; + } + + static bool HandleSkirmishCommand(ChatHandler* handler, char const* args) + { + Tokenizer tokens(args, ' '); + + if (!*args || !tokens.size()) + { + handler->PSendSysMessage("Usage: .skirmish [arena] [XvX] [Nick1] [Nick2] ... [NickN]"); + handler->PSendSysMessage("[arena] can be \"all\" or comma-separated list of possible arenas (NA,BE,RL,DS,RV)."); + handler->PSendSysMessage("[XvX] can be 1v1, 2v2, 3v3, 5v5. After [XvX] specify enough nicknames for that mode."); + handler->SetSentErrorMessage(true); + return false; + } + + Tokenizer::const_iterator i = tokens.begin(); + + std::set<BattlegroundTypeId> allowedArenas; + std::string arenasStr = *(i++); + std::string tmpStr; + Tokenizer arenaTokens(arenasStr, ','); + for (Tokenizer::const_iterator itr = arenaTokens.begin(); itr != arenaTokens.end(); ++itr) + { + tmpStr = std::string(*itr); + if (tmpStr == "all") + { + if (arenaTokens.size() > 1) + { + handler->PSendSysMessage("Invalid [arena] specified."); + handler->SetSentErrorMessage(true); + return false; + } + allowedArenas.insert(BATTLEGROUND_NA); + allowedArenas.insert(BATTLEGROUND_BE); + allowedArenas.insert(BATTLEGROUND_RL); + allowedArenas.insert(BATTLEGROUND_DS); + allowedArenas.insert(BATTLEGROUND_RV); + } + else if (tmpStr == "NA") + allowedArenas.insert(BATTLEGROUND_NA); + else if (tmpStr == "BE") + allowedArenas.insert(BATTLEGROUND_BE); + else if (tmpStr == "RL") + allowedArenas.insert(BATTLEGROUND_RL); + else if (tmpStr == "DS") + allowedArenas.insert(BATTLEGROUND_DS); + else if (tmpStr == "RV") + allowedArenas.insert(BATTLEGROUND_RV); + else + { + handler->PSendSysMessage("Invalid [arena] specified."); + handler->SetSentErrorMessage(true); + return false; + } + } + ASSERT(!allowedArenas.empty()); + BattlegroundTypeId randomizedArenaBgTypeId = Trinity::Containers::SelectRandomContainerElement(allowedArenas); + + uint8 count = 0; + if (i != tokens.end()) + { + std::string mode = *(i++); + if (mode == "1v1") count = 2; + else if (mode == "2v2") count = 4; + else if (mode == "3v3") count = 6; + else if (mode == "5v5") count = 10; + } + + if (!count) + { + handler->PSendSysMessage("Invalid bracket. Can be 1v1, 2v2, 3v3, 5v5"); + handler->SetSentErrorMessage(true); + return false; + } + + if (tokens.size() != count+2) + { + handler->PSendSysMessage("Invalid number of nicknames for this bracket."); + handler->SetSentErrorMessage(true); + return false; + } + + uint8 hcnt = count / 2; + uint8 error = 0; + std::string last_name; + Player* plr = NULL; + Player* players[10] = {NULL}; + uint8 cnt = 0; + for (; i != tokens.end(); ++i) + { + last_name = std::string(*i); + plr = ObjectAccessor::FindPlayerByName(last_name, false); + if (!plr) { error = 1; break; } + if (!plr->IsInWorld() || !plr->FindMap() || plr->IsBeingTeleported()) { error = 2; break; } + if (plr->GetMap()->GetEntry()->Instanceable()) { error = 3; break; } + if (plr->isUsingLfg()) { error = 4; break; } + if (plr->InBattlegroundQueue()) { error = 5; break; } + if (plr->IsInFlight()) { error = 10; break; } + if (!plr->IsAlive()) { error = 11; break; } + const Group* g = plr->GetGroup(); + if (hcnt > 1) + { + if (!g) { error = 6; break; } + if (g->isRaidGroup() || g->isBGGroup() || g->isBFGroup() || g->isLFGGroup()) { error = 7; break; } + if (g->GetMembersCount() != hcnt) { error = 8; break; } + + uint8 sti = (cnt < hcnt ? 0 : hcnt); + if (sti != cnt) + if (players[sti]->GetGroup() != plr->GetGroup()) { error = 9; last_name += " and " + players[sti]->GetName(); break; } + } + else // 1v1 + { + if (g) { error = 12; break; } + } + players[cnt++] = plr; + } + + for (uint8 i=0; i<cnt && !error; ++i) + for (uint8 j=i+1; j<cnt; ++j) + if (players[i]->GetGUID() == players[j]->GetGUID()) + { + last_name = players[i]->GetName(); + error = 13; + break; + } + + switch (error) + { + case 1: + handler->PSendSysMessage("Player %s not found.", last_name.c_str()); + break; + case 2: + handler->PSendSysMessage("Player %s is being teleported.", last_name.c_str()); + break; + case 3: + handler->PSendSysMessage("Player %s is in instance/battleground/arena.", last_name.c_str()); + break; + case 4: + handler->PSendSysMessage("Player %s is in LFG system.", last_name.c_str()); + break; + case 5: + handler->PSendSysMessage("Player %s is queued for battleground/arena.", last_name.c_str()); + break; + case 6: + handler->PSendSysMessage("Player %s is not in group.", last_name.c_str()); + break; + case 7: + handler->PSendSysMessage("Player %s is not in normal group.", last_name.c_str()); + break; + case 8: + handler->PSendSysMessage("Group of player %s has invalid member count.", last_name.c_str()); + break; + case 9: + handler->PSendSysMessage("Players %s are not in the same group.", last_name.c_str()); + break; + case 10: + handler->PSendSysMessage("Player %s is in flight.", last_name.c_str()); + break; + case 11: + handler->PSendSysMessage("Player %s is dead.", last_name.c_str()); + break; + case 12: + handler->PSendSysMessage("Player %s is in a group.", last_name.c_str()); + break; + case 13: + handler->PSendSysMessage("Player %s occurs more than once.", last_name.c_str()); + break; + } + + if (error) + { + handler->SetSentErrorMessage(true); + return false; + } + + Battleground* bgt = sBattlegroundMgr->GetBattlegroundTemplate(BATTLEGROUND_AA); + if (!bgt) + { + handler->PSendSysMessage("Couldn't create arena map!"); + handler->SetSentErrorMessage(true); + return false; + } + + Battleground* bg = sBattlegroundMgr->CreateNewBattleground(randomizedArenaBgTypeId, 80, 80, ArenaType(hcnt >= 2 ? hcnt : 2), false); + if (!bg) + { + handler->PSendSysMessage("Couldn't create arena map!"); + handler->SetSentErrorMessage(true); + return false; + } + + bg->StartBattleground(); + + BattlegroundTypeId bgTypeId = bg->GetBgTypeID(); + + TeamId teamId1 = Player::TeamIdForRace(players[0]->getRace()); + TeamId teamId2 = (teamId1 == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE); + for (uint8 i=0; i<cnt; ++i) + { + Player* player = players[i]; + + TeamId teamId = (i < hcnt ? teamId1 : teamId2); + player->SetEntryPoint(); + + uint32 queueSlot = 0; + WorldPacket data; + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType(), teamId); + player->GetSession()->SendPacket(&data); + + player->SetBattlegroundId(bg->GetInstanceID(), bgTypeId, queueSlot, true, false, teamId); + sBattlegroundMgr->SendToBattleground(player, bg->GetInstanceID(), bgTypeId); + } + + handler->PSendSysMessage("Success! Players are now being teleported to the arena."); + return true; + } + + static bool HandleDevCommand(ChatHandler* handler, char const* args) + { + if (!*args) + { + if (handler->GetSession()->GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_DEVELOPER)) + handler->GetSession()->SendNotification(LANG_DEV_ON); + else + handler->GetSession()->SendNotification(LANG_DEV_OFF); + return true; + } + + std::string argstr = (char*)args; + + if (argstr == "on") + { + handler->GetSession()->GetPlayer()->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_DEVELOPER); + handler->GetSession()->SendNotification(LANG_DEV_ON); + return true; + } + + if (argstr == "off") + { + handler->GetSession()->GetPlayer()->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_DEVELOPER); + handler->GetSession()->SendNotification(LANG_DEV_OFF); + return true; + } + + handler->SendSysMessage(LANG_USE_BOL); + handler->SetSentErrorMessage(true); + return false; + } + + static bool HandleGPSCommand(ChatHandler* handler, char const* args) + { + WorldObject* object = NULL; + if (*args) + { + uint64 guid = handler->extractGuidFromLink((char*)args); + if (guid) + object = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*handler->GetSession()->GetPlayer(), guid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT); + + if (!object) + { + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + } + else + { + object = handler->getSelectedUnit(); + + if (!object) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + } + + CellCoord cellCoord = Trinity::ComputeCellCoord(object->GetPositionX(), object->GetPositionY()); + Cell cell(cellCoord); + + uint32 zoneId, areaId; + object->GetZoneAndAreaId(zoneId, areaId); + + MapEntry const* mapEntry = sMapStore.LookupEntry(object->GetMapId()); + AreaTableEntry const* zoneEntry = GetAreaEntryByAreaID(zoneId); + AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(areaId); + + float zoneX = object->GetPositionX(); + float zoneY = object->GetPositionY(); + + Map2ZoneCoordinates(zoneX, zoneY, zoneId); + + Map const* map = object->GetMap(); + float groundZ = map->GetHeight(object->GetPhaseMask(), object->GetPositionX(), object->GetPositionY(), MAX_HEIGHT); + float floorZ = map->GetHeight(object->GetPhaseMask(), object->GetPositionX(), object->GetPositionY(), object->GetPositionZ()); + + GridCoord gridCoord = Trinity::ComputeGridCoord(object->GetPositionX(), object->GetPositionY()); + + // 63? WHY? + int gridX = 63 - gridCoord.x_coord; + int gridY = 63 - gridCoord.y_coord; + + uint32 haveMap = Map::ExistMap(object->GetMapId(), gridX, gridY) ? 1 : 0; + uint32 haveVMap = Map::ExistVMap(object->GetMapId(), gridX, gridY) ? 1 : 0; + + if (haveVMap) + { + if (map->IsOutdoors(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ())) + handler->PSendSysMessage("You are outdoors"); + else + handler->PSendSysMessage("You are indoors"); + } + else + handler->PSendSysMessage("no VMAP available for area info"); + + handler->PSendSysMessage(LANG_MAP_POSITION, + object->GetMapId(), (mapEntry ? mapEntry->name[handler->GetSessionDbcLocale()] : "<unknown>"), + zoneId, (zoneEntry ? zoneEntry->area_name[handler->GetSessionDbcLocale()] : "<unknown>"), + areaId, (areaEntry ? areaEntry->area_name[handler->GetSessionDbcLocale()] : "<unknown>"), + object->GetPhaseMask(), + object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), object->GetOrientation(), + cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), object->GetInstanceId(), + zoneX, zoneY, groundZ, floorZ, haveMap, haveVMap); + + LiquidData liquidStatus; + ZLiquidStatus status = map->getLiquidStatus(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), MAP_ALL_LIQUIDS, &liquidStatus); + + if (status) + handler->PSendSysMessage(LANG_LIQUID_STATUS, liquidStatus.level, liquidStatus.depth_level, liquidStatus.entry, liquidStatus.type_flags, status); + if (Transport* t = object->GetTransport()) + handler->PSendSysMessage("Transport offset: %.2f, %.2f, %.2f, %.2f", object->m_movementInfo.transport.pos.GetPositionX(), object->m_movementInfo.transport.pos.GetPositionY(), object->m_movementInfo.transport.pos.GetPositionZ(), object->m_movementInfo.transport.pos.GetOrientation()); + + return true; + } + + static bool HandleAuraCommand(ChatHandler* handler, char const* args) + { + Unit* target = handler->getSelectedUnit(); + if (!target) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spellId = handler->extractSpellIdFromLink((char*)args); + if (!spellId) + return false; + + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); + if (!spellInfo) + { + handler->PSendSysMessage(LANG_COMMAND_NOSPELLFOUND); + handler->SetSentErrorMessage(true); + return false; + } + + if (!SpellMgr::IsSpellValid(spellInfo)) + { + handler->PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spellId); + handler->SetSentErrorMessage(true); + return false; + } + + SpellScriptsBounds bounds = sObjectMgr->GetSpellScriptsBounds(spellId); + uint32 spellDifficultyId = sSpellMgr->GetSpellDifficultyId(spellId); + if (bounds.first != bounds.second || spellDifficultyId) + { + handler->PSendSysMessage("Aura %u cannot be applied using a command!", spellId); + handler->SetSentErrorMessage(true); + return false; + } + + Aura::TryRefreshStackOrCreate(spellInfo, MAX_EFFECT_MASK, target, target); + + return true; + } + + static bool HandleUnAuraCommand(ChatHandler* handler, char const* args) + { + Unit* target = handler->getSelectedUnit(); + if (!target) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + std::string argstr = args; + if (argstr == "all") + { + target->RemoveAllAuras(); + return true; + } + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spellId = handler->extractSpellIdFromLink((char*)args); + if (!spellId) + return false; + + target->RemoveAurasDueToSpell(spellId); + + return true; + } + // Teleport to Player + static bool HandleAppearCommand(ChatHandler* handler, char const* args) + { + Player* target; + uint64 targetGuid; + std::string targetName; + if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) + return false; + + Player* _player = handler->GetSession()->GetPlayer(); + if (target == _player || targetGuid == _player->GetGUID()) + { + handler->SendSysMessage(LANG_CANT_TELEPORT_SELF); + handler->SetSentErrorMessage(true); + return false; + } + + if (target) + { + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + std::string chrNameLink = handler->playerLink(targetName); + + Map* map = target->GetMap(); + if (map->IsBattlegroundOrArena()) + { + // only allow if gm mode is on + if (!_player->IsGameMaster()) + { + handler->PSendSysMessage(LANG_CANNOT_GO_TO_BG_GM, chrNameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + if (!_player->GetMap()->IsBattlegroundOrArena()) + _player->SetEntryPoint(); + + _player->SetBattlegroundId(target->GetBattlegroundId(), target->GetBattlegroundTypeId(), PLAYER_MAX_BATTLEGROUND_QUEUES, false, false, TEAM_NEUTRAL); + } + else if (map->IsDungeon()) + { + // we have to go to instance, and can go to player only if: + // 1) we are in his group (either as leader or as member) + // 2) we are not bound to any group and have GM mode on + if (_player->GetGroup()) + { + // we are in group, we can go only if we are in the player group + if (_player->GetGroup() != target->GetGroup()) + { + handler->PSendSysMessage(LANG_CANNOT_GO_TO_INST_PARTY, chrNameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + } + else + { + // we are not in group, let's verify our GM mode + if (!_player->IsGameMaster()) + { + handler->PSendSysMessage(LANG_CANNOT_GO_TO_INST_GM, chrNameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + } + + // if the GM is bound to another instance, he will not be bound to another one + InstancePlayerBind* bind = sInstanceSaveMgr->PlayerGetBoundInstance(_player->GetGUIDLow(), target->GetMapId(), target->GetDifficulty(map->IsRaid())); + if (!bind) + if (InstanceSave* save = sInstanceSaveMgr->GetInstanceSave(target->GetInstanceId())) + sInstanceSaveMgr->PlayerBindToInstance(_player->GetGUIDLow(), save, !save->CanReset(), _player); + + if (map->IsRaid()) + _player->SetRaidDifficulty(target->GetRaidDifficulty()); + else + _player->SetDungeonDifficulty(target->GetDungeonDifficulty()); + } + + handler->PSendSysMessage(LANG_APPEARING_AT, chrNameLink.c_str()); + + // stop flight if need + if (_player->IsInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->CleanupAfterTaxiFlight(); + } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + _player->TeleportTo(target->GetMapId(), target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()+0.25f, _player->GetOrientation(), TELE_TO_GM_MODE); + _player->SetPhaseMask(target->GetPhaseMask() | 1, false); + } + else + { + // check offline security + if (handler->HasLowerSecurity(NULL, targetGuid)) + return false; + + std::string nameLink = handler->playerLink(targetName); + + handler->PSendSysMessage(LANG_APPEARING_AT, nameLink.c_str()); + + // to point where player stay (if loaded) + float x, y, z, o; + uint32 map; + bool in_flight; + if (!Player::LoadPositionFromDB(map, x, y, z, o, in_flight, targetGuid)) + return false; + + // stop flight if need + if (_player->IsInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->CleanupAfterTaxiFlight(); + } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + _player->TeleportTo(map, x, y, z, _player->GetOrientation()); + } + + return true; + } + // Summon Player + static bool HandleSummonCommand(ChatHandler* handler, char const* args) + { + Player* target; + uint64 targetGuid; + std::string targetName; + if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) + return false; + + Player* _player = handler->GetSession()->GetPlayer(); + if (target == _player || targetGuid == _player->GetGUID()) + { + handler->PSendSysMessage(LANG_CANT_TELEPORT_SELF); + handler->SetSentErrorMessage(true); + return false; + } + + if (target) + { + std::string nameLink = handler->playerLink(targetName); + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + if (target->IsBeingTeleported()) + { + handler->PSendSysMessage(LANG_IS_TELEPORTED, nameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + Map* map = handler->GetSession()->GetPlayer()->GetMap(); + + if (map->IsBattlegroundOrArena()) + { + handler->PSendSysMessage("Can't summon to a battleground!"); + handler->SetSentErrorMessage(true); + return false; + } + else if (map->IsDungeon()) + { + // pussywizard: prevent unbinding normal player's perm bind by just summoning him >_> + if (!target->GetSession()->GetSecurity()) + { + handler->PSendSysMessage("Only GMs can be summoned to an instance!"); + handler->SetSentErrorMessage(true); + return false; + } + + Map* destMap = target->GetMap(); + + if (destMap->Instanceable() && destMap->GetInstanceId() != map->GetInstanceId()) + sInstanceSaveMgr->PlayerUnbindInstance(target->GetGUIDLow(), map->GetInstanceId(), target->GetDungeonDifficulty(), true, target); + + // we are in an instance, and can only summon players in our group with us as leader + if (!handler->GetSession()->GetPlayer()->GetGroup() || !target->GetGroup() || + (target->GetGroup()->GetLeaderGUID() != handler->GetSession()->GetPlayer()->GetGUID()) || + (handler->GetSession()->GetPlayer()->GetGroup()->GetLeaderGUID() != handler->GetSession()->GetPlayer()->GetGUID())) + // the last check is a bit excessive, but let it be, just in case + { + handler->PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST, nameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + } + + handler->PSendSysMessage(LANG_SUMMONING, nameLink.c_str(), ""); + if (handler->needReportToTarget(target)) + ChatHandler(target->GetSession()).PSendSysMessage(LANG_SUMMONED_BY, handler->playerLink(_player->GetName()).c_str()); + + // stop flight if need + if (target->IsInFlight()) + { + target->GetMotionMaster()->MovementExpired(); + target->CleanupAfterTaxiFlight(); + } + // save only in non-flight case + else + target->SaveRecallPosition(); + + // before GM + float x, y, z; + handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, target->GetObjectSize()); + target->TeleportTo(handler->GetSession()->GetPlayer()->GetMapId(), x, y, z, target->GetOrientation()); + target->SetPhaseMask(handler->GetSession()->GetPlayer()->GetPhaseMask(), false); + } + else + { + // check offline security + if (handler->HasLowerSecurity(NULL, targetGuid)) + return false; + + std::string nameLink = handler->playerLink(targetName); + + handler->PSendSysMessage(LANG_SUMMONING, nameLink.c_str(), handler->GetTrinityString(LANG_OFFLINE)); + + // in point where GM stay + Player::SavePositionInDB(handler->GetSession()->GetPlayer()->GetMapId(), + handler->GetSession()->GetPlayer()->GetPositionX(), + handler->GetSession()->GetPlayer()->GetPositionY(), + handler->GetSession()->GetPlayer()->GetPositionZ(), + handler->GetSession()->GetPlayer()->GetOrientation(), + handler->GetSession()->GetPlayer()->GetZoneId(), + targetGuid); + } + + return true; + } + // Summon group of player + static bool HandleGroupSummonCommand(ChatHandler* handler, char const* args) + { + Player* target; + if (!handler->extractPlayerTarget((char*)args, &target)) + return false; + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + Group* group = target->GetGroup(); + + std::string nameLink = handler->GetNameLink(target); + + if (!group) + { + handler->PSendSysMessage(LANG_NOT_IN_GROUP, nameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + Map* gmMap = handler->GetSession()->GetPlayer()->GetMap(); + bool toInstance = gmMap->Instanceable(); + + // we are in instance, and can summon only player in our group with us as lead + if (toInstance && ( + !handler->GetSession()->GetPlayer()->GetGroup() || (group->GetLeaderGUID() != handler->GetSession()->GetPlayer()->GetGUID()) || + (handler->GetSession()->GetPlayer()->GetGroup()->GetLeaderGUID() != handler->GetSession()->GetPlayer()->GetGUID()))) + // the last check is a bit excessive, but let it be, just in case + { + handler->SendSysMessage(LANG_CANNOT_SUMMON_TO_INST); + handler->SetSentErrorMessage(true); + return false; + } + + for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player* player = itr->GetSource(); + + if (!player || player == handler->GetSession()->GetPlayer() || !player->GetSession()) + continue; + + // check online security + if (handler->HasLowerSecurity(player, 0)) + return false; + + std::string plNameLink = handler->GetNameLink(player); + + if (player->IsBeingTeleported() == true) + { + handler->PSendSysMessage(LANG_IS_TELEPORTED, plNameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + if (toInstance) + { + Map* playerMap = player->GetMap(); + + if (playerMap->Instanceable() && playerMap->GetInstanceId() != gmMap->GetInstanceId()) + { + // cannot summon from instance to instance + handler->PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST, plNameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + } + + handler->PSendSysMessage(LANG_SUMMONING, plNameLink.c_str(), ""); + if (handler->needReportToTarget(player)) + ChatHandler(player->GetSession()).PSendSysMessage(LANG_SUMMONED_BY, handler->GetNameLink().c_str()); + + // stop flight if need + if (player->IsInFlight()) + { + player->GetMotionMaster()->MovementExpired(); + player->CleanupAfterTaxiFlight(); + } + // save only in non-flight case + else + player->SaveRecallPosition(); + + // before GM + float x, y, z; + handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, player->GetObjectSize()); + player->TeleportTo(handler->GetSession()->GetPlayer()->GetMapId(), x, y, z, player->GetOrientation()); + } + + return true; + } + + static bool HandleCommandsCommand(ChatHandler* handler, char const* /*args*/) + { + handler->ShowHelpForCommand(handler->getCommandTable(), ""); + return true; + } + + static bool HandleDieCommand(ChatHandler* handler, char const* /*args*/) + { + Unit* target = handler->getSelectedUnit(); + + if (!target || !handler->GetSession()->GetPlayer()->GetTarget()) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + if (target->GetTypeId() == TYPEID_PLAYER) + { + if (handler->HasLowerSecurity(target->ToPlayer(), 0, false)) + return false; + } + + if (target->IsAlive()) + { + if (sWorld->getBoolConfig(CONFIG_DIE_COMMAND_MODE)) + { + if (target->GetTypeId() == TYPEID_UNIT && handler->GetSession()->GetSecurity() == SEC_CONSOLE) // pussywizard + target->ToCreature()->LowerPlayerDamageReq(target->GetMaxHealth()); + Unit::Kill(handler->GetSession()->GetPlayer(), target); + } + else + Unit::DealDamage(handler->GetSession()->GetPlayer(), target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false, true); + } + + return true; + } + + static bool HandleReviveCommand(ChatHandler* handler, char const* args) + { + Player* target; + uint64 targetGuid; + if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid)) + return false; + + if (target) + { + target->ResurrectPlayer(!AccountMgr::IsPlayerAccount(target->GetSession()->GetSecurity()) ? 1.0f : 0.5f); + target->SpawnCorpseBones(); + target->SaveToDB(false, false); + } + else + // will resurrected at login without corpse + sObjectAccessor->ConvertCorpseForPlayer(targetGuid); + + return true; + } + + static bool HandleDismountCommand(ChatHandler* handler, char const* /*args*/) + { + Player* player = handler->GetSession()->GetPlayer(); + + // If player is not mounted, so go out :) + if (!player->IsMounted()) + { + handler->SendSysMessage(LANG_CHAR_NON_MOUNTED); + handler->SetSentErrorMessage(true); + return false; + } + + if (player->IsInFlight()) + { + handler->SendSysMessage(LANG_YOU_IN_FLIGHT); + handler->SetSentErrorMessage(true); + return false; + } + + player->Dismount(); + player->RemoveAurasByType(SPELL_AURA_MOUNTED); + return true; + } + + static bool HandleGUIDCommand(ChatHandler* handler, char const* /*args*/) + { + uint64 guid = handler->GetSession()->GetPlayer()->GetTarget(); + + if (guid == 0) + { + handler->SendSysMessage(LANG_NO_SELECTION); + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage(LANG_OBJECT_GUID, GUID_LOPART(guid), GUID_HIPART(guid)); + return true; + } + + static bool HandleHelpCommand(ChatHandler* handler, char const* args) + { + char const* cmd = strtok((char*)args, " "); + if (!cmd) + { + handler->ShowHelpForCommand(handler->getCommandTable(), "help"); + handler->ShowHelpForCommand(handler->getCommandTable(), ""); + } + else + { + if (!handler->ShowHelpForCommand(handler->getCommandTable(), cmd)) + handler->SendSysMessage(LANG_NO_HELP_CMD); + } + + return true; + } + // move item to other slot + static bool HandleItemMoveCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + char const* param1 = strtok((char*)args, " "); + if (!param1) + return false; + + char const* param2 = strtok(NULL, " "); + if (!param2) + return false; + + uint8 srcSlot = uint8(atoi(param1)); + uint8 dstSlot = uint8(atoi(param2)); + + if (srcSlot == dstSlot) + return true; + + if (!handler->GetSession()->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0, srcSlot, true)) + return false; + + if (!handler->GetSession()->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); + + handler->GetSession()->GetPlayer()->SwapItem(src, dst); + + return true; + } + + static bool HandleCooldownCommand(ChatHandler* handler, char const* args) + { + Player* target = handler->getSelectedPlayer(); + if (!target) + { + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + + std::string nameLink = handler->GetNameLink(target); + + if (!*args) + { + target->RemoveAllSpellCooldown(); + handler->PSendSysMessage(LANG_REMOVEALL_COOLDOWN, nameLink.c_str()); + } + else + { + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spellIid = handler->extractSpellIdFromLink((char*)args); + if (!spellIid) + return false; + + if (!sSpellMgr->GetSpellInfo(spellIid)) + { + handler->PSendSysMessage(LANG_UNKNOWN_SPELL, target == handler->GetSession()->GetPlayer() ? handler->GetTrinityString(LANG_YOU) : nameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + target->RemoveSpellCooldown(spellIid, true); + handler->PSendSysMessage(LANG_REMOVE_COOLDOWN, spellIid, target == handler->GetSession()->GetPlayer() ? handler->GetTrinityString(LANG_YOU) : nameLink.c_str()); + } + return true; + } + + static bool HandleGetDistanceCommand(ChatHandler* handler, char const* args) + { + WorldObject* obj = NULL; + + if (*args) + { + uint64 guid = handler->extractGuidFromLink((char*)args); + if (guid) + obj = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*handler->GetSession()->GetPlayer(), guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); + + if (!obj) + { + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + } + else + { + obj = handler->getSelectedUnit(); + + if (!obj) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + } + + handler->PSendSysMessage(LANG_DISTANCE, handler->GetSession()->GetPlayer()->GetDistance(obj), handler->GetSession()->GetPlayer()->GetDistance2d(obj), handler->GetSession()->GetPlayer()->GetExactDist(obj), handler->GetSession()->GetPlayer()->GetExactDist2d(obj)); + return true; + } + // Teleport player to last position + static bool HandleRecallCommand(ChatHandler* handler, char const* args) + { + Player* target; + if (!handler->extractPlayerTarget((char*)args, &target)) + return false; + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + if (target->IsBeingTeleported()) + { + handler->PSendSysMessage(LANG_IS_TELEPORTED, handler->GetNameLink(target).c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + // stop flight if need + if (target->IsInFlight()) + { + target->GetMotionMaster()->MovementExpired(); + target->CleanupAfterTaxiFlight(); + } + + target->TeleportTo(target->m_recallMap, target->m_recallX, target->m_recallY, target->m_recallZ, target->m_recallO); + return true; + } + + static bool HandleSaveCommand(ChatHandler* handler, char const* /*args*/) + { + // pussywizard: fully disabled on 28.12.2011, but disabled it "silently" + return true; + } + + // Save all players in the world + static bool HandleSaveAllCommand(ChatHandler* handler, char const* /*args*/) + { + sObjectAccessor->SaveAllPlayers(); + handler->SendSysMessage(LANG_PLAYERS_SAVED); + return true; + } + + // kick player + static bool HandleKickPlayerCommand(ChatHandler* handler, char const* args) + { + Player* target = NULL; + std::string playerName; + if (!handler->extractPlayerTarget((char*)args, &target, NULL, &playerName)) + return false; + + if (handler->GetSession() && target == handler->GetSession()->GetPlayer()) + { + handler->SendSysMessage(LANG_COMMAND_KICKSELF); + handler->SetSentErrorMessage(true); + return false; + } + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + if (sWorld->getBoolConfig(CONFIG_SHOW_KICK_IN_WORLD)) + sWorld->SendWorldText(LANG_COMMAND_KICKMESSAGE, playerName.c_str()); + else + handler->PSendSysMessage(LANG_COMMAND_KICKMESSAGE, playerName.c_str()); + + target->GetSession()->KickPlayer(); + + return true; + } + + static bool HandleUnstuckCommand(ChatHandler* handler, char const* args) + { + //No args required for players + if (handler->GetSession() && AccountMgr::IsPlayerAccount(handler->GetSession()->GetSecurity())) + { + // 7355: "Stuck" + if (Player* player = handler->GetSession()->GetPlayer()) + player->CastSpell(player, 7355, false); + return true; + } + + if (!*args) + return false; + + char* player_str = strtok((char*)args, " "); + if (!player_str) + return false; + + std::string location_str = "inn"; + if (char const* loc = strtok(NULL, " ")) + location_str = loc; + + Player* player = NULL; + if (!handler->extractPlayerTarget(player_str, &player)) + return false; + + if (player->IsInFlight() || player->IsInCombat()) + { + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(7355); + if (!spellInfo) + return false; + + if (Player* caster = handler->GetSession()->GetPlayer()) + Spell::SendCastResult(caster, spellInfo, 0, SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW); + + return false; + } + + if (location_str == "inn") + { + player->TeleportTo(player->m_homebindMapId, player->m_homebindX, player->m_homebindY, player->m_homebindZ, player->GetOrientation()); + return true; + } + + if (location_str == "graveyard") + { + player->RepopAtGraveyard(); + return true; + } + + if (location_str == "startzone") + { + player->TeleportTo(player->GetStartPosition()); + return true; + } + + //Not a supported argument + return false; + + } + // Enable on\off all taxi paths + static bool HandleTaxiCheatCommand(ChatHandler* handler, char const* args) + { + if (!*args) + { + handler->SendSysMessage(LANG_USE_BOL); + handler->SetSentErrorMessage(true); + return false; + } + + std::string argStr = (char*)args; + + Player* chr = handler->getSelectedPlayer(); + + if (!chr) + chr = handler->GetSession()->GetPlayer(); + else if (handler->HasLowerSecurity(chr, 0)) // check online security + return false; + + if (argStr == "on") + { + chr->SetTaxiCheater(true); + handler->PSendSysMessage(LANG_YOU_GIVE_TAXIS, handler->GetNameLink(chr).c_str()); + if (handler->needReportToTarget(chr)) + ChatHandler(chr->GetSession()).PSendSysMessage(LANG_YOURS_TAXIS_ADDED, handler->GetNameLink().c_str()); + return true; + } + + if (argStr == "off") + { + chr->SetTaxiCheater(false); + handler->PSendSysMessage(LANG_YOU_REMOVE_TAXIS, handler->GetNameLink(chr).c_str()); + if (handler->needReportToTarget(chr)) + ChatHandler(chr->GetSession()).PSendSysMessage(LANG_YOURS_TAXIS_REMOVED, handler->GetNameLink().c_str()); + + return true; + } + + handler->SendSysMessage(LANG_USE_BOL); + handler->SetSentErrorMessage(true); + + return false; + } + + static bool HandleLinkGraveCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + char* px = strtok((char*)args, " "); + if (!px) + return false; + + uint32 graveyardId = uint32(atoi(px)); + + TeamId teamId; + + char* px2 = strtok(NULL, " "); + + if (!px2) + teamId = TEAM_NEUTRAL; + else if (strncmp(px2, "horde", 6) == 0) + teamId = TEAM_HORDE; + else if (strncmp(px2, "alliance", 9) == 0) + teamId = TEAM_ALLIANCE; + else + return false; + + WorldSafeLocsEntry const* graveyard = sWorldSafeLocsStore.LookupEntry(graveyardId); + + if (!graveyard) + { + handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST, graveyardId); + handler->SetSentErrorMessage(true); + return false; + } + + Player* player = handler->GetSession()->GetPlayer(); + + uint32 zoneId = player->GetZoneId(); + + AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(zoneId); + if (!areaEntry || areaEntry->zone !=0) + { + handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, graveyardId, zoneId); + handler->SetSentErrorMessage(true); + return false; + } + + if (sObjectMgr->AddGraveyardLink(graveyardId, zoneId, teamId)) + handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, graveyardId, zoneId); + else + handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, graveyardId, zoneId); + + return true; + } + + static bool HandleNearGraveCommand(ChatHandler* handler, char const* args) + { + TeamId teamId; + + size_t argStr = strlen(args); + + if (!*args) + teamId = TEAM_NEUTRAL; + else if (strncmp((char*)args, "horde", argStr) == 0) + teamId = TEAM_HORDE; + else if (strncmp((char*)args, "alliance", argStr) == 0) + teamId = TEAM_ALLIANCE; + else + return false; + + Player* player = handler->GetSession()->GetPlayer(); + uint32 zone_id = player->GetZoneId(); + + WorldSafeLocsEntry const* graveyard = sObjectMgr->GetClosestGraveyard(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), teamId); + + if (graveyard) + { + uint32 graveyardId = graveyard->ID; + + GraveyardData const* data = sObjectMgr->FindGraveyardData(graveyardId, zone_id); + if (!data) + { + handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR, graveyardId); + handler->SetSentErrorMessage(true); + return false; + } + + std::string team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_NOTEAM); + + if (data->teamId == TEAM_NEUTRAL) + team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_ANY); + else if (data->teamId == TEAM_HORDE) + team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_HORDE); + else if (data->teamId == TEAM_ALLIANCE) + team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_ALLIANCE); + + handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, graveyardId, team_name.c_str(), zone_id); + } + else + { + std::string team_name; + + if (teamId == TEAM_NEUTRAL) + team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_ANY); + else if (teamId == TEAM_HORDE) + team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_HORDE); + else if (teamId == TEAM_ALLIANCE) + team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_ALLIANCE); + + //if (team == ~uint32(0)) + // handler->PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, zone_id); + //else + handler->PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, zone_id, team_name.c_str()); + } + + return true; + } + + static bool HandleExploreCheatCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + int32 flag = int32(atoi((char*)args)); + + Player* playerTarget = handler->getSelectedPlayer(); + if (!playerTarget) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + if (flag != 0) + { + handler->PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, handler->GetNameLink(playerTarget).c_str()); + if (handler->needReportToTarget(playerTarget)) + ChatHandler(playerTarget->GetSession()).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL, handler->GetNameLink().c_str()); + } + else + { + handler->PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, handler->GetNameLink(playerTarget).c_str()); + if (handler->needReportToTarget(playerTarget)) + ChatHandler(playerTarget->GetSession()).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING, handler->GetNameLink().c_str()); + } + + for (uint8 i = 0; i < PLAYER_EXPLORED_ZONES_SIZE; ++i) + { + if (flag != 0) + handler->GetSession()->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i, 0xFFFFFFFF); + else + handler->GetSession()->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i, 0); + } + + return true; + } + + static bool HandleShowAreaCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + Player* playerTarget = handler->getSelectedPlayer(); + if (!playerTarget) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + int32 area = GetAreaFlagByAreaID(atoi((char*)args)); + int32 offset = area / 32; + uint32 val = uint32((1 << (area % 32))); + + if (area<0 || offset >= PLAYER_EXPLORED_ZONES_SIZE) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 currFields = playerTarget->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset); + playerTarget->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, uint32((currFields | val))); + + handler->SendSysMessage(LANG_EXPLORE_AREA); + return true; + } + + static bool HandleHideAreaCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + Player* playerTarget = handler->getSelectedPlayer(); + if (!playerTarget) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + int32 area = GetAreaFlagByAreaID(atoi((char*)args)); + int32 offset = area / 32; + uint32 val = uint32((1 << (area % 32))); + + if (area < 0 || offset >= PLAYER_EXPLORED_ZONES_SIZE) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 currFields = playerTarget->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset); + playerTarget->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, uint32((currFields ^ val))); + + handler->SendSysMessage(LANG_UNEXPLORE_AREA); + return true; + } + + static bool HandleAddItemCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + uint32 itemId = 0; + + if (args[0] == '[') // [name] manual form + { + char const* itemNameStr = strtok((char*)args, "]"); + + if (itemNameStr && itemNameStr[0]) + { + std::string itemName = itemNameStr+1; + WorldDatabase.EscapeString(itemName); + + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_ITEM_TEMPLATE_BY_NAME); + stmt->setString(0, itemName); + PreparedQueryResult result = WorldDatabase.Query(stmt); + + if (!result) + { + handler->PSendSysMessage(LANG_COMMAND_COULDNOTFIND, itemNameStr+1); + handler->SetSentErrorMessage(true); + return false; + } + itemId = result->Fetch()->GetUInt32(); + } + else + return false; + } + else // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r + { + char const* id = handler->extractKeyFromLink((char*)args, "Hitem"); + if (!id) + return false; + itemId = uint32(atol(id)); + } + + char const* ccount = strtok(NULL, " "); + + int32 count = 1; + + if (ccount) + count = strtol(ccount, NULL, 10); + + if (count == 0) + count = 1; + + Player* player = handler->GetSession()->GetPlayer(); + Player* playerTarget = handler->getSelectedPlayer(); + if (!playerTarget) + playerTarget = player; + + ;//sLog->outDetail(handler->GetTrinityString(LANG_ADDITEM), itemId, count); + + ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemId); + if (!itemTemplate) + { + handler->PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId); + handler->SetSentErrorMessage(true); + return false; + } + + // Subtract + if (count < 0) + { + playerTarget->DestroyItemCount(itemId, -count, true, false); + handler->PSendSysMessage(LANG_REMOVEITEM, itemId, -count, handler->GetNameLink(playerTarget).c_str()); + return true; + } + + /* [AC] Sunwell hack + if (handler->GetSession()->GetSecurity() < SEC_ADMINISTRATOR) + { + handler->PSendSysMessage("You may only remove items. Adding items is available for higher GMLevel."); + return false; + } + */ + + // Adding items + uint32 noSpaceForCount = 0; + + // check space and find places + ItemPosCountVec dest; + InventoryResult msg = playerTarget->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount); + if (msg != EQUIP_ERR_OK) // convert to possible store amount + count -= noSpaceForCount; + + if (count == 0 || dest.empty()) // can't add any + { + handler->PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount); + handler->SetSentErrorMessage(true); + return false; + } + + Item* item = playerTarget->StoreNewItem(dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId)); + + // remove binding (let GM give it to another player later) + if (player == playerTarget) + for (ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr) + if (Item* item1 = player->GetItemByPos(itr->pos)) + item1->SetBinding(false); + + if (count > 0 && item) + { + player->SendNewItem(item, count, false, true); + if (player != playerTarget) + playerTarget->SendNewItem(item, count, true, false); + } + + if (noSpaceForCount > 0) + handler->PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount); + + return true; + } + + static bool HandleAddItemSetCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + char const* id = handler->extractKeyFromLink((char*)args, "Hitemset"); // number or [name] Shift-click form |color|Hitemset:itemset_id|h[name]|h|r + if (!id) + return false; + + uint32 itemSetId = atol(id); + + // prevent generation all items with itemset field value '0' + if (itemSetId == 0) + { + handler->PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND, itemSetId); + handler->SetSentErrorMessage(true); + return false; + } + + Player* player = handler->GetSession()->GetPlayer(); + Player* playerTarget = handler->getSelectedPlayer(); + if (!playerTarget) + playerTarget = player; + + ;//sLog->outDetail(handler->GetTrinityString(LANG_ADDITEMSET), itemSetId); + + bool found = false; + ItemTemplateContainer const* its = sObjectMgr->GetItemTemplateStore(); + for (ItemTemplateContainer::const_iterator itr = its->begin(); itr != its->end(); ++itr) + { + if (itr->second.ItemSet == itemSetId) + { + found = true; + ItemPosCountVec dest; + InventoryResult msg = playerTarget->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itr->second.ItemId, 1); + if (msg == EQUIP_ERR_OK) + { + Item* item = playerTarget->StoreNewItem(dest, itr->second.ItemId, true); + + // remove binding (let GM give it to another player later) + if (player == playerTarget) + item->SetBinding(false); + + player->SendNewItem(item, 1, false, true); + if (player != playerTarget) + playerTarget->SendNewItem(item, 1, true, false); + } + else + { + player->SendEquipError(msg, NULL, NULL, itr->second.ItemId); + handler->PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itr->second.ItemId, 1); + } + } + } + + if (!found) + { + handler->PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND, itemSetId); + handler->SetSentErrorMessage(true); + return false; + } + + return true; + } + + static bool HandleBankCommand(ChatHandler* handler, char const* /*args*/) + { + handler->GetSession()->SendShowBank(handler->GetSession()->GetPlayer()->GetGUID()); + return true; + } + + static bool HandleChangeWeather(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + // Weather is OFF + if (!sWorld->getBoolConfig(CONFIG_WEATHER)) + { + handler->SendSysMessage(LANG_WEATHER_DISABLED); + handler->SetSentErrorMessage(true); + return false; + } + + // *Change the weather of a cell + char const* px = strtok((char*)args, " "); + char const* py = strtok(NULL, " "); + + if (!px || !py) + return false; + + uint32 type = uint32(atoi(px)); //0 to 3, 0: fine, 1: rain, 2: snow, 3: sand + float grade = float(atof(py)); //0 to 1, sending -1 is instand good weather + + Player* player = handler->GetSession()->GetPlayer(); + uint32 zoneid = player->GetZoneId(); + + Weather* weather = WeatherMgr::FindWeather(zoneid); + + if (!weather) + weather = WeatherMgr::AddWeather(zoneid); + if (!weather) + { + handler->SendSysMessage(LANG_NO_WEATHER); + handler->SetSentErrorMessage(true); + return false; + } + + weather->SetWeather(WeatherType(type), grade); + + return true; + } + + + static bool HandleMaxSkillCommand(ChatHandler* handler, char const* /*args*/) + { + Player* SelectedPlayer = handler->getSelectedPlayer(); + if (!SelectedPlayer) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + // each skills that have max skill value dependent from level seted to current level max skill value + SelectedPlayer->UpdateSkillsToMaxSkillsForLevel(); + return true; + } + + static bool HandleSetSkillCommand(ChatHandler* handler, char const* args) + { + // number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r + char const* skillStr = handler->extractKeyFromLink((char*)args, "Hskill"); + if (!skillStr) + return false; + + char const* levelStr = strtok(NULL, " "); + if (!levelStr) + return false; + + char const* maxPureSkill = strtok(NULL, " "); + + int32 skill = atoi(skillStr); + if (skill <= 0) + { + handler->PSendSysMessage(LANG_INVALID_SKILL_ID, skill); + handler->SetSentErrorMessage(true); + return false; + } + + int32 level = uint32(atol(levelStr)); + + Player* target = handler->getSelectedPlayer(); + if (!target) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + SkillLineEntry const* skillLine = sSkillLineStore.LookupEntry(skill); + if (!skillLine) + { + handler->PSendSysMessage(LANG_INVALID_SKILL_ID, skill); + handler->SetSentErrorMessage(true); + return false; + } + + bool targetHasSkill = target->GetSkillValue(skill); + + // If our target does not yet have the skill they are trying to add to them, the chosen level also becomes + // the max level of the new profession. + uint16 max = maxPureSkill ? atol (maxPureSkill) : targetHasSkill ? target->GetPureMaxSkillValue(skill) : uint16(level); + + if (level <= 0 || level > max || max <= 0) + return false; + + // If the player has the skill, we get the current skill step. If they don't have the skill, we + // add the skill to the player's book with step 1 (which is the first rank, in most cases something + // like 'Apprentice <skill>'. + target->SetSkill(skill, targetHasSkill ? target->GetSkillStep(skill) : 1, level, max); + handler->PSendSysMessage(LANG_SET_SKILL, skill, skillLine->name[handler->GetSessionDbcLocale()], handler->GetNameLink(target).c_str(), level, max); + return true; + } + + // show info of player + static bool HandlePInfoCommand(ChatHandler* handler, char const* args) + { + Player* target; + uint64 targetGuid; + std::string targetName; + + uint32 parseGUID = MAKE_NEW_GUID(atol((char*)args), 0, HIGHGUID_PLAYER); + + if (sObjectMgr->GetPlayerNameByGUID(parseGUID, targetName)) + { + target = ObjectAccessor::FindPlayerInOrOutOfWorld(MAKE_NEW_GUID(parseGUID, 0, HIGHGUID_PLAYER)); + targetGuid = parseGUID; + } + 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; + 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; + } + + // get additional information from Player object + if (target) + { + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + accId = target->GetSession()->GetAccountId(); + money = target->GetMoney(); + totalPlayerTime = 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 (handler->HasLowerSecurity(NULL, targetGuid)) + return false; + + PreparedStatement* 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(); + } + + 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); + stmt->setInt32(0, int32(realmID)); + stmt->setUInt32(1, accId); + PreparedQueryResult result = LoginDatabase.Query(stmt); + + if (result) + { + 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 = "-"; + + if (!handler->GetSession() || handler->GetSession()->GetSecurity() >= AccountTypes(security)) + { + lastIp = fields[3].GetString(); + lastLogin = fields[4].GetString(); + + uint32 ip = inet_addr(lastIp.c_str()); +#if TRINITY_ENDIAN == BIGENDIAN + EndianConvertReverse(ip); +#endif + + } + else + { + lastIp = "-"; + lastLogin = "-"; + } + } + + 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); + if (!result2) + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PINFO_BANS); + stmt->setUInt32(0, GUID_LOPART(targetGuid)); + result2 = CharacterDatabase.Query(stmt); + } + + if (result2) + { + Field* fields = result2->Fetch(); + banTime = int64(fields[1].GetUInt64() ? 0 : fields[0].GetUInt32()); + bannedby = fields[2].GetString(); + banreason = fields[3].GetString(); + } + + if (muteTime > 0 && muteTime > time(NULL)) + handler->PSendSysMessage(LANG_PINFO_MUTE, secsToTimeString(muteTime - time(NULL), true).c_str(), muteBy.c_str(), muteReason.c_str()); + + if (banTime >= 0) + handler->PSendSysMessage(LANG_PINFO_BAN, banTime > 0 ? secsToTimeString(banTime - time(NULL), true).c_str() : "permanently", bannedby.c_str(), banreason.c_str()); + + std::string raceStr, ClassStr; + switch (race) + { + case RACE_HUMAN: + raceStr = "Human"; + break; + case RACE_ORC: + raceStr = "Orc"; + break; + case RACE_DWARF: + raceStr = "Dwarf"; + break; + case RACE_NIGHTELF: + raceStr = "Night Elf"; + break; + case RACE_UNDEAD_PLAYER: + raceStr = "Undead"; + break; + case RACE_TAUREN: + raceStr = "Tauren"; + break; + case RACE_GNOME: + raceStr = "Gnome"; + break; + case RACE_TROLL: + raceStr = "Troll"; + break; + case RACE_BLOODELF: + raceStr = "Blood Elf"; + break; + case RACE_DRAENEI: + raceStr = "Draenei"; + break; + } + + switch (Class) + { + case CLASS_WARRIOR: + ClassStr = "Warrior"; + break; + case CLASS_PALADIN: + ClassStr = "Paladin"; + break; + case CLASS_HUNTER: + ClassStr = "Hunter"; + break; + case CLASS_ROGUE: + ClassStr = "Rogue"; + break; + case CLASS_PRIEST: + ClassStr = "Priest"; + break; + case CLASS_DEATH_KNIGHT: + ClassStr = "Death Knight"; + break; + case CLASS_SHAMAN: + ClassStr = "Shaman"; + break; + case CLASS_MAGE: + ClassStr = "Mage"; + break; + case CLASS_WARLOCK: + ClassStr = "Warlock"; + break; + case CLASS_DRUID: + ClassStr = "Druid"; + break; + } + + 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); + + // Add map, zone, subzone and phase to output + int locale = handler->GetSessionDbcLocale(); + std::string areaName = "<unknown>"; + 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()) + 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); + } + else + handler->PSendSysMessage(LANG_PINFO_MAP_OFFLINE, map->name[locale], areaName.c_str()); + + 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"); + } + + return true; + } + + static bool HandleRespawnCommand(ChatHandler* handler, char const* /*args*/) + { + Player* player = handler->GetSession()->GetPlayer(); + + // accept only explicitly selected target (not implicitly self targeting case) + Unit* target = handler->getSelectedUnit(); + if (player->GetTarget() && target) + { + if (target->GetTypeId() != TYPEID_UNIT || target->IsPet()) + { + handler->SendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + if (target->isDead()) + target->ToCreature()->Respawn(); + return true; + } + + CellCoord p(Trinity::ComputeCellCoord(player->GetPositionX(), player->GetPositionY())); + Cell cell(p); + cell.SetNoCreate(); + + Trinity::RespawnDo u_do; + Trinity::WorldObjectWorker<Trinity::RespawnDo> worker(player, u_do); + + TypeContainerVisitor<Trinity::WorldObjectWorker<Trinity::RespawnDo>, GridTypeMapContainer > obj_worker(worker); + cell.Visit(p, obj_worker, *player->GetMap(), *player, player->GetGridActivationRange()); + + return true; + } + // mute player for some times + static bool HandleMuteCommand(ChatHandler* handler, char const* args) + { + char* nameStr; + char* delayStr; + handler->extractOptFirstArg((char*)args, &nameStr, &delayStr); + if (!delayStr) + return false; + + char const* muteReason = strtok(NULL, "\r"); + std::string muteReasonStr = "No reason"; + if (muteReason != NULL) + muteReasonStr = muteReason; + + Player* target; + uint64 targetGuid; + std::string targetName; + if (!handler->extractPlayerTarget(nameStr, &target, &targetGuid, &targetName)) + return false; + + uint32 accountId = target ? target->GetSession()->GetAccountId() : sObjectMgr->GetPlayerAccountIdByGUID(targetGuid); + + // 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 (handler->HasLowerSecurity (target, targetGuid, true)) + return false; + + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME); + std::string muteBy = ""; + if (handler->GetSession()) + muteBy = handler->GetSession()->GetPlayerName(); + else + muteBy = "Console"; + + 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->GetSession()).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notSpeakTime, muteBy.c_str(), 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->setString(1, muteReasonStr.c_str()); + stmt->setString(2, muteBy.c_str()); + stmt->setUInt32(3, accountId); + LoginDatabase.Execute(stmt); + std::string nameLink = handler->playerLink(targetName); + + // pussywizard: notify all online GMs + TRINITY_READ_GUARD(HashMapHolder<Player>::LockType, *HashMapHolder<Player>::GetLock()); + HashMapHolder<Player>::MapType const& m = sObjectAccessor->GetPlayers(); + for (HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr) + if (itr->second->GetSession()->GetSecurity()) + ChatHandler(itr->second->GetSession()).PSendSysMessage(target ? LANG_YOU_DISABLE_CHAT : LANG_COMMAND_DISABLE_CHAT_DELAYED, (handler->GetSession() ? handler->GetSession()->GetPlayerName().c_str() : "Console"), nameLink.c_str(), notSpeakTime, muteReasonStr.c_str()); + + return true; + } + + // unmute player + static bool HandleUnmuteCommand(ChatHandler* handler, char const* args) + { + Player* target; + uint64 targetGuid; + std::string targetName; + if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) + return false; + + uint32 accountId = target ? target->GetSession()->GetAccountId() : sObjectMgr->GetPlayerAccountIdByGUID(targetGuid); + + // 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 (handler->HasLowerSecurity (target, targetGuid, true)) + return false; + + if (target) + { + if (target->CanSpeak()) + { + handler->SendSysMessage(LANG_CHAT_ALREADY_ENABLED); + handler->SetSentErrorMessage(true); + return false; + } + + target->GetSession()->m_muteTime = 0; + } + + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME); + stmt->setInt64(0, 0); + stmt->setString(1, ""); + stmt->setString(2, ""); + stmt->setUInt32(3, accountId); + LoginDatabase.Execute(stmt); + + if (target) + ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOUR_CHAT_ENABLED); + + std::string nameLink = handler->playerLink(targetName); + + handler->PSendSysMessage(LANG_YOU_ENABLE_CHAT, nameLink.c_str()); + + return true; + } + + + static bool HandleMovegensCommand(ChatHandler* handler, char const* /*args*/) + { + Unit* unit = handler->getSelectedUnit(); + if (!unit) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage(LANG_MOVEGENS_LIST, (unit->GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature"), unit->GetGUIDLow()); + + MotionMaster* motionMaster = unit->GetMotionMaster(); + float x, y, z; + motionMaster->GetDestination(x, y, z); + + for (uint8 i = 0; i < MAX_MOTION_SLOT; ++i) + { + MovementGenerator* movementGenerator = motionMaster->GetMotionSlot(i); + if (!movementGenerator) + { + handler->SendSysMessage("Empty"); + continue; + } + + switch (movementGenerator->GetMovementGeneratorType()) + { + case IDLE_MOTION_TYPE: + handler->SendSysMessage(LANG_MOVEGENS_IDLE); + break; + case RANDOM_MOTION_TYPE: + handler->SendSysMessage(LANG_MOVEGENS_RANDOM); + break; + case WAYPOINT_MOTION_TYPE: + handler->SendSysMessage(LANG_MOVEGENS_WAYPOINT); + break; + case ANIMAL_RANDOM_MOTION_TYPE: + handler->SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM); + break; + case CONFUSED_MOTION_TYPE: + handler->SendSysMessage(LANG_MOVEGENS_CONFUSED); + break; + case CHASE_MOTION_TYPE: + { + Unit* target = NULL; + if (unit->GetTypeId() == TYPEID_PLAYER) + target = static_cast<ChaseMovementGenerator<Player> const*>(movementGenerator)->GetTarget(); + else + target = static_cast<ChaseMovementGenerator<Creature> const*>(movementGenerator)->GetTarget(); + + if (!target) + handler->SendSysMessage(LANG_MOVEGENS_CHASE_NULL); + else if (target->GetTypeId() == TYPEID_PLAYER) + handler->PSendSysMessage(LANG_MOVEGENS_CHASE_PLAYER, target->GetName().c_str(), target->GetGUIDLow()); + else + handler->PSendSysMessage(LANG_MOVEGENS_CHASE_CREATURE, target->GetName().c_str(), target->GetGUIDLow()); + break; + } + case FOLLOW_MOTION_TYPE: + { + Unit* target = NULL; + if (unit->GetTypeId() == TYPEID_PLAYER) + target = static_cast<FollowMovementGenerator<Player> const*>(movementGenerator)->GetTarget(); + else + target = static_cast<FollowMovementGenerator<Creature> const*>(movementGenerator)->GetTarget(); + + if (!target) + handler->SendSysMessage(LANG_MOVEGENS_FOLLOW_NULL); + else if (target->GetTypeId() == TYPEID_PLAYER) + handler->PSendSysMessage(LANG_MOVEGENS_FOLLOW_PLAYER, target->GetName().c_str(), target->GetGUIDLow()); + else + handler->PSendSysMessage(LANG_MOVEGENS_FOLLOW_CREATURE, target->GetName().c_str(), target->GetGUIDLow()); + break; + } + case HOME_MOTION_TYPE: + { + if (unit->GetTypeId() == TYPEID_UNIT) + handler->PSendSysMessage(LANG_MOVEGENS_HOME_CREATURE, x, y, z); + else + handler->SendSysMessage(LANG_MOVEGENS_HOME_PLAYER); + break; + } + case FLIGHT_MOTION_TYPE: + handler->SendSysMessage(LANG_MOVEGENS_FLIGHT); + break; + case POINT_MOTION_TYPE: + { + handler->PSendSysMessage(LANG_MOVEGENS_POINT, x, y, z); + break; + } + case FLEEING_MOTION_TYPE: + handler->SendSysMessage(LANG_MOVEGENS_FEAR); + break; + case DISTRACT_MOTION_TYPE: + handler->SendSysMessage(LANG_MOVEGENS_DISTRACT); + break; + case EFFECT_MOTION_TYPE: + handler->SendSysMessage(LANG_MOVEGENS_EFFECT); + break; + default: + handler->PSendSysMessage(LANG_MOVEGENS_UNKNOWN, movementGenerator->GetMovementGeneratorType()); + break; + } + } + return true; + } + /* + ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator + Without this function 3rd party scripting library will get linking errors (unresolved external) + when attempting to use the PointMovementGenerator + */ + static bool HandleComeToMeCommand(ChatHandler* handler, char const* args) + { + char const* newFlagStr = strtok((char*)args, " "); + if (!newFlagStr) + return false; + + Creature* caster = handler->getSelectedCreature(); + if (!caster) + { + handler->SendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + Player* player = handler->GetSession()->GetPlayer(); + + caster->GetMotionMaster()->MovePoint(0, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()); + + return true; + } + + static bool HandleDamageCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + Unit* target = handler->getSelectedUnit(); + if (!target || !handler->GetSession()->GetPlayer()->GetTarget()) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + if (target->GetTypeId() == TYPEID_PLAYER) + { + if (handler->HasLowerSecurity(target->ToPlayer(), 0, false)) + return false; + } + + if (!target->IsAlive()) + return true; + + int32 damage_int = atoi(args); + if (damage_int <= 0) + return true; + + uint32 damage = damage_int; + + if (target->GetTypeId() == TYPEID_UNIT && handler->GetSession()->GetSecurity() == SEC_CONSOLE) // pussywizard + target->ToCreature()->LowerPlayerDamageReq(target->GetMaxHealth()); + Unit::DealDamage(handler->GetSession()->GetPlayer(), target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false, true); + if (target != handler->GetSession()->GetPlayer()) + handler->GetSession()->GetPlayer()->SendAttackStateUpdate (HITINFO_AFFECTS_VICTIM, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_HIT, 0); + return true; + } + + static bool HandleCombatStopCommand(ChatHandler* handler, char const* args) + { + Player* target = NULL; + + if (args && strlen(args) > 0) + { + target = ObjectAccessor::FindPlayerByName(args); + if (!target) + { + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + } + + if (!target) + { + if (!handler->extractPlayerTarget((char*)args, &target)) + return false; + } + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + target->CombatStop(); + target->getHostileRefManager().deleteReferences(); + return true; + } + + static bool HandleFlushArenaPointsCommand(ChatHandler* /*handler*/, char const* /*args*/) + { + sArenaTeamMgr->DistributeArenaPoints(); + return true; + } + + static bool HandleRepairitemsCommand(ChatHandler* handler, char const* args) + { + Player* target; + if (!handler->extractPlayerTarget((char*)args, &target)) + return false; + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + // Repair items + target->DurabilityRepairAll(false, 0, false); + + handler->PSendSysMessage(LANG_YOU_REPAIR_ITEMS, handler->GetNameLink(target).c_str()); + if (handler->needReportToTarget(target)) + ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED, handler->GetNameLink().c_str()); + + return true; + } + + static bool HandleWaterwalkCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + Player* player = handler->getSelectedPlayer(); + if (!player) + { + handler->PSendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + // check online security + if (handler->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 + { + handler->SendSysMessage(LANG_USE_BOL); + return false; + } + + handler->PSendSysMessage(LANG_YOU_SET_WATERWALK, args, handler->GetNameLink(player).c_str()); + if (handler->needReportToTarget(player)) + ChatHandler(player->GetSession()).PSendSysMessage(LANG_YOUR_WATERWALK_SET, args, handler->GetNameLink().c_str()); + return true; + } + + // Send mail by command + static bool HandleSendMailCommand(ChatHandler* handler, char const* args) + { + // format: name "subject text" "mail text" + Player* target; + uint64 targetGuid; + std::string targetName; + if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) + return false; + + char* tail1 = strtok(NULL, ""); + if (!tail1) + return false; + + char const* msgSubject = handler->extractQuotedArg(tail1); + if (!msgSubject) + return false; + + char* tail2 = strtok(NULL, ""); + if (!tail2) + return false; + + char const* msgText = handler->extractQuotedArg(tail2); + if (!msgText) + return false; + + // msgSubject, msgText isn't NUL after prev. check + std::string subject = msgSubject; + std::string text = msgText; + + // from console show not existed sender + MailSender sender(MAIL_NORMAL, handler->GetSession() ? handler->GetSession()->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM); + + //- TODO: Fix poor design + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + MailDraft(subject, text) + .SendMailTo(trans, MailReceiver(target, GUID_LOPART(targetGuid)), sender); + + CharacterDatabase.CommitTransaction(trans); + + std::string nameLink = handler->playerLink(targetName); + handler->PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); + return true; + } + // Send items by mail + static bool HandleSendItemsCommand(ChatHandler* handler, char const* args) + { + // format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12] + Player* receiver; + uint64 receiverGuid; + std::string receiverName; + if (!handler->extractPlayerTarget((char*)args, &receiver, &receiverGuid, &receiverName)) + return false; + + char* tail1 = strtok(NULL, ""); + if (!tail1) + return false; + + char const* msgSubject = handler->extractQuotedArg(tail1); + if (!msgSubject) + return false; + + char* tail2 = strtok(NULL, ""); + if (!tail2) + return false; + + char const* msgText = handler->extractQuotedArg(tail2); + if (!msgText) + return false; + + // msgSubject, msgText isn't NUL after prev. check + std::string subject = msgSubject; + std::string text = msgText; + + // extract items + typedef std::pair<uint32, uint32> ItemPair; + typedef std::list< ItemPair > ItemPairs; + ItemPairs items; + + // get all tail string + char* tail = strtok(NULL, ""); + + // get from tail next item str + while (char* itemStr = strtok(tail, " ")) + { + // and get new tail + tail = strtok(NULL, ""); + + // parse item str + char const* itemIdStr = strtok(itemStr, ":"); + char const* itemCountStr = strtok(NULL, " "); + + uint32 itemId = atoi(itemIdStr); + if (!itemId) + return false; + + ItemTemplate const* item_proto = sObjectMgr->GetItemTemplate(itemId); + if (!item_proto) + { + handler->PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 itemCount = itemCountStr ? atoi(itemCountStr) : 1; + if (itemCount < 1 || (item_proto->MaxCount > 0 && itemCount > uint32(item_proto->MaxCount))) + { + handler->PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, itemCount, itemId); + handler->SetSentErrorMessage(true); + return false; + } + + while (itemCount > item_proto->GetMaxStackSize()) + { + items.push_back(ItemPair(itemId, item_proto->GetMaxStackSize())); + itemCount -= item_proto->GetMaxStackSize(); + } + + items.push_back(ItemPair(itemId, itemCount)); + + if (items.size() > MAX_MAIL_ITEMS) + { + handler->PSendSysMessage(LANG_COMMAND_MAIL_ITEMS_LIMIT, MAX_MAIL_ITEMS); + handler->SetSentErrorMessage(true); + return false; + } + } + + // from console show not existed sender + MailSender sender(MAIL_NORMAL, handler->GetSession() ? handler->GetSession()->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM); + + // fill mail + MailDraft draft(subject, text); + + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + + for (ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr) + { + if (Item* item = Item::CreateItem(itr->first, itr->second, handler->GetSession() ? handler->GetSession()->GetPlayer() : 0)) + { + item->SaveToDB(trans); // save for prevent lost at next mail load, if send fail then item will deleted + draft.AddItem(item); + } + } + + draft.SendMailTo(trans, MailReceiver(receiver, GUID_LOPART(receiverGuid)), sender); + CharacterDatabase.CommitTransaction(trans); + + std::string nameLink = handler->playerLink(receiverName); + handler->PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); + return true; + } + /// Send money by mail + static bool HandleSendMoneyCommand(ChatHandler* handler, char const* args) + { + /// format: name "subject text" "mail text" money + + Player* receiver; + uint64 receiverGuid; + std::string receiverName; + if (!handler->extractPlayerTarget((char*)args, &receiver, &receiverGuid, &receiverName)) + return false; + + char* tail1 = strtok(NULL, ""); + if (!tail1) + return false; + + char* msgSubject = handler->extractQuotedArg(tail1); + if (!msgSubject) + return false; + + char* tail2 = strtok(NULL, ""); + if (!tail2) + return false; + + char* msgText = handler->extractQuotedArg(tail2); + if (!msgText) + return false; + + char* moneyStr = strtok(NULL, ""); + int32 money = moneyStr ? atoi(moneyStr) : 0; + if (money <= 0) + return false; + + // msgSubject, msgText isn't NUL after prev. check + std::string subject = msgSubject; + std::string text = msgText; + + // from console show not existed sender + MailSender sender(MAIL_NORMAL, handler->GetSession() ? handler->GetSession()->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM); + + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + + MailDraft(subject, text) + .AddMoney(money) + .SendMailTo(trans, MailReceiver(receiver, GUID_LOPART(receiverGuid)), sender); + + CharacterDatabase.CommitTransaction(trans); + + std::string nameLink = handler->playerLink(receiverName); + handler->PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); + return true; + } + /// Send a message to a player in game + static bool HandleSendMessageCommand(ChatHandler* handler, char const* args) + { + /// - Find the player + Player* player = NULL; + if (!handler->extractPlayerTarget((char*)args, &player)) + return false; + + if (!player) + return false; + + char* msgStr = strtok(NULL, ""); + if (!msgStr) + return false; + + /// - Send the message + // Use SendAreaTriggerMessage for fastest delivery. + player->GetSession()->SendAreaTriggerMessage("%s", msgStr); + player->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r"); + + // Confirmation message + std::string nameLink = handler->GetNameLink(player); + handler->PSendSysMessage(LANG_SENDMESSAGE, nameLink.c_str(), msgStr); + + return true; + } + + static bool HandleCreatePetCommand(ChatHandler* handler, char const* /*args*/) + { + Player* player = handler->GetSession()->GetPlayer(); + Creature* creatureTarget = handler->getSelectedCreature(); + + if (!creatureTarget || creatureTarget->IsPet() || creatureTarget->GetTypeId() == TYPEID_PLAYER) + { + handler->PSendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + CreatureTemplate const* creatrueTemplate = sObjectMgr->GetCreatureTemplate(creatureTarget->GetEntry()); + // Creatures with family 0 crashes the server + if (!creatrueTemplate->family) + { + handler->PSendSysMessage("This creature cannot be tamed. (family id: 0)."); + handler->SetSentErrorMessage(true); + return false; + } + + if (player->GetPetGUID()) + { + handler->PSendSysMessage("You already have a pet"); + handler->SetSentErrorMessage(true); + return false; + } + + // Everything looks OK, create new pet + Pet* pet = new Pet(player, HUNTER_PET); + if (!pet->CreateBaseAtCreature(creatureTarget)) + { + delete pet; + handler->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."); + handler->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, false); + player->PetSpellInitialize(); + + return true; + } + + static bool HandlePetLearnCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + Player* player = handler->GetSession()->GetPlayer(); + Pet* pet = player->GetPet(); + + if (!pet) + { + handler->PSendSysMessage("You have no pet"); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 spellId = handler->extractSpellIdFromLink((char*)args); + if (!spellId) + return false; + + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); + if (!spellInfo) + { + handler->PSendSysMessage(LANG_COMMAND_NOSPELLFOUND); + handler->SetSentErrorMessage(true); + return false; + } + + if (!SpellMgr::IsSpellValid(spellInfo)) + { + handler->PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spellId); + handler->SetSentErrorMessage(true); + return false; + } + + SpellScriptsBounds bounds = sObjectMgr->GetSpellScriptsBounds(spellId); + uint32 spellDifficultyId = sSpellMgr->GetSpellDifficultyId(spellId); + if (bounds.first != bounds.second || spellDifficultyId) + { + handler->PSendSysMessage("Spell %u cannot be learnt using a command!", spellId); + handler->SetSentErrorMessage(true); + return false; + } + + // Check if pet already has it + if (pet->HasSpell(spellId)) + { + handler->PSendSysMessage("Pet already has spell: %u", spellId); + handler->SetSentErrorMessage(true); + return false; + } + + pet->learnSpell(spellId); + + handler->PSendSysMessage("Pet has learned spell %u", spellId); + return true; + } + + static bool HandlePetUnlearnCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + Player* player = handler->GetSession()->GetPlayer(); + Pet* pet = player->GetPet(); + if (!pet) + { + handler->PSendSysMessage("You have no pet"); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 spellId = handler->extractSpellIdFromLink((char*)args); + + if (pet->HasSpell(spellId)) + pet->removeSpell(spellId, false); + else + handler->PSendSysMessage("Pet doesn't have that spell"); + + return true; + } + + static bool HandleFreezeCommand(ChatHandler* handler, char const* args) + { + std::string name; + Player* player; + char const* TargetName = strtok((char*)args, " "); // get entered name + if (!TargetName) // if no name entered use target + { + player = handler->getSelectedPlayer(); + if (player) //prevent crash with creature as target + { + name = player->GetName(); + normalizePlayerName(name); + } + } + else // if name entered + { + name = TargetName; + normalizePlayerName(name); + player = ObjectAccessor::FindPlayerByName(name); + } + + if (!player) + { + handler->SendSysMessage(LANG_COMMAND_FREEZE_WRONG); + return true; + } + + if (player == handler->GetSession()->GetPlayer()) + { + handler->SendSysMessage(LANG_COMMAND_FREEZE_ERROR); + return true; + } + + if (player && (player != handler->GetSession()->GetPlayer())) + { + handler->PSendSysMessage(LANG_COMMAND_FREEZE, name.c_str()); + if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(9454)) + Aura::TryRefreshStackOrCreate(spellInfo, MAX_EFFECT_MASK, player, player); + } + + return true; + } + + static bool HandleUnFreezeCommand(ChatHandler* handler, char const*args) + { + std::string name; + Player* player; + char* targetName = strtok((char*)args, " "); // Get entered name + + if (targetName) + { + name = targetName; + normalizePlayerName(name); + player = ObjectAccessor::FindPlayerByName(name); + } + else // If no name was entered - use target + { + player = handler->getSelectedPlayer(); + if (player) + name = player->GetName(); + } + + if (player) + { + handler->PSendSysMessage(LANG_COMMAND_UNFREEZE, name.c_str()); + player->RemoveAurasDueToSpell(9454); + return true; + } + else if (targetName) + { + if (uint64 playerGUID = sWorld->GetGlobalPlayerGUID(name)) + { + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_AURA_FROZEN); + stmt->setUInt32(0, GUID_LOPART(playerGUID)); + CharacterDatabase.Execute(stmt); + handler->PSendSysMessage(LANG_COMMAND_UNFREEZE, name.c_str()); + return true; + } + } + + handler->SendSysMessage(LANG_COMMAND_FREEZE_WRONG); + return true; + } + + static bool HandleGroupLeaderCommand(ChatHandler* handler, char const* args) + { + Player* player = NULL; + Group* group = NULL; + uint64 guid = 0; + char* nameStr = strtok((char*)args, " "); + + if (handler->GetPlayerGroupAndGUIDByName(nameStr, player, group, guid)) + if (group && group->GetLeaderGUID() != guid) + { + group->ChangeLeader(guid); + group->SendUpdate(); + } + + return true; + } + + static bool HandleGroupDisbandCommand(ChatHandler* handler, char const* args) + { + Player* player = NULL; + Group* group = NULL; + uint64 guid = 0; + char* nameStr = strtok((char*)args, " "); + + if (handler->GetPlayerGroupAndGUIDByName(nameStr, player, group, guid)) + if (group) + group->Disband(); + + return true; + } + + static bool HandleGroupRemoveCommand(ChatHandler* handler, char const* args) + { + Player* player = NULL; + Group* group = NULL; + uint64 guid = 0; + char* nameStr = strtok((char*)args, " "); + + if (handler->GetPlayerGroupAndGUIDByName(nameStr, player, group, guid, true)) + if (group) + group->RemoveMember(guid); + + return true; + } + + static bool HandleGroupJoinCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + Player* playerSource = NULL; + Group* groupSource = NULL; + uint64 guidSource = 0; + uint64 guidTarget = 0; + char* nameplgrStr = strtok((char*)args, " "); + char* nameplStr = strtok(NULL, " "); + + if (handler->GetPlayerGroupAndGUIDByName(nameplgrStr, playerSource, groupSource, guidSource, true)) + { + if (groupSource) + { + Group* groupTarget = NULL; + Player* playerTarget = NULL; + if (handler->GetPlayerGroupAndGUIDByName(nameplStr, playerTarget, groupTarget, guidTarget, true)) + { + if (!groupTarget && playerTarget->GetGroup() != groupSource) + { + if (!groupSource->IsFull()) + { + groupSource->AddMember(playerTarget); + groupSource->BroadcastGroupUpdate(); + handler->PSendSysMessage(LANG_GROUP_PLAYER_JOINED, playerTarget->GetName().c_str(), playerSource->GetName().c_str()); + return true; + } + else + { + // group is full + handler->PSendSysMessage(LANG_GROUP_FULL); + return true; + } + } + else + { + // group is full or target player already in a group + handler->PSendSysMessage(LANG_GROUP_ALREADY_IN_GROUP, playerTarget->GetName().c_str()); + return true; + } + } + } + else + { + // specified source player is not in a group + handler->PSendSysMessage(LANG_GROUP_NOT_IN_GROUP, playerSource->GetName().c_str()); + return true; + } + } + + return true; + } + + static bool HandleGroupListCommand(ChatHandler* handler, char const* args) + { + Player* playerTarget; + uint64 guidTarget = 0; + std::string nameTarget; + + uint32 parseGUID = MAKE_NEW_GUID(atol((char*)args), 0, HIGHGUID_PLAYER); + + if (sObjectMgr->GetPlayerNameByGUID(parseGUID, nameTarget)) + { + playerTarget = ObjectAccessor::FindPlayerInOrOutOfWorld(MAKE_NEW_GUID(parseGUID, 0, HIGHGUID_PLAYER)); + guidTarget = parseGUID; + } + else if (!handler->extractPlayerTarget((char*)args, &playerTarget, &guidTarget, &nameTarget)) + return false; + + Group* groupTarget = NULL; + if (playerTarget) + groupTarget = playerTarget->GetGroup(); + + if (!groupTarget && guidTarget) + if (uint32 groupId = Player::GetGroupIdFromStorage(GUID_LOPART(guidTarget))) + groupTarget = sGroupMgr->GetGroupByGUID(groupId); + + if (groupTarget) + { + handler->PSendSysMessage(LANG_GROUP_TYPE, (groupTarget->isRaidGroup() ? "raid" : "party")); + Group::MemberSlotList const& members = groupTarget->GetMemberSlots(); + for (Group::MemberSlotList::const_iterator itr = members.begin(); itr != members.end(); ++itr) + { + Group::MemberSlot const& slot = *itr; + + std::string flags; + if (slot.flags & MEMBER_FLAG_ASSISTANT) + flags = "Assistant"; + + if (slot.flags & MEMBER_FLAG_MAINTANK) + { + if (!flags.empty()) + flags.append(", "); + flags.append("MainTank"); + } + + if (slot.flags & MEMBER_FLAG_MAINASSIST) + { + if (!flags.empty()) + flags.append(", "); + flags.append("MainAssist"); + } + + if (flags.empty()) + flags = "None"; + + Player* p = ObjectAccessor::FindPlayerInOrOutOfWorld((*itr).guid); + const char* onlineState = p ? "online" : "offline"; + + /*handler->PSendSysMessage(LANG_GROUP_PLAYER_NAME_GUID, slot.name.c_str(), onlineState, + GUID_LOPART(slot.guid), flags.c_str(), lfg::GetRolesString(slot.roles).c_str());*/ + } + } + else + handler->PSendSysMessage(LANG_GROUP_NOT_IN_GROUP, nameTarget.c_str()); + + return true; + } + + static bool HandlePlayAllCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + uint32 soundId = atoi((char*)args); + + if (!sSoundEntriesStore.LookupEntry(soundId)) + { + handler->PSendSysMessage(LANG_SOUND_NOT_EXIST, soundId); + handler->SetSentErrorMessage(true); + return false; + } + + WorldPacket data(SMSG_PLAY_SOUND, 4); + data << uint32(soundId) << handler->GetSession()->GetPlayer()->GetGUID(); + sWorld->SendGlobalMessage(&data); + + handler->PSendSysMessage(LANG_COMMAND_PLAYED_TO_ALL, soundId); + return true; + } + + static bool HandlePossessCommand(ChatHandler* handler, char const* /*args*/) + { + Unit* unit = handler->getSelectedUnit(); + if (!unit) + return false; + + handler->GetSession()->GetPlayer()->CastSpell(unit, 530, true); + return true; + } + + static bool HandleUnPossessCommand(ChatHandler* handler, char const* /*args*/) + { + Unit* unit = handler->getSelectedUnit(); + if (!unit) + unit = handler->GetSession()->GetPlayer(); + + unit->RemoveCharmAuras(); + + return true; + } + + static bool HandleBindSightCommand(ChatHandler* handler, char const* /*args*/) + { + Unit* unit = handler->getSelectedUnit(); + if (!unit) + return false; + + handler->GetSession()->GetPlayer()->CastSpell(unit, 6277, true); + return true; + } + + static bool HandleUnbindSightCommand(ChatHandler* handler, char const* /*args*/) + { + Player* player = handler->GetSession()->GetPlayer(); + + if (player->isPossessing()) + return false; + + player->StopCastingBindSight(); + return true; + } + + static bool HandleMailBoxCommand(ChatHandler* handler, char const* /*args*/) + { + Player* player = handler->GetSession()->GetPlayer(); + + handler->GetSession()->SendShowMailBox(player->GetGUID()); + return true; + } +}; + +void AddSC_misc_commandscript() +{ + new misc_commandscript(); +} |