mirror of
https://github.com/araxiaonline/TrinityCore2.git
synced 2026-06-14 03:53:03 -04:00
4774 lines
143 KiB
C++
Executable File
4774 lines
143 KiB
C++
Executable File
/*
|
|
* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
|
|
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
|
*
|
|
* 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 "Common.h"
|
|
#include "DatabaseEnv.h"
|
|
#include "WorldPacket.h"
|
|
#include "WorldSession.h"
|
|
#include "World.h"
|
|
#include "ObjectMgr.h"
|
|
#include "ArenaTeamMgr.h"
|
|
#include "GuildMgr.h"
|
|
#include "AuctionHouseMgr.h"
|
|
#include "AccountMgr.h"
|
|
#include "PlayerDump.h"
|
|
#include "SpellMgr.h"
|
|
#include "Player.h"
|
|
#include "Opcodes.h"
|
|
#include "GameObject.h"
|
|
#include "Chat.h"
|
|
#include "Log.h"
|
|
#include "Guild.h"
|
|
#include "ObjectAccessor.h"
|
|
#include "MapManager.h"
|
|
#include "Language.h"
|
|
#include "GridNotifiersImpl.h"
|
|
#include "CellImpl.h"
|
|
#include "Weather.h"
|
|
#include "PointMovementGenerator.h"
|
|
#include "TargetedMovementGenerator.h"
|
|
#include "SkillDiscovery.h"
|
|
#include "SkillExtraItems.h"
|
|
#include "SystemConfig.h"
|
|
#include "Config.h"
|
|
#include "Util.h"
|
|
#include "ItemEnchantmentMgr.h"
|
|
#include "BattlegroundMgr.h"
|
|
#include "InstanceSaveMgr.h"
|
|
#include "InstanceScript.h"
|
|
#include "CreatureEventAIMgr.h"
|
|
#include "SpellAuraEffects.h"
|
|
#include "DBCEnums.h"
|
|
#include "ConditionMgr.h"
|
|
#include "DisableMgr.h"
|
|
#include "Transport.h"
|
|
#include "WeatherMgr.h"
|
|
#include "ScriptMgr.h"
|
|
#include "CreatureTextMgr.h"
|
|
#include "SmartAI.h"
|
|
#include "Group.h"
|
|
#include "ChannelMgr.h"
|
|
|
|
bool ChatHandler::HandleMaxSkillCommand(const char* /*args*/)
|
|
{
|
|
Player* SelectedPlayer = getSelectedPlayer();
|
|
if (!SelectedPlayer)
|
|
{
|
|
SendSysMessage(LANG_NO_CHAR_SELECTED);
|
|
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;
|
|
}
|
|
|
|
bool ChatHandler::HandleSetSkillCommand(const char *args)
|
|
{
|
|
// number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r
|
|
char* skill_p = extractKeyFromLink((char*)args, "Hskill");
|
|
if (!skill_p)
|
|
return false;
|
|
|
|
char *level_p = strtok (NULL, " ");
|
|
if (!level_p)
|
|
return false;
|
|
|
|
char *max_p = strtok (NULL, " ");
|
|
|
|
int32 skill = atoi(skill_p);
|
|
if (skill <= 0)
|
|
{
|
|
PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
int32 level = atol(level_p);
|
|
|
|
Player* target = getSelectedPlayer();
|
|
if (!target)
|
|
{
|
|
SendSysMessage(LANG_NO_CHAR_SELECTED);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
SkillLineEntry const* sl = sSkillLineStore.LookupEntry(skill);
|
|
if (!sl)
|
|
{
|
|
PSendSysMessage(LANG_INVALID_SKILL_ID, skill);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
std::string tNameLink = GetNameLink(target);
|
|
|
|
if (!target->GetSkillValue(skill))
|
|
{
|
|
PSendSysMessage(LANG_SET_SKILL_ERROR, tNameLink.c_str(), skill, sl->name[GetSessionDbcLocale()]);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
int32 max = max_p ? atol (max_p) : target->GetPureMaxSkillValue(skill);
|
|
|
|
if (level <= 0 || level > max || max <= 0)
|
|
return false;
|
|
|
|
target->SetSkill(skill, target->GetSkillStep(skill), level, max);
|
|
PSendSysMessage(LANG_SET_SKILL, skill, sl->name[GetSessionDbcLocale()], tNameLink.c_str(), level, max);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleUnLearnCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
|
|
uint32 spell_id = extractSpellIdFromLink((char*)args);
|
|
if (!spell_id)
|
|
return false;
|
|
|
|
char const* allStr = strtok(NULL, " ");
|
|
bool allRanks = allStr ? (strncmp(allStr, "all", strlen(allStr)) == 0) : false;
|
|
|
|
Player* target = getSelectedPlayer();
|
|
if (!target)
|
|
{
|
|
SendSysMessage(LANG_NO_CHAR_SELECTED);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
if (allRanks)
|
|
spell_id = sSpellMgr->GetFirstSpellInChain (spell_id);
|
|
|
|
if (target->HasSpell(spell_id))
|
|
target->removeSpell(spell_id, false, !allRanks);
|
|
else
|
|
SendSysMessage(LANG_FORGET_SPELL);
|
|
|
|
if (GetTalentSpellCost(spell_id))
|
|
target->SendTalentsInfoData(false);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleCooldownCommand(const char *args)
|
|
{
|
|
Player* target = getSelectedPlayer();
|
|
if (!target)
|
|
{
|
|
SendSysMessage(LANG_PLAYER_NOT_FOUND);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
std::string tNameLink = GetNameLink(target);
|
|
|
|
if (!*args)
|
|
{
|
|
target->RemoveAllSpellCooldown();
|
|
PSendSysMessage(LANG_REMOVEALL_COOLDOWN, tNameLink.c_str());
|
|
}
|
|
else
|
|
{
|
|
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
|
|
uint32 spell_id = extractSpellIdFromLink((char*)args);
|
|
if (!spell_id)
|
|
return false;
|
|
|
|
if (!sSpellMgr->GetSpellInfo(spell_id))
|
|
{
|
|
PSendSysMessage(LANG_UNKNOWN_SPELL, target == m_session->GetPlayer() ? GetTrinityString(LANG_YOU) : tNameLink.c_str());
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
target->RemoveSpellCooldown(spell_id, true);
|
|
PSendSysMessage(LANG_REMOVE_COOLDOWN, spell_id, target == m_session->GetPlayer() ? GetTrinityString(LANG_YOU) : tNameLink.c_str());
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleAddItemCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
uint32 itemId = 0;
|
|
|
|
if (args[0] == '[') // [name] manual form
|
|
{
|
|
char* citemName = strtok((char*)args, "]");
|
|
|
|
if (citemName && citemName[0])
|
|
{
|
|
std::string itemName = citemName+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)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_COULDNOTFIND, citemName+1);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
itemId = result->Fetch()->GetUInt16();
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
else // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r
|
|
{
|
|
char* cId = extractKeyFromLink((char*)args, "Hitem");
|
|
if (!cId)
|
|
return false;
|
|
itemId = atol(cId);
|
|
}
|
|
|
|
char* ccount = strtok(NULL, " ");
|
|
|
|
int32 count = 1;
|
|
|
|
if (ccount)
|
|
count = strtol(ccount, NULL, 10);
|
|
|
|
if (count == 0)
|
|
count = 1;
|
|
|
|
Player* player = m_session->GetPlayer();
|
|
Player* plTarget = getSelectedPlayer();
|
|
if (!plTarget)
|
|
plTarget = player;
|
|
|
|
sLog->outDetail(GetTrinityString(LANG_ADDITEM), itemId, count);
|
|
|
|
ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(itemId);
|
|
if (!pProto)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
//Subtract
|
|
if (count < 0)
|
|
{
|
|
plTarget->DestroyItemCount(itemId, -count, true, false);
|
|
PSendSysMessage(LANG_REMOVEITEM, itemId, -count, GetNameLink(plTarget).c_str());
|
|
return true;
|
|
}
|
|
|
|
//Adding items
|
|
uint32 noSpaceForCount = 0;
|
|
|
|
// check space and find places
|
|
ItemPosCountVec dest;
|
|
InventoryResult msg = plTarget->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
|
|
{
|
|
PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
Item* item = plTarget->StoreNewItem(dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId));
|
|
|
|
// remove binding (let GM give it to another player later)
|
|
if (player == plTarget)
|
|
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 != plTarget)
|
|
plTarget->SendNewItem(item, count, true, false);
|
|
}
|
|
|
|
if (noSpaceForCount > 0)
|
|
PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleAddItemSetCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
char* cId = extractKeyFromLink((char*)args, "Hitemset"); // number or [name] Shift-click form |color|Hitemset:itemset_id|h[name]|h|r
|
|
if (!cId)
|
|
return false;
|
|
|
|
uint32 itemsetId = atol(cId);
|
|
|
|
// prevent generation all items with itemset field value '0'
|
|
if (itemsetId == 0)
|
|
{
|
|
PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND, itemsetId);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
Player* player = m_session->GetPlayer();
|
|
Player* playerTarget = getSelectedPlayer();
|
|
if (!playerTarget)
|
|
playerTarget = player;
|
|
|
|
sLog->outDetail(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);
|
|
PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itr->second.ItemId, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!found)
|
|
{
|
|
PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND, itemsetId);
|
|
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleListItemCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
char* cId = extractKeyFromLink((char*)args, "Hitem");
|
|
if (!cId)
|
|
return false;
|
|
|
|
uint32 item_id = atol(cId);
|
|
if (!item_id)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
ItemTemplate const* itemProto = sObjectMgr->GetItemTemplate(item_id);
|
|
if (!itemProto)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
char* c_count = strtok(NULL, " ");
|
|
int _count = c_count ? atol(c_count) : 10;
|
|
|
|
if (_count < 0)
|
|
return false;
|
|
uint32 count = uint32(_count);
|
|
|
|
PreparedQueryResult result;
|
|
|
|
// inventory case
|
|
uint32 inv_count = 0;
|
|
|
|
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_INVENTORY_COUNT_ITEM);
|
|
stmt->setUInt32(0, item_id);
|
|
result = CharacterDatabase.Query(stmt);
|
|
|
|
if (result)
|
|
inv_count = (*result)[0].GetUInt32();
|
|
|
|
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_INVENTORY_ITEM_BY_ENTRY);
|
|
stmt->setUInt32(0, item_id);
|
|
stmt->setUInt32(1, count);
|
|
result = CharacterDatabase.Query(stmt);
|
|
|
|
if (result)
|
|
{
|
|
do
|
|
{
|
|
Field* fields = result->Fetch();
|
|
uint32 item_guid = fields[0].GetUInt32();
|
|
uint32 item_bag = fields[1].GetUInt32();
|
|
uint32 item_slot = fields[2].GetUInt32();
|
|
uint32 owner_guid = fields[3].GetUInt32();
|
|
uint32 owner_acc = fields[4].GetUInt32();
|
|
std::string owner_name = fields[5].GetString();
|
|
|
|
char const* item_pos = 0;
|
|
if (Player::IsEquipmentPos(item_bag, item_slot))
|
|
item_pos = "[equipped]";
|
|
else if (Player::IsInventoryPos(item_bag, item_slot))
|
|
item_pos = "[in inventory]";
|
|
else if (Player::IsBankPos(item_bag, item_slot))
|
|
item_pos = "[in bank]";
|
|
else
|
|
item_pos = "";
|
|
|
|
PSendSysMessage(LANG_ITEMLIST_SLOT, item_guid, owner_name.c_str(), owner_guid, owner_acc, item_pos);
|
|
}
|
|
while (result->NextRow());
|
|
|
|
uint32 res_count = uint32(result->GetRowCount());
|
|
|
|
if (count > res_count)
|
|
count -= res_count;
|
|
else if (count)
|
|
count = 0;
|
|
}
|
|
|
|
// mail case
|
|
uint32 mail_count = 0;
|
|
|
|
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_COUNT_ITEM);
|
|
stmt->setUInt32(0, item_id);
|
|
result = CharacterDatabase.Query(stmt);
|
|
|
|
if (result)
|
|
mail_count = (*result)[0].GetUInt32();
|
|
|
|
if (count > 0)
|
|
{
|
|
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_ITEMS_BY_ENTRY);
|
|
stmt->setUInt32(0, item_id);
|
|
stmt->setUInt32(1, count);
|
|
result = CharacterDatabase.Query(stmt);
|
|
}
|
|
else
|
|
result = PreparedQueryResult(NULL);
|
|
|
|
if (result)
|
|
{
|
|
do
|
|
{
|
|
Field* fields = result->Fetch();
|
|
uint32 item_guid = fields[0].GetUInt32();
|
|
uint32 item_s = fields[1].GetUInt32();
|
|
uint32 item_r = fields[2].GetUInt32();
|
|
uint32 item_s_acc = fields[3].GetUInt32();
|
|
std::string item_s_name = fields[4].GetString();
|
|
uint32 item_r_acc = fields[5].GetUInt32();
|
|
std::string item_r_name = fields[6].GetString();
|
|
|
|
char const* item_pos = "[in mail]";
|
|
|
|
PSendSysMessage(LANG_ITEMLIST_MAIL, item_guid, item_s_name.c_str(), item_s, item_s_acc, item_r_name.c_str(), item_r, item_r_acc, item_pos);
|
|
}
|
|
while (result->NextRow());
|
|
|
|
uint32 res_count = uint32(result->GetRowCount());
|
|
|
|
if (count > res_count)
|
|
count -= res_count;
|
|
else if (count)
|
|
count = 0;
|
|
}
|
|
|
|
// auction case
|
|
uint32 auc_count = 0;
|
|
|
|
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_AUCTIONHOUSE_COUNT_ITEM);
|
|
stmt->setUInt32(0, item_id);
|
|
result = CharacterDatabase.Query(stmt);
|
|
|
|
if (result)
|
|
auc_count = (*result)[0].GetUInt32();
|
|
|
|
if (count > 0)
|
|
{
|
|
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_AUCTIONHOUSE_ITEM_BY_ENTRY);
|
|
stmt->setUInt32(0, item_id);
|
|
stmt->setUInt32(1, count);
|
|
result = CharacterDatabase.Query(stmt);
|
|
}
|
|
else
|
|
result = PreparedQueryResult(NULL);
|
|
|
|
if (result)
|
|
{
|
|
do
|
|
{
|
|
Field* fields = result->Fetch();
|
|
uint32 item_guid = fields[0].GetUInt32();
|
|
uint32 owner = fields[1].GetUInt32();
|
|
uint32 owner_acc = fields[2].GetUInt32();
|
|
std::string owner_name = fields[3].GetString();
|
|
|
|
char const* item_pos = "[in auction]";
|
|
|
|
PSendSysMessage(LANG_ITEMLIST_AUCTION, item_guid, owner_name.c_str(), owner, owner_acc, item_pos);
|
|
}
|
|
while (result->NextRow());
|
|
}
|
|
|
|
// guild bank case
|
|
uint32 guild_count = 0;
|
|
|
|
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_BANK_COUNT_ITEM);
|
|
stmt->setUInt32(0, item_id);
|
|
result = CharacterDatabase.Query(stmt);
|
|
|
|
if (result)
|
|
guild_count = (*result)[0].GetUInt32();
|
|
|
|
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_BANK_ITEM_BY_ENTRY);
|
|
stmt->setUInt32(0, item_id);
|
|
stmt->setUInt32(1, count);
|
|
result = CharacterDatabase.Query(stmt);
|
|
|
|
if (result)
|
|
{
|
|
do
|
|
{
|
|
Field* fields = result->Fetch();
|
|
uint32 item_guid = fields[0].GetUInt32();
|
|
uint32 guild_guid = fields[1].GetUInt32();
|
|
std::string guild_name = fields[2].GetString();
|
|
|
|
char const* item_pos = "[in guild bank]";
|
|
|
|
PSendSysMessage(LANG_ITEMLIST_GUILD, item_guid, guild_name.c_str(), guild_guid, item_pos);
|
|
}
|
|
while (result->NextRow());
|
|
|
|
uint32 res_count = uint32(result->GetRowCount());
|
|
|
|
if (count > res_count)
|
|
count -= res_count;
|
|
else if (count)
|
|
count = 0;
|
|
}
|
|
|
|
if (inv_count + mail_count + auc_count + guild_count == 0)
|
|
{
|
|
SendSysMessage(LANG_COMMAND_NOITEMFOUND);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
PSendSysMessage(LANG_COMMAND_LISTITEMMESSAGE, item_id, inv_count + mail_count + auc_count + guild_count, inv_count, mail_count, auc_count, guild_count);
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleListObjectCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
// number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
|
|
char* cId = extractKeyFromLink((char*)args, "Hgameobject_entry");
|
|
if (!cId)
|
|
return false;
|
|
|
|
uint32 go_id = atol(cId);
|
|
if (!go_id)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
GameObjectTemplate const* gInfo = sObjectMgr->GetGameObjectTemplate(go_id);
|
|
if (!gInfo)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
char* c_count = strtok(NULL, " ");
|
|
int count = c_count ? atol(c_count) : 10;
|
|
|
|
if (count < 0)
|
|
return false;
|
|
|
|
QueryResult result;
|
|
|
|
uint32 obj_count = 0;
|
|
result = WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'", go_id);
|
|
if (result)
|
|
obj_count = (*result)[0].GetUInt32();
|
|
|
|
if (m_session)
|
|
{
|
|
Player* player = m_session->GetPlayer();
|
|
result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, id, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE id = '%u' ORDER BY order_ ASC LIMIT %u",
|
|
player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), go_id, uint32(count));
|
|
}
|
|
else
|
|
result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, id FROM gameobject WHERE id = '%u' LIMIT %u",
|
|
go_id, uint32(count));
|
|
|
|
if (result)
|
|
{
|
|
do
|
|
{
|
|
Field* fields = result->Fetch();
|
|
uint32 guid = fields[0].GetUInt32();
|
|
float x = fields[1].GetFloat();
|
|
float y = fields[2].GetFloat();
|
|
float z = fields[3].GetFloat();
|
|
int mapid = fields[4].GetUInt16();
|
|
uint32 entry = fields[5].GetUInt32();
|
|
|
|
if (m_session)
|
|
PSendSysMessage(LANG_GO_LIST_CHAT, guid, entry, guid, gInfo->name.c_str(), x, y, z, mapid);
|
|
else
|
|
PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, gInfo->name.c_str(), x, y, z, mapid);
|
|
} while (result->NextRow());
|
|
}
|
|
|
|
PSendSysMessage(LANG_COMMAND_LISTOBJMESSAGE, go_id, obj_count);
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleListCreatureCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
// number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
|
|
char* cId = extractKeyFromLink((char*)args, "Hcreature_entry");
|
|
if (!cId)
|
|
return false;
|
|
|
|
uint32 cr_id = atol(cId);
|
|
if (!cr_id)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(cr_id);
|
|
if (!cInfo)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
char* c_count = strtok(NULL, " ");
|
|
int count = c_count ? atol(c_count) : 10;
|
|
|
|
if (count < 0)
|
|
return false;
|
|
|
|
QueryResult result;
|
|
|
|
uint32 cr_count = 0;
|
|
result = WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'", cr_id);
|
|
if (result)
|
|
cr_count = (*result)[0].GetUInt32();
|
|
|
|
if (m_session)
|
|
{
|
|
Player* player = m_session->GetPlayer();
|
|
result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM creature WHERE id = '%u' ORDER BY order_ ASC LIMIT %u",
|
|
player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), cr_id, uint32(count));
|
|
}
|
|
else
|
|
result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM creature WHERE id = '%u' LIMIT %u",
|
|
cr_id, uint32(count));
|
|
|
|
if (result)
|
|
{
|
|
do
|
|
{
|
|
Field* fields = result->Fetch();
|
|
uint32 guid = fields[0].GetUInt32();
|
|
float x = fields[1].GetFloat();
|
|
float y = fields[2].GetFloat();
|
|
float z = fields[3].GetFloat();
|
|
int mapid = fields[4].GetUInt16();
|
|
|
|
if (m_session)
|
|
PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name.c_str(), x, y, z, mapid);
|
|
else
|
|
PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name.c_str(), x, y, z, mapid);
|
|
} while (result->NextRow());
|
|
}
|
|
|
|
PSendSysMessage(LANG_COMMAND_LISTCREATUREMESSAGE, cr_id, cr_count);
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleLookupItemCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
std::string namepart = args;
|
|
std::wstring wnamepart;
|
|
|
|
// converting string that we try to find to lower case
|
|
if (!Utf8toWStr(namepart, wnamepart))
|
|
return false;
|
|
|
|
wstrToLower(wnamepart);
|
|
|
|
bool found = false;
|
|
uint32 count = 0;
|
|
uint32 maxResults = sWorld->getIntConfig(CONFIG_MAX_RESULTS_LOOKUP_COMMANDS);
|
|
|
|
// Search in `item_template`
|
|
ItemTemplateContainer const* its = sObjectMgr->GetItemTemplateStore();
|
|
for (ItemTemplateContainer::const_iterator itr = its->begin(); itr != its->end(); ++itr)
|
|
{
|
|
int loc_idx = GetSessionDbLocaleIndex();
|
|
if (loc_idx >= 0)
|
|
{
|
|
uint8 uloc_idx = uint8(loc_idx);
|
|
if (ItemLocale const* il = sObjectMgr->GetItemLocale(itr->second.ItemId))
|
|
{
|
|
if (il->Name.size() > uloc_idx && !il->Name[uloc_idx].empty())
|
|
{
|
|
std::string name = il->Name[uloc_idx];
|
|
|
|
if (Utf8FitTo(name, wnamepart))
|
|
{
|
|
if (maxResults && count++ == maxResults)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
|
|
return true;
|
|
}
|
|
|
|
if (m_session)
|
|
PSendSysMessage(LANG_ITEM_LIST_CHAT, itr->second.ItemId, itr->second.ItemId, name.c_str());
|
|
else
|
|
PSendSysMessage(LANG_ITEM_LIST_CONSOLE, itr->second.ItemId, name.c_str());
|
|
|
|
if (!found)
|
|
found = true;
|
|
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
std::string name = itr->second.Name1;
|
|
if (name.empty())
|
|
continue;
|
|
|
|
if (Utf8FitTo(name, wnamepart))
|
|
{
|
|
if (maxResults && count++ == maxResults)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
|
|
return true;
|
|
}
|
|
|
|
if (m_session)
|
|
PSendSysMessage(LANG_ITEM_LIST_CHAT, itr->second.ItemId, itr->second.ItemId, name.c_str());
|
|
else
|
|
PSendSysMessage(LANG_ITEM_LIST_CONSOLE, itr->second.ItemId, name.c_str());
|
|
|
|
if (!found)
|
|
found = true;
|
|
}
|
|
}
|
|
|
|
if (!found)
|
|
SendSysMessage(LANG_COMMAND_NOITEMFOUND);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleLookupItemSetCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
std::string namepart = args;
|
|
std::wstring wnamepart;
|
|
|
|
if (!Utf8toWStr(namepart, wnamepart))
|
|
return false;
|
|
|
|
// converting string that we try to find to lower case
|
|
wstrToLower(wnamepart);
|
|
|
|
bool found = false;
|
|
uint32 count = 0;
|
|
uint32 maxResults = sWorld->getIntConfig(CONFIG_MAX_RESULTS_LOOKUP_COMMANDS);
|
|
|
|
// Search in ItemSet.dbc
|
|
for (uint32 id = 0; id < sItemSetStore.GetNumRows(); id++)
|
|
{
|
|
ItemSetEntry const* set = sItemSetStore.LookupEntry(id);
|
|
if (set)
|
|
{
|
|
int loc = GetSessionDbcLocale();
|
|
std::string name = set->name[loc];
|
|
if (name.empty())
|
|
continue;
|
|
|
|
if (!Utf8FitTo(name, wnamepart))
|
|
{
|
|
loc = 0;
|
|
for (; loc < TOTAL_LOCALES; ++loc)
|
|
{
|
|
if (loc == GetSessionDbcLocale())
|
|
continue;
|
|
|
|
name = set->name[loc];
|
|
if (name.empty())
|
|
continue;
|
|
|
|
if (Utf8FitTo(name, wnamepart))
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (loc < TOTAL_LOCALES)
|
|
{
|
|
if (maxResults && count++ == maxResults)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
|
|
return true;
|
|
}
|
|
|
|
// send item set in "id - [namedlink locale]" format
|
|
if (m_session)
|
|
PSendSysMessage(LANG_ITEMSET_LIST_CHAT, id, id, name.c_str(), localeNames[loc]);
|
|
else
|
|
PSendSysMessage(LANG_ITEMSET_LIST_CONSOLE, id, name.c_str(), localeNames[loc]);
|
|
|
|
if (!found)
|
|
found = true;
|
|
}
|
|
}
|
|
}
|
|
if (!found)
|
|
SendSysMessage(LANG_COMMAND_NOITEMSETFOUND);
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleLookupSkillCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
// can be NULL in console call
|
|
Player* target = getSelectedPlayer();
|
|
|
|
std::string namepart = args;
|
|
std::wstring wnamepart;
|
|
|
|
if (!Utf8toWStr(namepart, wnamepart))
|
|
return false;
|
|
|
|
// converting string that we try to find to lower case
|
|
wstrToLower(wnamepart);
|
|
|
|
bool found = false;
|
|
uint32 count = 0;
|
|
uint32 maxResults = sWorld->getIntConfig(CONFIG_MAX_RESULTS_LOOKUP_COMMANDS);
|
|
|
|
// Search in SkillLine.dbc
|
|
for (uint32 id = 0; id < sSkillLineStore.GetNumRows(); id++)
|
|
{
|
|
SkillLineEntry const* skillInfo = sSkillLineStore.LookupEntry(id);
|
|
if (skillInfo)
|
|
{
|
|
int loc = GetSessionDbcLocale();
|
|
std::string name = skillInfo->name[loc];
|
|
if (name.empty())
|
|
continue;
|
|
|
|
if (!Utf8FitTo(name, wnamepart))
|
|
{
|
|
loc = 0;
|
|
for (; loc < TOTAL_LOCALES; ++loc)
|
|
{
|
|
if (loc == GetSessionDbcLocale())
|
|
continue;
|
|
|
|
name = skillInfo->name[loc];
|
|
if (name.empty())
|
|
continue;
|
|
|
|
if (Utf8FitTo(name, wnamepart))
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (loc < TOTAL_LOCALES)
|
|
{
|
|
if (maxResults && count++ == maxResults)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
|
|
return true;
|
|
}
|
|
|
|
char valStr[50] = "";
|
|
char const* knownStr = "";
|
|
if (target && target->HasSkill(id))
|
|
{
|
|
knownStr = GetTrinityString(LANG_KNOWN);
|
|
uint32 curValue = target->GetPureSkillValue(id);
|
|
uint32 maxValue = target->GetPureMaxSkillValue(id);
|
|
uint32 permValue = target->GetSkillPermBonusValue(id);
|
|
uint32 tempValue = target->GetSkillTempBonusValue(id);
|
|
|
|
char const* valFormat = GetTrinityString(LANG_SKILL_VALUES);
|
|
snprintf(valStr, 50, valFormat, curValue, maxValue, permValue, tempValue);
|
|
}
|
|
|
|
// send skill in "id - [namedlink locale]" format
|
|
if (m_session)
|
|
PSendSysMessage(LANG_SKILL_LIST_CHAT, id, id, name.c_str(), localeNames[loc], knownStr, valStr);
|
|
else
|
|
PSendSysMessage(LANG_SKILL_LIST_CONSOLE, id, name.c_str(), localeNames[loc], knownStr, valStr);
|
|
|
|
if (!found)
|
|
found = true;
|
|
}
|
|
}
|
|
}
|
|
if (!found)
|
|
SendSysMessage(LANG_COMMAND_NOSKILLFOUND);
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleLookupSpellCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
// can be NULL at console call
|
|
Player* target = getSelectedPlayer();
|
|
|
|
std::string namepart = args;
|
|
std::wstring wnamepart;
|
|
|
|
if (!Utf8toWStr(namepart, wnamepart))
|
|
return false;
|
|
|
|
// converting string that we try to find to lower case
|
|
wstrToLower(wnamepart);
|
|
|
|
bool found = false;
|
|
uint32 count = 0;
|
|
uint32 maxResults = sWorld->getIntConfig(CONFIG_MAX_RESULTS_LOOKUP_COMMANDS);
|
|
|
|
// Search in Spell.dbc
|
|
for (uint32 id = 0; id < sSpellMgr->GetSpellInfoStoreSize(); id++)
|
|
{
|
|
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(id);
|
|
if (spellInfo)
|
|
{
|
|
int loc = GetSessionDbcLocale();
|
|
std::string name = spellInfo->SpellName[loc];
|
|
if (name.empty())
|
|
continue;
|
|
|
|
if (!Utf8FitTo(name, wnamepart))
|
|
{
|
|
loc = 0;
|
|
for (; loc < TOTAL_LOCALES; ++loc)
|
|
{
|
|
if (loc == GetSessionDbcLocale())
|
|
continue;
|
|
|
|
name = spellInfo->SpellName[loc];
|
|
if (name.empty())
|
|
continue;
|
|
|
|
if (Utf8FitTo(name, wnamepart))
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (loc < TOTAL_LOCALES)
|
|
{
|
|
if (maxResults && count++ == maxResults)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
|
|
return true;
|
|
}
|
|
|
|
bool known = target && target->HasSpell(id);
|
|
bool learn = (spellInfo->Effects[0].Effect == SPELL_EFFECT_LEARN_SPELL);
|
|
|
|
SpellInfo const* learnSpellInfo = sSpellMgr->GetSpellInfo(spellInfo->Effects[0].TriggerSpell);
|
|
|
|
uint32 talentCost = GetTalentSpellCost(id);
|
|
|
|
bool talent = (talentCost > 0);
|
|
bool passive = spellInfo->IsPassive();
|
|
bool active = target && target->HasAura(id);
|
|
|
|
// unit32 used to prevent interpreting uint8 as char at output
|
|
// find rank of learned spell for learning spell, or talent rank
|
|
uint32 rank = talentCost ? talentCost : learn && learnSpellInfo ? learnSpellInfo->GetRank() : spellInfo->GetRank();
|
|
|
|
// send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format
|
|
std::ostringstream ss;
|
|
if (m_session)
|
|
ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name;
|
|
else
|
|
ss << id << " - " << name;
|
|
|
|
// include rank in link name
|
|
if (rank)
|
|
ss << GetTrinityString(LANG_SPELL_RANK) << rank;
|
|
|
|
if (m_session)
|
|
ss << ' ' << localeNames[loc] << "]|h|r";
|
|
else
|
|
ss << ' ' << localeNames[loc];
|
|
|
|
if (talent)
|
|
ss << GetTrinityString(LANG_TALENT);
|
|
if (passive)
|
|
ss << GetTrinityString(LANG_PASSIVE);
|
|
if (learn)
|
|
ss << GetTrinityString(LANG_LEARN);
|
|
if (known)
|
|
ss << GetTrinityString(LANG_KNOWN);
|
|
if (active)
|
|
ss << GetTrinityString(LANG_ACTIVE);
|
|
|
|
SendSysMessage(ss.str().c_str());
|
|
|
|
if (!found)
|
|
found = true;
|
|
}
|
|
}
|
|
}
|
|
if (!found)
|
|
SendSysMessage(LANG_COMMAND_NOSPELLFOUND);
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleLookupQuestCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
// can be NULL at console call
|
|
Player* target = getSelectedPlayer();
|
|
|
|
std::string namepart = args;
|
|
std::wstring wnamepart;
|
|
|
|
// converting string that we try to find to lower case
|
|
if (!Utf8toWStr(namepart, wnamepart))
|
|
return false;
|
|
|
|
wstrToLower(wnamepart);
|
|
|
|
bool found = false;
|
|
uint32 count = 0;
|
|
uint32 maxResults = sWorld->getIntConfig(CONFIG_MAX_RESULTS_LOOKUP_COMMANDS);
|
|
|
|
ObjectMgr::QuestMap const& qTemplates = sObjectMgr->GetQuestTemplates();
|
|
for (ObjectMgr::QuestMap::const_iterator iter = qTemplates.begin(); iter != qTemplates.end(); ++iter)
|
|
{
|
|
Quest * qinfo = iter->second;
|
|
|
|
int loc_idx = GetSessionDbLocaleIndex();
|
|
if (loc_idx >= 0)
|
|
{
|
|
uint8 uloc_idx = uint8(loc_idx);
|
|
if (QuestLocale const* il = sObjectMgr->GetQuestLocale(qinfo->GetQuestId()))
|
|
{
|
|
if (il->Title.size() > uloc_idx && !il->Title[uloc_idx].empty())
|
|
{
|
|
std::string title = il->Title[uloc_idx];
|
|
|
|
if (Utf8FitTo(title, wnamepart))
|
|
{
|
|
if (maxResults && count++ == maxResults)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
|
|
return true;
|
|
}
|
|
|
|
char const* statusStr = "";
|
|
|
|
if (target)
|
|
{
|
|
QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
|
|
|
|
if (status == QUEST_STATUS_COMPLETE)
|
|
{
|
|
if (target->GetQuestRewardStatus(qinfo->GetQuestId()))
|
|
statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED);
|
|
else
|
|
statusStr = GetTrinityString(LANG_COMMAND_QUEST_COMPLETE);
|
|
}
|
|
else if (status == QUEST_STATUS_INCOMPLETE)
|
|
statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE);
|
|
}
|
|
|
|
if (m_session)
|
|
PSendSysMessage(LANG_QUEST_LIST_CHAT, qinfo->GetQuestId(), qinfo->GetQuestId(), qinfo->GetQuestLevel(), title.c_str(), statusStr);
|
|
else
|
|
PSendSysMessage(LANG_QUEST_LIST_CONSOLE, qinfo->GetQuestId(), title.c_str(), statusStr);
|
|
|
|
if (!found)
|
|
found = true;
|
|
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
std::string title = qinfo->GetTitle();
|
|
if (title.empty())
|
|
continue;
|
|
|
|
if (Utf8FitTo(title, wnamepart))
|
|
{
|
|
if (maxResults && count++ == maxResults)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
|
|
return true;
|
|
}
|
|
|
|
char const* statusStr = "";
|
|
|
|
if (target)
|
|
{
|
|
QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
|
|
|
|
if (status == QUEST_STATUS_COMPLETE)
|
|
{
|
|
if (target->GetQuestRewardStatus(qinfo->GetQuestId()))
|
|
statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED);
|
|
else
|
|
statusStr = GetTrinityString(LANG_COMMAND_QUEST_COMPLETE);
|
|
}
|
|
else if (status == QUEST_STATUS_INCOMPLETE)
|
|
statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE);
|
|
}
|
|
|
|
if (m_session)
|
|
PSendSysMessage(LANG_QUEST_LIST_CHAT, qinfo->GetQuestId(), qinfo->GetQuestId(), qinfo->GetQuestLevel(), title.c_str(), statusStr);
|
|
else
|
|
PSendSysMessage(LANG_QUEST_LIST_CONSOLE, qinfo->GetQuestId(), title.c_str(), statusStr);
|
|
|
|
if (!found)
|
|
found = true;
|
|
}
|
|
}
|
|
|
|
if (!found)
|
|
SendSysMessage(LANG_COMMAND_NOQUESTFOUND);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleLookupCreatureCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
std::string namepart = args;
|
|
std::wstring wnamepart;
|
|
|
|
// converting string that we try to find to lower case
|
|
if (!Utf8toWStr (namepart, wnamepart))
|
|
return false;
|
|
|
|
wstrToLower (wnamepart);
|
|
|
|
bool found = false;
|
|
uint32 count = 0;
|
|
uint32 maxResults = sWorld->getIntConfig(CONFIG_MAX_RESULTS_LOOKUP_COMMANDS);
|
|
|
|
CreatureTemplateContainer const* ctc = sObjectMgr->GetCreatureTemplates();
|
|
for (CreatureTemplateContainer::const_iterator itr = ctc->begin(); itr != ctc->end(); ++itr)
|
|
{
|
|
uint32 id = itr->second.Entry;
|
|
uint8 localeIndex = GetSessionDbLocaleIndex();
|
|
if (CreatureLocale const* cl = sObjectMgr->GetCreatureLocale(id))
|
|
{
|
|
if (cl->Name.size() > localeIndex && !cl->Name[localeIndex].empty())
|
|
{
|
|
std::string name = cl->Name[localeIndex];
|
|
|
|
if (Utf8FitTo (name, wnamepart))
|
|
{
|
|
if (maxResults && count++ == maxResults)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
|
|
return true;
|
|
}
|
|
|
|
if (m_session)
|
|
PSendSysMessage(LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str());
|
|
else
|
|
PSendSysMessage(LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str());
|
|
|
|
if (!found)
|
|
found = true;
|
|
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
std::string name = itr->second.Name;
|
|
if (name.empty())
|
|
continue;
|
|
|
|
if (Utf8FitTo(name, wnamepart))
|
|
{
|
|
if (maxResults && count++ == maxResults)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
|
|
return true;
|
|
}
|
|
|
|
if (m_session)
|
|
PSendSysMessage(LANG_CREATURE_ENTRY_LIST_CHAT, id, id, name.c_str());
|
|
else
|
|
PSendSysMessage(LANG_CREATURE_ENTRY_LIST_CONSOLE, id, name.c_str());
|
|
|
|
if (!found)
|
|
found = true;
|
|
}
|
|
}
|
|
|
|
if (!found)
|
|
SendSysMessage(LANG_COMMAND_NOCREATUREFOUND);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleLookupObjectCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
std::string namepart = args;
|
|
std::wstring wnamepart;
|
|
|
|
// converting string that we try to find to lower case
|
|
if (!Utf8toWStr(namepart, wnamepart))
|
|
return false;
|
|
|
|
wstrToLower(wnamepart);
|
|
|
|
bool found = false;
|
|
uint32 count = 0;
|
|
uint32 maxResults = sWorld->getIntConfig(CONFIG_MAX_RESULTS_LOOKUP_COMMANDS);
|
|
|
|
GameObjectTemplateContainer const* gotc = sObjectMgr->GetGameObjectTemplates();
|
|
for (GameObjectTemplateContainer::const_iterator itr = gotc->begin(); itr != gotc->end(); ++itr)
|
|
{
|
|
uint8 localeIndex = GetSessionDbLocaleIndex();
|
|
if (GameObjectLocale const* gl = sObjectMgr->GetGameObjectLocale(itr->second.entry))
|
|
{
|
|
if (gl->Name.size() > localeIndex && !gl->Name[localeIndex].empty())
|
|
{
|
|
std::string name = gl->Name[localeIndex];
|
|
|
|
if (Utf8FitTo(name, wnamepart))
|
|
{
|
|
if (maxResults && count++ == maxResults)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
|
|
return true;
|
|
}
|
|
|
|
if (m_session)
|
|
PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, itr->second.entry, itr->second.entry, name.c_str());
|
|
else
|
|
PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, itr->second.entry, name.c_str());
|
|
|
|
if (!found)
|
|
found = true;
|
|
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
std::string name = itr->second.name;
|
|
if (name.empty())
|
|
continue;
|
|
|
|
if (Utf8FitTo(name, wnamepart))
|
|
{
|
|
if (maxResults && count++ == maxResults)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
|
|
return true;
|
|
}
|
|
|
|
if (m_session)
|
|
PSendSysMessage(LANG_GO_ENTRY_LIST_CHAT, itr->second.entry, itr->second.entry, name.c_str());
|
|
else
|
|
PSendSysMessage(LANG_GO_ENTRY_LIST_CONSOLE, itr->second.entry, name.c_str());
|
|
|
|
if (!found)
|
|
found = true;
|
|
}
|
|
}
|
|
|
|
if (!found)
|
|
SendSysMessage(LANG_COMMAND_NOGAMEOBJECTFOUND);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleLookupFactionCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
// Can be NULL at console call
|
|
Player* target = getSelectedPlayer();
|
|
|
|
std::string namepart = args;
|
|
std::wstring wnamepart;
|
|
|
|
if (!Utf8toWStr (namepart, wnamepart))
|
|
return false;
|
|
|
|
// converting string that we try to find to lower case
|
|
wstrToLower (wnamepart);
|
|
|
|
bool found = false;
|
|
uint32 count = 0;
|
|
uint32 maxResults = sWorld->getIntConfig(CONFIG_MAX_RESULTS_LOOKUP_COMMANDS);
|
|
|
|
for (uint32 id = 0; id < sFactionStore.GetNumRows(); ++id)
|
|
{
|
|
FactionEntry const* factionEntry = sFactionStore.LookupEntry (id);
|
|
if (factionEntry)
|
|
{
|
|
FactionState const* repState = target ? target->GetReputationMgr().GetState(factionEntry) : NULL;
|
|
|
|
int loc = GetSessionDbcLocale();
|
|
std::string name = factionEntry->name[loc];
|
|
if (name.empty())
|
|
continue;
|
|
|
|
if (!Utf8FitTo(name, wnamepart))
|
|
{
|
|
loc = 0;
|
|
for (; loc < TOTAL_LOCALES; ++loc)
|
|
{
|
|
if (loc == GetSessionDbcLocale())
|
|
continue;
|
|
|
|
name = factionEntry->name[loc];
|
|
if (name.empty())
|
|
continue;
|
|
|
|
if (Utf8FitTo(name, wnamepart))
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (loc < TOTAL_LOCALES)
|
|
{
|
|
if (maxResults && count++ == maxResults)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
|
|
return true;
|
|
}
|
|
|
|
// send faction in "id - [faction] rank reputation [visible] [at war] [own team] [unknown] [invisible] [inactive]" format
|
|
// or "id - [faction] [no reputation]" format
|
|
std::ostringstream ss;
|
|
if (m_session)
|
|
ss << id << " - |cffffffff|Hfaction:" << id << "|h[" << name << ' ' << localeNames[loc] << "]|h|r";
|
|
else
|
|
ss << id << " - " << name << ' ' << localeNames[loc];
|
|
|
|
if (repState) // and then target != NULL also
|
|
{
|
|
uint32 index = target->GetReputationMgr().GetReputationRankStrIndex(factionEntry);
|
|
std::string rankName = GetTrinityString(index);
|
|
|
|
ss << ' ' << rankName << "|h|r (" << target->GetReputationMgr().GetReputation(factionEntry) << ')';
|
|
|
|
if (repState->Flags & FACTION_FLAG_VISIBLE)
|
|
ss << GetTrinityString(LANG_FACTION_VISIBLE);
|
|
if (repState->Flags & FACTION_FLAG_AT_WAR)
|
|
ss << GetTrinityString(LANG_FACTION_ATWAR);
|
|
if (repState->Flags & FACTION_FLAG_PEACE_FORCED)
|
|
ss << GetTrinityString(LANG_FACTION_PEACE_FORCED);
|
|
if (repState->Flags & FACTION_FLAG_HIDDEN)
|
|
ss << GetTrinityString(LANG_FACTION_HIDDEN);
|
|
if (repState->Flags & FACTION_FLAG_INVISIBLE_FORCED)
|
|
ss << GetTrinityString(LANG_FACTION_INVISIBLE_FORCED);
|
|
if (repState->Flags & FACTION_FLAG_INACTIVE)
|
|
ss << GetTrinityString(LANG_FACTION_INACTIVE);
|
|
}
|
|
else
|
|
ss << GetTrinityString(LANG_FACTION_NOREPUTATION);
|
|
|
|
SendSysMessage(ss.str().c_str());
|
|
|
|
if (!found)
|
|
found = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!found)
|
|
SendSysMessage(LANG_COMMAND_FACTION_NOTFOUND);
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleLookupTaxiNodeCommand(const char * args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
std::string namepart = args;
|
|
std::wstring wnamepart;
|
|
|
|
if (!Utf8toWStr(namepart, wnamepart))
|
|
return false;
|
|
|
|
// converting string that we try to find to lower case
|
|
wstrToLower(wnamepart);
|
|
|
|
bool found = false;
|
|
uint32 count = 0;
|
|
uint32 maxResults = sWorld->getIntConfig(CONFIG_MAX_RESULTS_LOOKUP_COMMANDS);
|
|
|
|
// Search in TaxiNodes.dbc
|
|
for (uint32 id = 0; id < sTaxiNodesStore.GetNumRows(); id++)
|
|
{
|
|
TaxiNodesEntry const* nodeEntry = sTaxiNodesStore.LookupEntry(id);
|
|
if (nodeEntry)
|
|
{
|
|
int loc = GetSessionDbcLocale();
|
|
std::string name = nodeEntry->name[loc];
|
|
if (name.empty())
|
|
continue;
|
|
|
|
if (!Utf8FitTo(name, wnamepart))
|
|
{
|
|
loc = 0;
|
|
for (; loc < TOTAL_LOCALES; ++loc)
|
|
{
|
|
if (loc == GetSessionDbcLocale())
|
|
continue;
|
|
|
|
name = nodeEntry->name[loc];
|
|
if (name.empty())
|
|
continue;
|
|
|
|
if (Utf8FitTo(name, wnamepart))
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (loc < TOTAL_LOCALES)
|
|
{
|
|
if (maxResults && count++ == maxResults)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
|
|
return true;
|
|
}
|
|
|
|
// send taxinode in "id - [name] (Map:m X:x Y:y Z:z)" format
|
|
if (m_session)
|
|
PSendSysMessage(LANG_TAXINODE_ENTRY_LIST_CHAT, id, id, name.c_str(), localeNames[loc],
|
|
nodeEntry->map_id, nodeEntry->x, nodeEntry->y, nodeEntry->z);
|
|
else
|
|
PSendSysMessage(LANG_TAXINODE_ENTRY_LIST_CONSOLE, id, name.c_str(), localeNames[loc],
|
|
nodeEntry->map_id, nodeEntry->x, nodeEntry->y, nodeEntry->z);
|
|
|
|
if (!found)
|
|
found = true;
|
|
}
|
|
}
|
|
}
|
|
if (!found)
|
|
SendSysMessage(LANG_COMMAND_NOTAXINODEFOUND);
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleLookupMapCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
/*std::string namepart = args;
|
|
std::wstring wnamepart;
|
|
|
|
// converting string that we try to find to lower case
|
|
if (!Utf8toWStr(namepart, wnamepart))
|
|
return false;
|
|
|
|
wstrToLower(wnamepart);
|
|
|
|
bool found = false;
|
|
|
|
// search in Map.dbc
|
|
for (uint32 id = 0; id < sMapStore.GetNumRows(); id++)
|
|
{
|
|
MapEntry const* MapInfo = sMapStore.LookupEntry(id);
|
|
if (MapInfo)
|
|
{
|
|
uint8 loc = m_session ? m_session->GetSessionDbcLocale() : sWorld->GetDefaultDbcLocale();
|
|
|
|
std::string name = MapInfo->name[loc];
|
|
if (name.empty())
|
|
continue;
|
|
|
|
if (!Utf8FitTo(name, wnamepart))
|
|
{
|
|
loc = LOCALE_enUS;
|
|
for (; loc < TOTAL_LOCALES; loc++)
|
|
{
|
|
if (m_session && loc == m_session->GetSessionDbcLocale())
|
|
continue;
|
|
|
|
name = MapInfo->name[loc];
|
|
if (name.empty())
|
|
continue;
|
|
|
|
if (Utf8FitTo(name, wnamepart))
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (loc < TOTAL_LOCALES)
|
|
{
|
|
// send map in "id - [name][Continent][Instance/Battleground/Arena][Raid reset time:][Heroic reset time:][Mountable]" format
|
|
std::ostringstream ss;
|
|
|
|
if (m_session)
|
|
ss << id << " - |cffffffff|Hmap:" << id << "|h[" << name << ']';
|
|
else // console
|
|
ss << id << " - [" << name << ']';
|
|
|
|
if (MapInfo->IsContinent())
|
|
ss << GetTrinityString(LANG_CONTINENT);
|
|
|
|
switch (MapInfo->map_type)
|
|
{
|
|
case MAP_INSTANCE: ss << GetTrinityString(LANG_INSTANCE); break;
|
|
case MAP_BATTLEGROUND: ss << GetTrinityString(LANG_BATTLEGROUND); break;
|
|
case MAP_ARENA: ss << GetTrinityString(LANG_ARENA); break;
|
|
}
|
|
|
|
if (MapInfo->IsRaid())
|
|
ss << GetTrinityString(LANG_RAID);
|
|
|
|
if (MapInfo->SupportsHeroicMode())
|
|
ss << GetTrinityString(LANG_HEROIC);
|
|
|
|
uint32 ResetTimeRaid = MapInfo->resetTimeRaid;
|
|
|
|
std::string ResetTimeRaidStr;
|
|
if (ResetTimeRaid)
|
|
ResetTimeRaidStr = secsToTimeString(ResetTimeRaid, true, false);
|
|
|
|
uint32 ResetTimeHeroic = MapInfo->resetTimeHeroic;
|
|
std::string ResetTimeHeroicStr;
|
|
if (ResetTimeHeroic)
|
|
ResetTimeHeroicStr = secsToTimeString(ResetTimeHeroic, true, false);
|
|
|
|
if (MapInfo->IsMountAllowed())
|
|
ss << GetTrinityString(LANG_MOUNTABLE);
|
|
|
|
if (ResetTimeRaid && !ResetTimeHeroic)
|
|
PSendSysMessage(ss.str().c_str(), ResetTimeRaidStr.c_str());
|
|
else if (!ResetTimeRaid && ResetTimeHeroic)
|
|
PSendSysMessage(ss.str().c_str(), ResetTimeHeroicStr.c_str());
|
|
else if (ResetTimeRaid && ResetTimeHeroic)
|
|
PSendSysMessage(ss.str().c_str(), ResetTimeRaidStr.c_str(), ResetTimeHeroicStr.c_str());
|
|
else
|
|
SendSysMessage(ss.str().c_str());
|
|
|
|
if (!found)
|
|
found = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!found)
|
|
SendSysMessage(LANG_COMMAND_NOMAPFOUND);
|
|
*/
|
|
return true;
|
|
}
|
|
|
|
/** \brief GM command level 3 - Create a guild.
|
|
*
|
|
* This command allows a GM (level 3) to create a guild.
|
|
*
|
|
* The "args" parameter contains the name of the guild leader
|
|
* and then the name of the guild.
|
|
*
|
|
*/
|
|
bool ChatHandler::HandleGuildCreateCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
// if not guild name only (in "") then player name
|
|
Player* target;
|
|
if (!extractPlayerTarget(*args != '"' ? (char*)args : NULL, &target))
|
|
return false;
|
|
|
|
char* tailStr = *args != '"' ? strtok(NULL, "") : (char*)args;
|
|
if (!tailStr)
|
|
return false;
|
|
|
|
char* guildStr = extractQuotedArg(tailStr);
|
|
if (!guildStr)
|
|
return false;
|
|
|
|
std::string guildname = guildStr;
|
|
|
|
if (target->GetGuildId())
|
|
{
|
|
SendSysMessage(LANG_PLAYER_IN_GUILD);
|
|
return true;
|
|
}
|
|
|
|
Guild* guild = new Guild;
|
|
if (!guild->Create(target, guildname))
|
|
{
|
|
delete guild;
|
|
SendSysMessage(LANG_GUILD_NOT_CREATED);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
sGuildMgr->AddGuild(guild);
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleGuildInviteCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
// if not guild name only (in "") then player name
|
|
uint64 target_guid;
|
|
if (!extractPlayerTarget(*args != '"' ? (char*)args : NULL, NULL, &target_guid))
|
|
return false;
|
|
|
|
char* tailStr = *args != '"' ? strtok(NULL, "") : (char*)args;
|
|
if (!tailStr)
|
|
return false;
|
|
|
|
char* guildStr = extractQuotedArg(tailStr);
|
|
if (!guildStr)
|
|
return false;
|
|
|
|
std::string glName = guildStr;
|
|
Guild* targetGuild = sGuildMgr->GetGuildByName(glName);
|
|
if (!targetGuild)
|
|
return false;
|
|
|
|
// player's guild membership checked in AddMember before add
|
|
return targetGuild->AddMember(target_guid);
|
|
}
|
|
|
|
bool ChatHandler::HandleGuildUninviteCommand(const char *args)
|
|
{
|
|
Player* target;
|
|
uint64 target_guid;
|
|
if (!extractPlayerTarget((char*)args, &target, &target_guid))
|
|
return false;
|
|
|
|
uint32 glId = target ? target->GetGuildId() : Player::GetGuildIdFromDB(target_guid);
|
|
if (!glId)
|
|
return false;
|
|
|
|
Guild* targetGuild = sGuildMgr->GetGuildById(glId);
|
|
if (!targetGuild)
|
|
return false;
|
|
|
|
targetGuild->DeleteMember(target_guid, false, true);
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleGuildRankCommand(const char *args)
|
|
{
|
|
char* nameStr;
|
|
char* rankStr;
|
|
extractOptFirstArg((char*)args, &nameStr, &rankStr);
|
|
if (!rankStr)
|
|
return false;
|
|
|
|
Player* target;
|
|
uint64 target_guid;
|
|
std::string target_name;
|
|
if (!extractPlayerTarget(nameStr, &target, &target_guid, &target_name))
|
|
return false;
|
|
|
|
uint32 glId = target ? target->GetGuildId() : Player::GetGuildIdFromDB(target_guid);
|
|
if (!glId)
|
|
return false;
|
|
|
|
Guild* targetGuild = sGuildMgr->GetGuildById (glId);
|
|
if (!targetGuild)
|
|
return false;
|
|
|
|
uint32 newrank = uint32 (atoi (rankStr));
|
|
return targetGuild->ChangeMemberRank(target_guid, newrank);
|
|
}
|
|
|
|
bool ChatHandler::HandleGuildDeleteCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
char* guildStr = extractQuotedArg((char*)args);
|
|
if (!guildStr)
|
|
return false;
|
|
|
|
std::string gld = guildStr;
|
|
|
|
Guild* targetGuild = sGuildMgr->GetGuildByName(gld);
|
|
if (!targetGuild)
|
|
return false;
|
|
|
|
targetGuild->Disband();
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleGetDistanceCommand(const char *args)
|
|
{
|
|
WorldObject* obj = NULL;
|
|
|
|
if (*args)
|
|
{
|
|
uint64 guid = extractGuidFromLink((char*)args);
|
|
if (guid)
|
|
obj = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*m_session->GetPlayer(), guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
|
|
|
|
if (!obj)
|
|
{
|
|
SendSysMessage(LANG_PLAYER_NOT_FOUND);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
obj = getSelectedUnit();
|
|
|
|
if (!obj)
|
|
{
|
|
SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
PSendSysMessage(LANG_DISTANCE, m_session->GetPlayer()->GetDistance(obj), m_session->GetPlayer()->GetDistance2d(obj), m_session->GetPlayer()->GetExactDist(obj), m_session->GetPlayer()->GetExactDist2d(obj));
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleDieCommand(const char* /*args*/)
|
|
{
|
|
Unit* target = getSelectedUnit();
|
|
|
|
if (!target || !m_session->GetPlayer()->GetSelection())
|
|
{
|
|
SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
if (target->GetTypeId() == TYPEID_PLAYER)
|
|
{
|
|
if (HasLowerSecurity((Player*)target, 0, false))
|
|
return false;
|
|
}
|
|
|
|
if (target->isAlive())
|
|
{
|
|
if (sWorld->getBoolConfig(CONFIG_DIE_COMMAND_MODE))
|
|
m_session->GetPlayer()->Kill(target);
|
|
else
|
|
m_session->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleDamageCommand(const char * args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
Unit* target = getSelectedUnit();
|
|
|
|
if (!target || !m_session->GetPlayer()->GetSelection())
|
|
{
|
|
SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
if (target->GetTypeId() == TYPEID_PLAYER)
|
|
{
|
|
if (HasLowerSecurity((Player*)target, 0, false))
|
|
return false;
|
|
}
|
|
|
|
if (!target->isAlive())
|
|
return true;
|
|
|
|
char* damageStr = strtok((char*)args, " ");
|
|
if (!damageStr)
|
|
return false;
|
|
|
|
int32 damage_int = atoi((char*)damageStr);
|
|
if (damage_int <= 0)
|
|
return true;
|
|
|
|
uint32 damage = damage_int;
|
|
|
|
char* schoolStr = strtok((char*)NULL, " ");
|
|
|
|
// flat melee damage without resistence/etc reduction
|
|
if (!schoolStr)
|
|
{
|
|
m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
|
|
if (target != m_session->GetPlayer())
|
|
m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_AFFECTS_VICTIM, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_HIT, 0);
|
|
return true;
|
|
}
|
|
|
|
uint32 school = schoolStr ? atoi((char*)schoolStr) : SPELL_SCHOOL_NORMAL;
|
|
if (school >= MAX_SPELL_SCHOOL)
|
|
return false;
|
|
|
|
SpellSchoolMask schoolmask = SpellSchoolMask(1 << school);
|
|
|
|
if (Unit::IsDamageReducedByArmor(schoolmask))
|
|
damage = m_session->GetPlayer()->CalcArmorReducedDamage(target, damage, NULL, BASE_ATTACK);
|
|
|
|
char* spellStr = strtok((char*)NULL, " ");
|
|
|
|
// melee damage by specific school
|
|
if (!spellStr)
|
|
{
|
|
uint32 absorb = 0;
|
|
uint32 resist = 0;
|
|
|
|
m_session->GetPlayer()->CalcAbsorbResist(target, schoolmask, SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);
|
|
|
|
if (damage <= absorb + resist)
|
|
return true;
|
|
|
|
damage -= absorb + resist;
|
|
|
|
m_session->GetPlayer()->DealDamageMods(target, damage, &absorb);
|
|
m_session->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false);
|
|
m_session->GetPlayer()->SendAttackStateUpdate (HITINFO_AFFECTS_VICTIM, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_HIT, 0);
|
|
return true;
|
|
}
|
|
|
|
// non-melee damage
|
|
|
|
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
|
|
uint32 spellid = extractSpellIdFromLink((char*)args);
|
|
if (!spellid || !sSpellMgr->GetSpellInfo(spellid))
|
|
return false;
|
|
|
|
m_session->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage);
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleReviveCommand(const char *args)
|
|
{
|
|
Player* target;
|
|
uint64 target_guid;
|
|
if (!extractPlayerTarget((char*)args, &target, &target_guid))
|
|
return false;
|
|
|
|
if (target)
|
|
{
|
|
target->ResurrectPlayer(!AccountMgr::IsPlayerAccount(target->GetSession()->GetSecurity()) ? 1.0f : 0.5f);
|
|
target->SpawnCorpseBones();
|
|
target->SaveToDB();
|
|
}
|
|
else
|
|
// will resurrected at login without corpse
|
|
sObjectAccessor->ConvertCorpseForPlayer(target_guid);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleAuraCommand(const char *args)
|
|
{
|
|
Unit* target = getSelectedUnit();
|
|
if (!target)
|
|
{
|
|
SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
|
|
uint32 spellID = extractSpellIdFromLink((char*)args);
|
|
|
|
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellID))
|
|
Aura::TryRefreshStackOrCreate(spellInfo, MAX_EFFECT_MASK, target, target);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleUnAuraCommand(const char *args)
|
|
{
|
|
Unit* target = getSelectedUnit();
|
|
if (!target)
|
|
{
|
|
SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
|
|
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 = extractSpellIdFromLink((char*)args);
|
|
if (!spellID)
|
|
return false;
|
|
|
|
target->RemoveAurasDueToSpell(spellID);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleLinkGraveCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
char* px = strtok((char*)args, " ");
|
|
if (!px)
|
|
return false;
|
|
|
|
uint32 g_id = (uint32)atoi(px);
|
|
|
|
uint32 g_team;
|
|
|
|
char* px2 = strtok(NULL, " ");
|
|
|
|
if (!px2)
|
|
g_team = 0;
|
|
else if (strncmp(px2, "horde", 6) == 0)
|
|
g_team = HORDE;
|
|
else if (strncmp(px2, "alliance", 9) == 0)
|
|
g_team = ALLIANCE;
|
|
else
|
|
return false;
|
|
|
|
WorldSafeLocsEntry const* graveyard = sWorldSafeLocsStore.LookupEntry(g_id);
|
|
|
|
if (!graveyard)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST, g_id);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
Player* player = m_session->GetPlayer();
|
|
|
|
uint32 zoneId = player->GetZoneId();
|
|
|
|
AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(zoneId);
|
|
if (!areaEntry || areaEntry->zone !=0)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, g_id, zoneId);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
if (sObjectMgr->AddGraveYardLink(g_id, zoneId, g_team))
|
|
PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, g_id, zoneId);
|
|
else
|
|
PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, g_id, zoneId);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleNearGraveCommand(const char *args)
|
|
{
|
|
uint32 g_team;
|
|
|
|
size_t argslen = strlen(args);
|
|
|
|
if (!*args)
|
|
g_team = 0;
|
|
else if (strncmp((char*)args, "horde", argslen) == 0)
|
|
g_team = HORDE;
|
|
else if (strncmp((char*)args, "alliance", argslen) == 0)
|
|
g_team = ALLIANCE;
|
|
else
|
|
return false;
|
|
|
|
Player* player = m_session->GetPlayer();
|
|
uint32 zone_id = player->GetZoneId();
|
|
|
|
WorldSafeLocsEntry const* graveyard = sObjectMgr->GetClosestGraveYard(
|
|
player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), g_team);
|
|
|
|
if (graveyard)
|
|
{
|
|
uint32 g_id = graveyard->ID;
|
|
|
|
GraveYardData const* data = sObjectMgr->FindGraveYardData(g_id, zone_id);
|
|
if (!data)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR, g_id);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
g_team = data->team;
|
|
|
|
std::string team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_NOTEAM);
|
|
|
|
if (g_team == 0)
|
|
team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_ANY);
|
|
else if (g_team == HORDE)
|
|
team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_HORDE);
|
|
else if (g_team == ALLIANCE)
|
|
team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
|
|
|
|
PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, g_id, team_name.c_str(), zone_id);
|
|
}
|
|
else
|
|
{
|
|
std::string team_name;
|
|
|
|
if (g_team == 0)
|
|
team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_ANY);
|
|
else if (g_team == HORDE)
|
|
team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_HORDE);
|
|
else if (g_team == ALLIANCE)
|
|
team_name = GetTrinityString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
|
|
|
|
if (g_team == ~uint32(0))
|
|
PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, zone_id);
|
|
else
|
|
PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, zone_id, team_name.c_str());
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleExploreCheatCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
int flag = atoi((char*)args);
|
|
|
|
Player* chr = getSelectedPlayer();
|
|
if (chr == NULL)
|
|
{
|
|
SendSysMessage(LANG_NO_CHAR_SELECTED);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
if (flag != 0)
|
|
{
|
|
PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, GetNameLink(chr).c_str());
|
|
if (needReportToTarget(chr))
|
|
ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL, GetNameLink().c_str());
|
|
}
|
|
else
|
|
{
|
|
PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, GetNameLink(chr).c_str());
|
|
if (needReportToTarget(chr))
|
|
ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING, GetNameLink().c_str());
|
|
}
|
|
|
|
for (uint8 i = 0; i < PLAYER_EXPLORED_ZONES_SIZE; ++i)
|
|
{
|
|
if (flag != 0)
|
|
m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i, 0xFFFFFFFF);
|
|
else
|
|
m_session->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i, 0);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleHoverCommand(const char *args)
|
|
{
|
|
char* px = strtok((char*)args, " ");
|
|
uint32 flag;
|
|
if (!px)
|
|
flag = 1;
|
|
else
|
|
flag = atoi(px);
|
|
|
|
m_session->GetPlayer()->SetHover(flag);
|
|
|
|
if (flag)
|
|
SendSysMessage(LANG_HOVER_ENABLED);
|
|
else
|
|
SendSysMessage(LANG_HOVER_DISABLED);
|
|
|
|
return true;
|
|
}
|
|
|
|
void ChatHandler::HandleCharacterLevel(Player* player, uint64 playerGuid, uint32 oldLevel, uint32 newLevel)
|
|
{
|
|
if (player)
|
|
{
|
|
player->GiveLevel(newLevel);
|
|
player->InitTalentForLevel();
|
|
player->SetUInt32Value(PLAYER_XP, 0);
|
|
|
|
if (needReportToTarget(player))
|
|
{
|
|
if (oldLevel == newLevel)
|
|
ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_PROGRESS_RESET, GetNameLink().c_str());
|
|
else if (oldLevel < newLevel)
|
|
ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_UP, GetNameLink().c_str(), newLevel);
|
|
else // if (oldlevel > newlevel)
|
|
ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_DOWN, GetNameLink().c_str(), newLevel);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Update level and reset XP, everything else will be updated at login
|
|
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_LEVEL);
|
|
|
|
stmt->setUInt8(0, uint8(newLevel));
|
|
stmt->setUInt32(1, GUID_LOPART(playerGuid));
|
|
|
|
CharacterDatabase.Execute(stmt);
|
|
}
|
|
}
|
|
|
|
bool ChatHandler::HandleCharacterLevelCommand(const char *args)
|
|
{
|
|
char* nameStr;
|
|
char* levelStr;
|
|
extractOptFirstArg((char*)args, &nameStr, &levelStr);
|
|
if (!levelStr)
|
|
return false;
|
|
|
|
// exception opt second arg: .character level $name
|
|
if (isalpha(levelStr[0]))
|
|
{
|
|
nameStr = levelStr;
|
|
levelStr = NULL; // current level will used
|
|
}
|
|
|
|
Player* target;
|
|
uint64 target_guid;
|
|
std::string target_name;
|
|
if (!extractPlayerTarget(nameStr, &target, &target_guid, &target_name))
|
|
return false;
|
|
|
|
int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromDB(target_guid);
|
|
int32 newlevel = levelStr ? atoi(levelStr) : oldlevel;
|
|
|
|
if (newlevel < 1)
|
|
return false; // invalid level
|
|
|
|
if (newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
|
|
newlevel = STRONG_MAX_LEVEL;
|
|
|
|
HandleCharacterLevel(target, target_guid, oldlevel, newlevel);
|
|
|
|
if (!m_session || m_session->GetPlayer() != target) // including player == NULL
|
|
{
|
|
std::string nameLink = playerLink(target_name);
|
|
PSendSysMessage(LANG_YOU_CHANGE_LVL, nameLink.c_str(), newlevel);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleLevelUpCommand(const char *args)
|
|
{
|
|
char* nameStr;
|
|
char* levelStr;
|
|
extractOptFirstArg((char*)args, &nameStr, &levelStr);
|
|
|
|
// exception opt second arg: .character level $name
|
|
if (levelStr && isalpha(levelStr[0]))
|
|
{
|
|
nameStr = levelStr;
|
|
levelStr = NULL; // current level will used
|
|
}
|
|
|
|
Player* target;
|
|
uint64 target_guid;
|
|
std::string target_name;
|
|
if (!extractPlayerTarget(nameStr, &target, &target_guid, &target_name))
|
|
return false;
|
|
|
|
int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromDB(target_guid);
|
|
int32 addlevel = levelStr ? atoi(levelStr) : 1;
|
|
int32 newlevel = oldlevel + addlevel;
|
|
|
|
if (newlevel < 1)
|
|
newlevel = 1;
|
|
|
|
if (newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
|
|
newlevel = STRONG_MAX_LEVEL;
|
|
|
|
HandleCharacterLevel(target, target_guid, oldlevel, newlevel);
|
|
|
|
if (!m_session || m_session->GetPlayer() != target) // including chr == NULL
|
|
{
|
|
std::string nameLink = playerLink(target_name);
|
|
PSendSysMessage(LANG_YOU_CHANGE_LVL, nameLink.c_str(), newlevel);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleShowAreaCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
Player* chr = getSelectedPlayer();
|
|
if (chr == NULL)
|
|
{
|
|
SendSysMessage(LANG_NO_CHAR_SELECTED);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
int area = GetAreaFlagByAreaID(atoi((char*)args));
|
|
int offset = area / 32;
|
|
uint32 val = (uint32)(1 << (area % 32));
|
|
|
|
if (area<0 || offset >= PLAYER_EXPLORED_ZONES_SIZE)
|
|
{
|
|
SendSysMessage(LANG_BAD_VALUE);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
|
|
chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val));
|
|
|
|
SendSysMessage(LANG_EXPLORE_AREA);
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleHideAreaCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
Player* chr = getSelectedPlayer();
|
|
if (chr == NULL)
|
|
{
|
|
SendSysMessage(LANG_NO_CHAR_SELECTED);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
int area = GetAreaFlagByAreaID(atoi((char*)args));
|
|
int offset = area / 32;
|
|
uint32 val = (uint32)(1 << (area % 32));
|
|
|
|
if (area<0 || offset >= PLAYER_EXPLORED_ZONES_SIZE)
|
|
{
|
|
SendSysMessage(LANG_BAD_VALUE);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
uint32 currFields = chr->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
|
|
chr->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields ^ val));
|
|
|
|
SendSysMessage(LANG_UNEXPLORE_AREA);
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleBankCommand(const char* /*args*/)
|
|
{
|
|
m_session->SendShowBank(m_session->GetPlayer()->GetGUID());
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleChangeWeather(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
//Weather is OFF
|
|
if (!sWorld->getBoolConfig(CONFIG_WEATHER))
|
|
{
|
|
SendSysMessage(LANG_WEATHER_DISABLED);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
// *Change the weather of a cell
|
|
char* px = strtok((char*)args, " ");
|
|
char* 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 = m_session->GetPlayer();
|
|
uint32 zoneid = player->GetZoneId();
|
|
|
|
Weather* wth = WeatherMgr::FindWeather(zoneid);
|
|
|
|
if (!wth)
|
|
wth = WeatherMgr::AddWeather(zoneid);
|
|
if (!wth)
|
|
{
|
|
SendSysMessage(LANG_NO_WEATHER);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
wth->SetWeather(WeatherType(type), grade);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleListAurasCommand (const char * /*args*/)
|
|
{
|
|
Unit* unit = getSelectedUnit();
|
|
if (!unit)
|
|
{
|
|
SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
char const* talentStr = GetTrinityString(LANG_TALENT);
|
|
char const* passiveStr = GetTrinityString(LANG_PASSIVE);
|
|
|
|
Unit::AuraApplicationMap const& uAuras = unit->GetAppliedAuras();
|
|
PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, uAuras.size());
|
|
for (Unit::AuraApplicationMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr)
|
|
{
|
|
bool talent = GetTalentSpellCost(itr->second->GetBase()->GetId()) > 0;
|
|
|
|
AuraApplication const* aurApp = itr->second;
|
|
Aura const* aura = aurApp->GetBase();
|
|
char const* name = aura->GetSpellInfo()->SpellName[GetSessionDbcLocale()];
|
|
|
|
std::ostringstream ss_name;
|
|
ss_name << "|cffffffff|Hspell:" << aura->GetId() << "|h[" << name << "]|h|r";
|
|
|
|
PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, aura->GetId(), (m_session ? ss_name.str().c_str() : name),
|
|
aurApp->GetEffectMask(), aura->GetCharges(), aura->GetStackAmount(), aurApp->GetSlot(),
|
|
aura->GetDuration(), aura->GetMaxDuration(), (aura->IsPassive() ? passiveStr : ""),
|
|
(talent ? talentStr : ""), IS_PLAYER_GUID(aura->GetCasterGUID()) ? "player" : "creature",
|
|
GUID_LOPART(aura->GetCasterGUID()));
|
|
}
|
|
for (uint16 i = 0; i < TOTAL_AURAS; ++i)
|
|
{
|
|
Unit::AuraEffectList const& uAuraList = unit->GetAuraEffectsByType(AuraType(i));
|
|
if (uAuraList.empty())
|
|
continue;
|
|
|
|
PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, uAuraList.size(), i);
|
|
for (Unit::AuraEffectList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
|
|
(*itr)->GetAmount());
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleResetAchievementsCommand (const char * args)
|
|
{
|
|
Player* target;
|
|
uint64 target_guid;
|
|
if (!extractPlayerTarget((char*)args, &target, &target_guid))
|
|
return false;
|
|
|
|
if (target)
|
|
target->GetAchievementMgr().Reset();
|
|
else
|
|
AchievementMgr::DeleteFromDB(GUID_LOPART(target_guid));
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleResetHonorCommand (const char * args)
|
|
{
|
|
Player* target;
|
|
if (!extractPlayerTarget((char*)args, &target))
|
|
return false;
|
|
|
|
target->SetHonorPoints(0);
|
|
target->SetUInt32Value(PLAYER_FIELD_KILLS, 0);
|
|
target->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, 0);
|
|
target->SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0);
|
|
target->SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0);
|
|
target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL);
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool HandleResetStatsOrLevelHelper(Player* player)
|
|
{
|
|
ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(player->getClass());
|
|
if (!cEntry)
|
|
{
|
|
sLog->outError("Class %u not found in DBC (Wrong DBC files?)", player->getClass());
|
|
return false;
|
|
}
|
|
|
|
uint8 powertype = cEntry->powerType;
|
|
|
|
// reset m_form if no aura
|
|
if (!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT))
|
|
player->SetShapeshiftForm(FORM_NONE);
|
|
|
|
player->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE);
|
|
player->SetFloatValue(UNIT_FIELD_COMBATREACH, DEFAULT_COMBAT_REACH);
|
|
|
|
player->setFactionForRace(player->getRace());
|
|
|
|
player->SetUInt32Value(UNIT_FIELD_BYTES_0, ((player->getRace()) | (player->getClass() << 8) | (player->getGender() << 16) | (powertype << 24)));
|
|
|
|
// reset only if player not in some form;
|
|
if (player->GetShapeshiftForm() == FORM_NONE)
|
|
player->InitDisplayIds();
|
|
|
|
player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP);
|
|
|
|
player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
|
|
|
|
//-1 is default value
|
|
player->SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1));
|
|
|
|
//player->SetUInt32Value(PLAYER_FIELD_BYTES, 0xEEE00000);
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleResetLevelCommand(const char * args)
|
|
{
|
|
Player* target;
|
|
if (!extractPlayerTarget((char*)args, &target))
|
|
return false;
|
|
|
|
if (!HandleResetStatsOrLevelHelper(target))
|
|
return false;
|
|
|
|
uint8 oldLevel = target->getLevel();
|
|
|
|
// set starting level
|
|
uint32 start_level = target->getClass() != CLASS_DEATH_KNIGHT
|
|
? sWorld->getIntConfig(CONFIG_START_PLAYER_LEVEL)
|
|
: sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL);
|
|
|
|
target->_ApplyAllLevelScaleItemMods(false);
|
|
target->SetLevel(start_level);
|
|
target->InitRunes();
|
|
target->InitStatsForLevel(true);
|
|
target->InitTaxiNodesForLevel();
|
|
target->InitGlyphsForLevel();
|
|
target->InitTalentForLevel();
|
|
target->SetUInt32Value(PLAYER_XP, 0);
|
|
|
|
target->_ApplyAllLevelScaleItemMods(true);
|
|
|
|
// reset level for pet
|
|
if (Pet* pet = target->GetPet())
|
|
pet->SynchronizeLevelWithOwner();
|
|
|
|
sScriptMgr->OnPlayerLevelChanged(target, oldLevel);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleResetStatsCommand(const char * args)
|
|
{
|
|
Player* target;
|
|
if (!extractPlayerTarget((char*)args, &target))
|
|
return false;
|
|
|
|
if (!HandleResetStatsOrLevelHelper(target))
|
|
return false;
|
|
|
|
target->InitRunes();
|
|
target->InitStatsForLevel(true);
|
|
target->InitTaxiNodesForLevel();
|
|
target->InitGlyphsForLevel();
|
|
target->InitTalentForLevel();
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleResetSpellsCommand(const char* args)
|
|
{
|
|
Player* target;
|
|
uint64 targetGuid;
|
|
std::string targetName;
|
|
if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
|
|
return false;
|
|
|
|
if (target)
|
|
{
|
|
target->resetSpells(/* bool myClassOnly */);
|
|
|
|
ChatHandler(target).SendSysMessage(LANG_RESET_SPELLS);
|
|
if (!m_session || m_session->GetPlayer() != target)
|
|
PSendSysMessage(LANG_RESET_SPELLS_ONLINE, GetNameLink(target).c_str());
|
|
}
|
|
else
|
|
{
|
|
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
|
|
|
|
stmt->setUInt16(0, uint16(AT_LOGIN_RESET_SPELLS));
|
|
stmt->setUInt32(1, GUID_LOPART(targetGuid));
|
|
|
|
CharacterDatabase.Execute(stmt);
|
|
|
|
PSendSysMessage(LANG_RESET_SPELLS_OFFLINE, targetName.c_str());
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleResetTalentsCommand(const char* args)
|
|
{
|
|
Player* target;
|
|
uint64 targetGuid;
|
|
std::string targetName;
|
|
if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
|
|
{
|
|
// Try reset talents as Hunter Pet
|
|
Creature* creature = getSelectedCreature();
|
|
if (!*args && creature && creature->isPet())
|
|
{
|
|
Unit* owner = creature->GetOwner();
|
|
if (owner && owner->GetTypeId() == TYPEID_PLAYER && creature->ToPet()->IsPermanentPetFor(owner->ToPlayer()))
|
|
{
|
|
creature->ToPet()->resetTalents();
|
|
owner->ToPlayer()->SendTalentsInfoData(true);
|
|
|
|
ChatHandler(owner->ToPlayer()).SendSysMessage(LANG_RESET_PET_TALENTS);
|
|
if (!m_session || m_session->GetPlayer() != owner->ToPlayer())
|
|
PSendSysMessage(LANG_RESET_PET_TALENTS_ONLINE, GetNameLink(owner->ToPlayer()).c_str());
|
|
}
|
|
return true;
|
|
}
|
|
|
|
SendSysMessage(LANG_NO_CHAR_SELECTED);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
if (target)
|
|
{
|
|
target->resetTalents(true);
|
|
target->SendTalentsInfoData(false);
|
|
ChatHandler(target).SendSysMessage(LANG_RESET_TALENTS);
|
|
if (!m_session || m_session->GetPlayer() != target)
|
|
PSendSysMessage(LANG_RESET_TALENTS_ONLINE, GetNameLink(target).c_str());
|
|
|
|
Pet* pet = target->GetPet();
|
|
Pet::resetTalentsForAllPetsOf(target, pet);
|
|
if (pet)
|
|
target->SendTalentsInfoData(true);
|
|
return true;
|
|
}
|
|
else if (targetGuid)
|
|
{
|
|
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
|
|
|
|
stmt->setUInt16(0, uint16(AT_LOGIN_NONE | AT_LOGIN_RESET_PET_TALENTS));
|
|
stmt->setUInt32(1, GUID_LOPART(targetGuid));
|
|
|
|
CharacterDatabase.Execute(stmt);
|
|
|
|
std::string nameLink = playerLink(targetName);
|
|
PSendSysMessage(LANG_RESET_TALENTS_OFFLINE, nameLink.c_str());
|
|
return true;
|
|
}
|
|
|
|
SendSysMessage(LANG_NO_CHAR_SELECTED);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
bool ChatHandler::HandleResetAllCommand(const char * args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
std::string casename = args;
|
|
|
|
AtLoginFlags atLogin;
|
|
|
|
// Command specially created as single command to prevent using short case names
|
|
if (casename == "spells")
|
|
{
|
|
atLogin = AT_LOGIN_RESET_SPELLS;
|
|
sWorld->SendWorldText(LANG_RESETALL_SPELLS);
|
|
if (!m_session)
|
|
SendSysMessage(LANG_RESETALL_SPELLS);
|
|
}
|
|
else if (casename == "talents")
|
|
{
|
|
atLogin = AtLoginFlags(AT_LOGIN_RESET_TALENTS | AT_LOGIN_RESET_PET_TALENTS);
|
|
sWorld->SendWorldText(LANG_RESETALL_TALENTS);
|
|
if (!m_session)
|
|
SendSysMessage(LANG_RESETALL_TALENTS);
|
|
}
|
|
else
|
|
{
|
|
PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE, args);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ALL_AT_LOGIN_FLAGS);
|
|
|
|
stmt->setUInt16(0, uint16(atLogin));
|
|
|
|
CharacterDatabase.Execute(stmt);
|
|
|
|
TRINITY_READ_GUARD(HashMapHolder<Player>::LockType, *HashMapHolder<Player>::GetLock());
|
|
HashMapHolder<Player>::MapType const& plist = sObjectAccessor->GetPlayers();
|
|
for (HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr)
|
|
itr->second->SetAtLoginFlag(atLogin);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleServerShutDownCancelCommand(const char* /*args*/)
|
|
{
|
|
sWorld->ShutdownCancel();
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleServerShutDownCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
char* time_str = strtok ((char*) args, " ");
|
|
char* exitcode_str = strtok (NULL, "");
|
|
|
|
int32 time = atoi (time_str);
|
|
|
|
///- Prevent interpret wrong arg value as 0 secs shutdown time
|
|
if ((time == 0 && (time_str[0] != '0' || time_str[1] != '\0')) || time < 0)
|
|
return false;
|
|
|
|
if (exitcode_str)
|
|
{
|
|
int32 exitcode = atoi (exitcode_str);
|
|
|
|
// Handle atoi() errors
|
|
if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
|
|
return false;
|
|
|
|
// Exit code should be in range of 0-125, 126-255 is used
|
|
// in many shells for their own return codes and code > 255
|
|
// is not supported in many others
|
|
if (exitcode < 0 || exitcode > 125)
|
|
return false;
|
|
|
|
sWorld->ShutdownServ(time, 0, exitcode);
|
|
}
|
|
else
|
|
sWorld->ShutdownServ(time, 0, SHUTDOWN_EXIT_CODE);
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleServerRestartCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
char* time_str = strtok ((char*) args, " ");
|
|
char* exitcode_str = strtok (NULL, "");
|
|
|
|
int32 time = atoi (time_str);
|
|
|
|
///- Prevent interpret wrong arg value as 0 secs shutdown time
|
|
if ((time == 0 && (time_str[0] != '0' || time_str[1] != '\0')) || time < 0)
|
|
return false;
|
|
|
|
if (exitcode_str)
|
|
{
|
|
int32 exitcode = atoi (exitcode_str);
|
|
|
|
// Handle atoi() errors
|
|
if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
|
|
return false;
|
|
|
|
// Exit code should be in range of 0-125, 126-255 is used
|
|
// in many shells for their own return codes and code > 255
|
|
// is not supported in many others
|
|
if (exitcode < 0 || exitcode > 125)
|
|
return false;
|
|
|
|
sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART, exitcode);
|
|
}
|
|
else
|
|
sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE);
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleServerIdleRestartCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
char* time_str = strtok ((char*) args, " ");
|
|
char* exitcode_str = strtok (NULL, "");
|
|
|
|
int32 time = atoi (time_str);
|
|
|
|
///- Prevent interpret wrong arg value as 0 secs shutdown time
|
|
if ((time == 0 && (time_str[0] != '0' || time_str[1] != '\0')) || time < 0)
|
|
return false;
|
|
|
|
if (exitcode_str)
|
|
{
|
|
int32 exitcode = atoi (exitcode_str);
|
|
|
|
// Handle atoi() errors
|
|
if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
|
|
return false;
|
|
|
|
// Exit code should be in range of 0-125, 126-255 is used
|
|
// in many shells for their own return codes and code > 255
|
|
// is not supported in many others
|
|
if (exitcode < 0 || exitcode > 125)
|
|
return false;
|
|
|
|
sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE, exitcode);
|
|
}
|
|
else
|
|
sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE, RESTART_EXIT_CODE);
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleServerIdleShutDownCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
char* time_str = strtok ((char*) args, " ");
|
|
char* exitcode_str = strtok (NULL, "");
|
|
|
|
int32 time = atoi (time_str);
|
|
|
|
///- Prevent interpret wrong arg value as 0 secs shutdown time
|
|
if ((time == 0 && (time_str[0] != '0' || time_str[1] != '\0')) || time < 0)
|
|
return false;
|
|
|
|
if (exitcode_str)
|
|
{
|
|
int32 exitcode = atoi (exitcode_str);
|
|
|
|
// Handle atoi() errors
|
|
if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
|
|
return false;
|
|
|
|
// Exit code should be in range of 0-125, 126-255 is used
|
|
// in many shells for their own return codes and code > 255
|
|
// is not supported in many others
|
|
if (exitcode < 0 || exitcode > 125)
|
|
return false;
|
|
|
|
sWorld->ShutdownServ(time, SHUTDOWN_MASK_IDLE, exitcode);
|
|
}
|
|
else
|
|
sWorld->ShutdownServ(time, SHUTDOWN_MASK_IDLE, SHUTDOWN_EXIT_CODE);
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleBanAccountCommand(const char *args)
|
|
{
|
|
return HandleBanHelper(BAN_ACCOUNT, args);
|
|
}
|
|
|
|
bool ChatHandler::HandleBanAccountByCharCommand(const char *args)
|
|
{
|
|
return HandleBanHelper(BAN_CHARACTER, args);
|
|
}
|
|
|
|
bool ChatHandler::HandleBanCharacterCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
char* cname = strtok((char*)args, " ");
|
|
if (!cname)
|
|
return false;
|
|
|
|
std::string name = cname;
|
|
|
|
char* duration = strtok(NULL, " ");
|
|
if (!duration || !atoi(duration))
|
|
return false;
|
|
|
|
char* reason = strtok(NULL, "");
|
|
if (!reason)
|
|
return false;
|
|
|
|
if (!normalizePlayerName(name))
|
|
{
|
|
SendSysMessage(LANG_PLAYER_NOT_FOUND);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
switch (sWorld->BanCharacter(name, duration, reason, m_session ? m_session->GetPlayerName() : ""))
|
|
{
|
|
case BAN_SUCCESS:
|
|
{
|
|
if (atoi(duration) > 0)
|
|
PSendSysMessage(LANG_BAN_YOUBANNED, name.c_str(), secsToTimeString(TimeStringToSecs(duration), true).c_str(), reason);
|
|
else
|
|
PSendSysMessage(LANG_BAN_YOUPERMBANNED, name.c_str(), reason);
|
|
break;
|
|
}
|
|
case BAN_NOTFOUND:
|
|
{
|
|
PSendSysMessage(LANG_BAN_NOTFOUND, "character", name.c_str());
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleBanIPCommand(const char *args)
|
|
{
|
|
return HandleBanHelper(BAN_IP, args);
|
|
}
|
|
|
|
bool ChatHandler::HandleBanHelper(BanMode mode, const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
char* cnameOrIP = strtok ((char*)args, " ");
|
|
if (!cnameOrIP)
|
|
return false;
|
|
|
|
std::string nameOrIP = cnameOrIP;
|
|
|
|
char* duration = strtok (NULL, " ");
|
|
if (!duration || !atoi(duration))
|
|
return false;
|
|
|
|
char* reason = strtok (NULL, "");
|
|
if (!reason)
|
|
return false;
|
|
|
|
switch (mode)
|
|
{
|
|
case BAN_ACCOUNT:
|
|
if (!AccountMgr::normalizeString(nameOrIP))
|
|
{
|
|
PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, nameOrIP.c_str());
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
break;
|
|
case BAN_CHARACTER:
|
|
if (!normalizePlayerName(nameOrIP))
|
|
{
|
|
SendSysMessage(LANG_PLAYER_NOT_FOUND);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
break;
|
|
case BAN_IP:
|
|
if (!IsIPAddress(nameOrIP.c_str()))
|
|
return false;
|
|
break;
|
|
}
|
|
|
|
switch (sWorld->BanAccount(mode, nameOrIP, duration, reason, m_session ? m_session->GetPlayerName() : ""))
|
|
{
|
|
case BAN_SUCCESS:
|
|
if (atoi(duration)>0)
|
|
PSendSysMessage(LANG_BAN_YOUBANNED, nameOrIP.c_str(), secsToTimeString(TimeStringToSecs(duration), true).c_str(), reason);
|
|
else
|
|
PSendSysMessage(LANG_BAN_YOUPERMBANNED, nameOrIP.c_str(), reason);
|
|
break;
|
|
case BAN_SYNTAX_ERROR:
|
|
return false;
|
|
case BAN_NOTFOUND:
|
|
switch (mode)
|
|
{
|
|
default:
|
|
PSendSysMessage(LANG_BAN_NOTFOUND, "account", nameOrIP.c_str());
|
|
break;
|
|
case BAN_CHARACTER:
|
|
PSendSysMessage(LANG_BAN_NOTFOUND, "character", nameOrIP.c_str());
|
|
break;
|
|
case BAN_IP:
|
|
PSendSysMessage(LANG_BAN_NOTFOUND, "ip", nameOrIP.c_str());
|
|
break;
|
|
}
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleUnBanAccountCommand(const char *args)
|
|
{
|
|
return HandleUnBanHelper(BAN_ACCOUNT, args);
|
|
}
|
|
|
|
bool ChatHandler::HandleUnBanAccountByCharCommand(const char *args)
|
|
{
|
|
return HandleUnBanHelper(BAN_CHARACTER, args);
|
|
}
|
|
|
|
bool ChatHandler::HandleUnBanCharacterCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
char* cname = strtok((char*)args, " ");
|
|
if (!cname)
|
|
return false;
|
|
|
|
std::string name = cname;
|
|
|
|
if (!normalizePlayerName(name))
|
|
{
|
|
SendSysMessage(LANG_PLAYER_NOT_FOUND);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
if (!sWorld->RemoveBanCharacter(name))
|
|
{
|
|
SendSysMessage(LANG_PLAYER_NOT_FOUND);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleUnBanIPCommand(const char *args)
|
|
{
|
|
return HandleUnBanHelper(BAN_IP, args);
|
|
}
|
|
|
|
bool ChatHandler::HandleUnBanHelper(BanMode mode, const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
char* cnameOrIP = strtok ((char*)args, " ");
|
|
if (!cnameOrIP)
|
|
return false;
|
|
|
|
std::string nameOrIP = cnameOrIP;
|
|
|
|
switch (mode)
|
|
{
|
|
case BAN_ACCOUNT:
|
|
if (!AccountMgr::normalizeString(nameOrIP))
|
|
{
|
|
PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, nameOrIP.c_str());
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
break;
|
|
case BAN_CHARACTER:
|
|
if (!normalizePlayerName(nameOrIP))
|
|
{
|
|
SendSysMessage(LANG_PLAYER_NOT_FOUND);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
break;
|
|
case BAN_IP:
|
|
if (!IsIPAddress(nameOrIP.c_str()))
|
|
return false;
|
|
break;
|
|
}
|
|
|
|
if (sWorld->RemoveBanAccount(mode, nameOrIP))
|
|
PSendSysMessage(LANG_UNBAN_UNBANNED, nameOrIP.c_str());
|
|
else
|
|
PSendSysMessage(LANG_UNBAN_ERROR, nameOrIP.c_str());
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleBanInfoAccountCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
char* cname = strtok((char*)args, "");
|
|
if (!cname)
|
|
return false;
|
|
|
|
std::string account_name = cname;
|
|
if (!AccountMgr::normalizeString(account_name))
|
|
{
|
|
PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, account_name.c_str());
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
uint32 accountid = AccountMgr::GetId(account_name);
|
|
if (!accountid)
|
|
{
|
|
PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, account_name.c_str());
|
|
return true;
|
|
}
|
|
|
|
return HandleBanInfoHelper(accountid, account_name.c_str());
|
|
}
|
|
|
|
bool ChatHandler::HandleBanInfoCharacterCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
Player* target = sObjectAccessor->FindPlayerByName(args);
|
|
uint32 target_guid = 0;
|
|
std::string name(args);
|
|
|
|
if (!target)
|
|
{
|
|
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUID_BY_NAME);
|
|
stmt->setString(0, name);
|
|
PreparedQueryResult resultCharacter = CharacterDatabase.Query(stmt);
|
|
|
|
if (!resultCharacter)
|
|
{
|
|
PSendSysMessage(LANG_BANINFO_NOCHARACTER);
|
|
return false;
|
|
}
|
|
|
|
target_guid = (*resultCharacter)[0].GetUInt32();
|
|
}
|
|
else
|
|
target_guid = target->GetGUIDLow();
|
|
|
|
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_BANINFO);
|
|
stmt->setUInt32(0, target_guid);
|
|
PreparedQueryResult result = CharacterDatabase.Query(stmt);
|
|
if (!result)
|
|
{
|
|
PSendSysMessage(LANG_CHAR_NOT_BANNED, name.c_str());
|
|
return true;
|
|
}
|
|
|
|
PSendSysMessage(LANG_BANINFO_BANHISTORY, name.c_str());
|
|
do
|
|
{
|
|
Field* fields = result->Fetch();
|
|
time_t unbandate = time_t(fields[3].GetUInt32());
|
|
bool active = false;
|
|
if (fields[2].GetUInt8() && (!fields[1].GetUInt32() || unbandate >= time(NULL)))
|
|
active = true;
|
|
bool permanent = (fields[1].GetUInt32() == uint32(0));
|
|
std::string bantime = permanent ? GetTrinityString(LANG_BANINFO_INFINITE) : secsToTimeString(fields[1].GetUInt32(), true);
|
|
PSendSysMessage(LANG_BANINFO_HISTORYENTRY,
|
|
fields[0].GetCString(), bantime.c_str(), active ? GetTrinityString(LANG_BANINFO_YES) : GetTrinityString(LANG_BANINFO_NO), fields[4].GetCString(), fields[5].GetCString());
|
|
}
|
|
while (result->NextRow());
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleBanInfoHelper(uint32 accountid, char const* accountname)
|
|
{
|
|
QueryResult result = LoginDatabase.PQuery("SELECT FROM_UNIXTIME(bandate), unbandate-bandate, active, unbandate, banreason, bannedby FROM account_banned WHERE id = '%u' ORDER BY bandate ASC", accountid);
|
|
if (!result)
|
|
{
|
|
PSendSysMessage(LANG_BANINFO_NOACCOUNTBAN, accountname);
|
|
return true;
|
|
}
|
|
|
|
PSendSysMessage(LANG_BANINFO_BANHISTORY, accountname);
|
|
do
|
|
{
|
|
Field* fields = result->Fetch();
|
|
|
|
time_t unbandate = time_t(fields[3].GetUInt64());
|
|
bool active = false;
|
|
if (fields[2].GetBool() && (fields[1].GetUInt64() == (uint64)0 ||unbandate >= time(NULL)))
|
|
active = true;
|
|
bool permanent = (fields[1].GetUInt64() == (uint64)0);
|
|
std::string bantime = permanent ? GetTrinityString(LANG_BANINFO_INFINITE) : secsToTimeString(fields[1].GetUInt64(), true);
|
|
PSendSysMessage(LANG_BANINFO_HISTORYENTRY,
|
|
fields[0].GetCString(), bantime.c_str(), active ? GetTrinityString(LANG_BANINFO_YES) : GetTrinityString(LANG_BANINFO_NO), fields[4].GetCString(), fields[5].GetCString());
|
|
} while (result->NextRow());
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleBanInfoIPCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
char* cIP = strtok ((char*)args, "");
|
|
if (!cIP)
|
|
return false;
|
|
|
|
if (!IsIPAddress(cIP))
|
|
return false;
|
|
|
|
std::string IP = cIP;
|
|
|
|
LoginDatabase.EscapeString(IP);
|
|
QueryResult result = LoginDatabase.PQuery("SELECT ip, FROM_UNIXTIME(bandate), FROM_UNIXTIME(unbandate), unbandate-UNIX_TIMESTAMP(), banreason, bannedby, unbandate-bandate FROM ip_banned WHERE ip = '%s'", IP.c_str());
|
|
if (!result)
|
|
{
|
|
PSendSysMessage(LANG_BANINFO_NOIP);
|
|
return true;
|
|
}
|
|
|
|
Field* fields = result->Fetch();
|
|
bool permanent = !fields[6].GetUInt64();
|
|
PSendSysMessage(LANG_BANINFO_IPENTRY,
|
|
fields[0].GetCString(), fields[1].GetCString(), permanent ? GetTrinityString(LANG_BANINFO_NEVER) : fields[2].GetCString(),
|
|
permanent ? GetTrinityString(LANG_BANINFO_INFINITE) : secsToTimeString(fields[3].GetUInt64(), true).c_str(), fields[4].GetCString(), fields[5].GetCString());
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleBanListCharacterCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
char* cFilter = strtok((char*)args, " ");
|
|
if (!cFilter)
|
|
return false;
|
|
|
|
std::string filter(cFilter);
|
|
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUID_BY_NAME_FILTER);
|
|
stmt->setString(0, filter);
|
|
PreparedQueryResult result = CharacterDatabase.Query(stmt);
|
|
if (!result)
|
|
{
|
|
PSendSysMessage(LANG_BANLIST_NOCHARACTER);
|
|
return true;
|
|
}
|
|
|
|
PSendSysMessage(LANG_BANLIST_MATCHINGCHARACTER);
|
|
|
|
// Chat short output
|
|
if (m_session)
|
|
{
|
|
do
|
|
{
|
|
Field* fields = result->Fetch();
|
|
PreparedStatement* stmt2 = CharacterDatabase.GetPreparedStatement(CHAR_SEL_BANNED_NAME);
|
|
stmt2->setUInt32(0, fields[0].GetUInt32());
|
|
PreparedQueryResult banresult = CharacterDatabase.Query(stmt2);
|
|
if (banresult)
|
|
PSendSysMessage("%s", (*banresult)[0].GetCString());
|
|
}
|
|
while (result->NextRow());
|
|
}
|
|
// Console wide output
|
|
else
|
|
{
|
|
SendSysMessage(LANG_BANLIST_CHARACTERS);
|
|
SendSysMessage(" =============================================================================== ");
|
|
SendSysMessage(LANG_BANLIST_CHARACTERS_HEADER);
|
|
do
|
|
{
|
|
SendSysMessage("-------------------------------------------------------------------------------");
|
|
|
|
Field* fields = result->Fetch();
|
|
|
|
std::string char_name = fields[1].GetString();
|
|
|
|
PreparedStatement* stmt2 = CharacterDatabase.GetPreparedStatement(CHAR_SEL_BANINFO_LIST);
|
|
stmt2->setUInt32(0, fields[0].GetUInt32());
|
|
PreparedQueryResult banInfo = CharacterDatabase.Query(stmt2);
|
|
if (banInfo)
|
|
{
|
|
Field* banFields = banInfo->Fetch();
|
|
do
|
|
{
|
|
time_t t_ban = time_t(banFields[0].GetUInt32());
|
|
tm* aTm_ban = localtime(&t_ban);
|
|
|
|
if (banFields[0].GetUInt32() == banFields[1].GetUInt32())
|
|
{
|
|
PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
|
|
char_name.c_str(), aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min,
|
|
banFields[2].GetCString(), banFields[3].GetCString());
|
|
}
|
|
else
|
|
{
|
|
time_t t_unban = time_t(banFields[1].GetUInt32());
|
|
tm* aTm_unban = localtime(&t_unban);
|
|
PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
|
|
char_name.c_str(), aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min,
|
|
aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
|
|
banFields[2].GetCString(), banFields[3].GetCString());
|
|
}
|
|
}
|
|
while (banInfo->NextRow());
|
|
}
|
|
}
|
|
while (result->NextRow());
|
|
SendSysMessage(" =============================================================================== ");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleBanListAccountCommand(const char *args)
|
|
{
|
|
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS);
|
|
LoginDatabase.Execute(stmt);
|
|
|
|
char* cFilter = strtok((char*)args, " ");
|
|
std::string filter = cFilter ? cFilter : "";
|
|
|
|
PreparedQueryResult result;
|
|
|
|
if (filter.empty())
|
|
{
|
|
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_BANNED_ALL);
|
|
|
|
result = LoginDatabase.Query(stmt);
|
|
}
|
|
else
|
|
{
|
|
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_BANNED_BY_USERNAME);
|
|
|
|
stmt->setString(0, filter);
|
|
|
|
result = LoginDatabase.Query(stmt);
|
|
}
|
|
|
|
if (!result)
|
|
{
|
|
PSendSysMessage(LANG_BANLIST_NOACCOUNT);
|
|
return true;
|
|
}
|
|
|
|
return HandleBanListHelper(result);
|
|
}
|
|
|
|
bool ChatHandler::HandleBanListHelper(PreparedQueryResult result)
|
|
{
|
|
PSendSysMessage(LANG_BANLIST_MATCHINGACCOUNT);
|
|
|
|
// Chat short output
|
|
if (m_session)
|
|
{
|
|
do
|
|
{
|
|
Field* fields = result->Fetch();
|
|
uint32 accountid = fields[0].GetUInt32();
|
|
|
|
QueryResult banresult = LoginDatabase.PQuery("SELECT account.username FROM account, account_banned WHERE account_banned.id='%u' AND account_banned.id=account.id", accountid);
|
|
if (banresult)
|
|
{
|
|
Field* fields2 = banresult->Fetch();
|
|
PSendSysMessage("%s", fields2[0].GetCString());
|
|
}
|
|
} while (result->NextRow());
|
|
}
|
|
// Console wide output
|
|
else
|
|
{
|
|
SendSysMessage(LANG_BANLIST_ACCOUNTS);
|
|
SendSysMessage(" ===============================================================================");
|
|
SendSysMessage(LANG_BANLIST_ACCOUNTS_HEADER);
|
|
do
|
|
{
|
|
SendSysMessage("-------------------------------------------------------------------------------");
|
|
Field* fields = result->Fetch();
|
|
uint32 account_id = fields[0].GetUInt32();
|
|
|
|
std::string account_name;
|
|
|
|
// "account" case, name can be get in same query
|
|
if (result->GetFieldCount() > 1)
|
|
account_name = fields[1].GetString();
|
|
// "character" case, name need extract from another DB
|
|
else
|
|
AccountMgr::GetName (account_id, account_name);
|
|
|
|
// No SQL injection. id is uint32.
|
|
QueryResult banInfo = LoginDatabase.PQuery("SELECT bandate, unbandate, bannedby, banreason FROM account_banned WHERE id = %u ORDER BY unbandate", account_id);
|
|
if (banInfo)
|
|
{
|
|
Field* fields2 = banInfo->Fetch();
|
|
do
|
|
{
|
|
time_t t_ban = fields2[0].GetUInt64();
|
|
tm* aTm_ban = localtime(&t_ban);
|
|
|
|
if (fields2[0].GetUInt64() == fields2[1].GetUInt64())
|
|
{
|
|
PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
|
|
account_name.c_str(), aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min,
|
|
fields2[2].GetCString(), fields2[3].GetCString());
|
|
}
|
|
else
|
|
{
|
|
time_t t_unban = fields2[1].GetUInt64();
|
|
tm* aTm_unban = localtime(&t_unban);
|
|
PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
|
|
account_name.c_str(), aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min,
|
|
aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
|
|
fields2[2].GetCString(), fields2[3].GetCString());
|
|
}
|
|
} while (banInfo->NextRow());
|
|
}
|
|
}while (result->NextRow());
|
|
SendSysMessage(" ===============================================================================");
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleBanListIPCommand(const char *args)
|
|
{
|
|
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS);
|
|
LoginDatabase.Execute(stmt);
|
|
|
|
char* cFilter = strtok((char*)args, " ");
|
|
std::string filter = cFilter ? cFilter : "";
|
|
LoginDatabase.EscapeString(filter);
|
|
|
|
PreparedQueryResult result;
|
|
|
|
if (filter.empty())
|
|
{
|
|
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_BANNED_ALL);
|
|
|
|
result = LoginDatabase.Query(stmt);
|
|
}
|
|
else
|
|
{
|
|
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_BANNED_BY_IP);
|
|
|
|
stmt->setString(0, filter);
|
|
|
|
result = LoginDatabase.Query(stmt);
|
|
}
|
|
|
|
if (!result)
|
|
{
|
|
PSendSysMessage(LANG_BANLIST_NOIP);
|
|
return true;
|
|
}
|
|
|
|
PSendSysMessage(LANG_BANLIST_MATCHINGIP);
|
|
// Chat short output
|
|
if (m_session)
|
|
{
|
|
do
|
|
{
|
|
Field* fields = result->Fetch();
|
|
PSendSysMessage("%s", fields[0].GetCString());
|
|
} while (result->NextRow());
|
|
}
|
|
// Console wide output
|
|
else
|
|
{
|
|
SendSysMessage(LANG_BANLIST_IPS);
|
|
SendSysMessage(" ===============================================================================");
|
|
SendSysMessage(LANG_BANLIST_IPS_HEADER);
|
|
do
|
|
{
|
|
SendSysMessage("-------------------------------------------------------------------------------");
|
|
Field* fields = result->Fetch();
|
|
time_t t_ban = fields[1].GetUInt64();
|
|
tm* aTm_ban = localtime(&t_ban);
|
|
if (fields[1].GetUInt64() == fields[2].GetUInt64())
|
|
{
|
|
PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|",
|
|
fields[0].GetCString(), aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min,
|
|
fields[3].GetCString(), fields[4].GetCString());
|
|
}
|
|
else
|
|
{
|
|
time_t t_unban = fields[2].GetUInt64();
|
|
tm* aTm_unban = localtime(&t_unban);
|
|
PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|",
|
|
fields[0].GetCString(), aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min,
|
|
aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min,
|
|
fields[3].GetCString(), fields[4].GetCString());
|
|
}
|
|
}while (result->NextRow());
|
|
SendSysMessage(" ===============================================================================");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleRespawnCommand(const char* /*args*/)
|
|
{
|
|
Player* player = m_session->GetPlayer();
|
|
|
|
// accept only explicitly selected target (not implicitly self targeting case)
|
|
Unit* target = getSelectedUnit();
|
|
if (player->GetSelection() && target)
|
|
{
|
|
if (target->GetTypeId() != TYPEID_UNIT || target->isPet())
|
|
{
|
|
SendSysMessage(LANG_SELECT_CREATURE);
|
|
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;
|
|
}
|
|
|
|
bool ChatHandler::HandlePDumpLoadCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
char * file = strtok((char*)args, " ");
|
|
if (!file)
|
|
return false;
|
|
|
|
char * account = strtok(NULL, " ");
|
|
if (!account)
|
|
return false;
|
|
|
|
std::string account_name = account;
|
|
if (!AccountMgr::normalizeString(account_name))
|
|
{
|
|
PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, account_name.c_str());
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
uint32 account_id = AccountMgr::GetId(account_name);
|
|
if (!account_id)
|
|
{
|
|
account_id = atoi(account); // use original string
|
|
if (!account_id)
|
|
{
|
|
PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, account_name.c_str());
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (!AccountMgr::GetName(account_id, account_name))
|
|
{
|
|
PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, account_name.c_str());
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
char* guid_str = NULL;
|
|
char* name_str = strtok(NULL, " ");
|
|
|
|
std::string name;
|
|
if (name_str)
|
|
{
|
|
name = name_str;
|
|
// normalize the name if specified and check if it exists
|
|
if (!normalizePlayerName(name))
|
|
{
|
|
PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
if (ObjectMgr::CheckPlayerName(name, true) != CHAR_NAME_SUCCESS)
|
|
{
|
|
PSendSysMessage(LANG_INVALID_CHARACTER_NAME);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
guid_str = strtok(NULL, " ");
|
|
}
|
|
|
|
uint32 guid = 0;
|
|
|
|
if (guid_str)
|
|
{
|
|
guid = atoi(guid_str);
|
|
if (!guid)
|
|
{
|
|
PSendSysMessage(LANG_INVALID_CHARACTER_GUID);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
if (sObjectMgr->GetPlayerAccountIdByGUID(guid))
|
|
{
|
|
PSendSysMessage(LANG_CHARACTER_GUID_IN_USE, guid);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
switch (PlayerDumpReader().LoadDump(file, account_id, name, guid))
|
|
{
|
|
case DUMP_SUCCESS:
|
|
PSendSysMessage(LANG_COMMAND_IMPORT_SUCCESS);
|
|
break;
|
|
case DUMP_FILE_OPEN_ERROR:
|
|
PSendSysMessage(LANG_FILE_OPEN_FAIL, file);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
case DUMP_FILE_BROKEN:
|
|
PSendSysMessage(LANG_DUMP_BROKEN, file);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
case DUMP_TOO_MANY_CHARS:
|
|
PSendSysMessage(LANG_ACCOUNT_CHARACTER_LIST_FULL, account_name.c_str(), account_id);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
default:
|
|
PSendSysMessage(LANG_COMMAND_IMPORT_FAILED);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandlePDumpWriteCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
char* file = strtok((char*)args, " ");
|
|
char* p2 = strtok(NULL, " ");
|
|
|
|
if (!file || !p2)
|
|
return false;
|
|
|
|
uint64 guid;
|
|
// character name can't start from number
|
|
if (isNumeric(p2))
|
|
guid = MAKE_NEW_GUID(atoi(p2), 0, HIGHGUID_PLAYER);
|
|
else
|
|
{
|
|
std::string name = extractPlayerNameFromLink(p2);
|
|
if (name.empty())
|
|
{
|
|
SendSysMessage(LANG_PLAYER_NOT_FOUND);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
guid = sObjectMgr->GetPlayerGUIDByName(name);
|
|
}
|
|
|
|
if (!sObjectMgr->GetPlayerAccountIdByGUID(guid))
|
|
{
|
|
PSendSysMessage(LANG_PLAYER_NOT_FOUND);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
switch (PlayerDumpWriter().WriteDump(file, uint32(guid)))
|
|
{
|
|
case DUMP_SUCCESS:
|
|
PSendSysMessage(LANG_COMMAND_EXPORT_SUCCESS);
|
|
break;
|
|
case DUMP_FILE_OPEN_ERROR:
|
|
PSendSysMessage(LANG_FILE_OPEN_FAIL, file);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
case DUMP_CHARACTER_DELETED:
|
|
PSendSysMessage(LANG_COMMAND_EXPORT_DELETED_CHAR);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
default:
|
|
PSendSysMessage(LANG_COMMAND_EXPORT_FAILED);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleMovegensCommand(const char* /*args*/)
|
|
{
|
|
Unit* unit = getSelectedUnit();
|
|
if (!unit)
|
|
{
|
|
SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
PSendSysMessage(LANG_MOVEGENS_LIST, (unit->GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature"), unit->GetGUIDLow());
|
|
|
|
MotionMaster* mm = unit->GetMotionMaster();
|
|
float x,y,z;
|
|
mm->GetDestination(x,y,z);
|
|
|
|
for (uint8 i = 0; i < MAX_MOTION_SLOT; ++i)
|
|
{
|
|
MovementGenerator* mg = mm->GetMotionSlot(i);
|
|
if (!mg)
|
|
{
|
|
SendSysMessage("Empty");
|
|
continue;
|
|
}
|
|
switch (mg->GetMovementGeneratorType())
|
|
{
|
|
case IDLE_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_IDLE); break;
|
|
case RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_RANDOM); break;
|
|
case WAYPOINT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_WAYPOINT); break;
|
|
case ANIMAL_RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM); break;
|
|
case CONFUSED_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_CONFUSED); break;
|
|
case CHASE_MOTION_TYPE:
|
|
{
|
|
Unit* target = NULL;
|
|
if (unit->GetTypeId() == TYPEID_PLAYER)
|
|
target = static_cast<ChaseMovementGenerator<Player> const*>(mg)->GetTarget();
|
|
else
|
|
target = static_cast<ChaseMovementGenerator<Creature> const*>(mg)->GetTarget();
|
|
|
|
if (!target)
|
|
SendSysMessage(LANG_MOVEGENS_CHASE_NULL);
|
|
else if (target->GetTypeId() == TYPEID_PLAYER)
|
|
PSendSysMessage(LANG_MOVEGENS_CHASE_PLAYER, target->GetName(), target->GetGUIDLow());
|
|
else
|
|
PSendSysMessage(LANG_MOVEGENS_CHASE_CREATURE, target->GetName(), target->GetGUIDLow());
|
|
break;
|
|
}
|
|
case FOLLOW_MOTION_TYPE:
|
|
{
|
|
Unit* target = NULL;
|
|
if (unit->GetTypeId() == TYPEID_PLAYER)
|
|
target = static_cast<FollowMovementGenerator<Player> const*>(mg)->GetTarget();
|
|
else
|
|
target = static_cast<FollowMovementGenerator<Creature> const*>(mg)->GetTarget();
|
|
|
|
if (!target)
|
|
SendSysMessage(LANG_MOVEGENS_FOLLOW_NULL);
|
|
else if (target->GetTypeId() == TYPEID_PLAYER)
|
|
PSendSysMessage(LANG_MOVEGENS_FOLLOW_PLAYER, target->GetName(), target->GetGUIDLow());
|
|
else
|
|
PSendSysMessage(LANG_MOVEGENS_FOLLOW_CREATURE, target->GetName(), target->GetGUIDLow());
|
|
break;
|
|
}
|
|
case HOME_MOTION_TYPE:
|
|
{
|
|
if (unit->GetTypeId() == TYPEID_UNIT)
|
|
PSendSysMessage(LANG_MOVEGENS_HOME_CREATURE, x, y, z);
|
|
else
|
|
SendSysMessage(LANG_MOVEGENS_HOME_PLAYER);
|
|
break;
|
|
}
|
|
case FLIGHT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FLIGHT); break;
|
|
case POINT_MOTION_TYPE:
|
|
{
|
|
PSendSysMessage(LANG_MOVEGENS_POINT, x, y, z);
|
|
break;
|
|
}
|
|
case FLEEING_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FEAR); break;
|
|
case DISTRACT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_DISTRACT); break;
|
|
case EFFECT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_EFFECT); break;
|
|
default:
|
|
PSendSysMessage(LANG_MOVEGENS_UNKNOWN, mg->GetMovementGeneratorType());
|
|
break;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleServerPLimitCommand(const char *args)
|
|
{
|
|
if (*args)
|
|
{
|
|
char* param = strtok((char*)args, " ");
|
|
if (!param)
|
|
return false;
|
|
|
|
int l = strlen(param);
|
|
|
|
if (strncmp(param, "player", l) == 0)
|
|
sWorld->SetPlayerSecurityLimit(SEC_PLAYER);
|
|
else if (strncmp(param, "moderator", l) == 0)
|
|
sWorld->SetPlayerSecurityLimit(SEC_MODERATOR);
|
|
else if (strncmp(param, "gamemaster", l) == 0)
|
|
sWorld->SetPlayerSecurityLimit(SEC_GAMEMASTER);
|
|
else if (strncmp(param, "administrator", l) == 0)
|
|
sWorld->SetPlayerSecurityLimit(SEC_ADMINISTRATOR);
|
|
else if (strncmp(param, "reset", l) == 0)
|
|
{
|
|
sWorld->SetPlayerAmountLimit(ConfigMgr::GetIntDefault("PlayerLimit", 100));
|
|
sWorld->LoadDBAllowedSecurityLevel();
|
|
}
|
|
else
|
|
{
|
|
int val = atoi(param);
|
|
if (val < 0)
|
|
sWorld->SetPlayerSecurityLimit(AccountTypes(uint32(-val)));
|
|
else
|
|
sWorld->SetPlayerAmountLimit(uint32(val));
|
|
}
|
|
}
|
|
|
|
uint32 pLimit = sWorld->GetPlayerAmountLimit();
|
|
AccountTypes allowedAccountType = sWorld->GetPlayerSecurityLimit();
|
|
char const* secName = "";
|
|
switch (allowedAccountType)
|
|
{
|
|
case SEC_PLAYER: secName = "Player"; break;
|
|
case SEC_MODERATOR: secName = "Moderator"; break;
|
|
case SEC_GAMEMASTER: secName = "Gamemaster"; break;
|
|
case SEC_ADMINISTRATOR: secName = "Administrator"; break;
|
|
default: secName = "<unknown>"; break;
|
|
}
|
|
|
|
PSendSysMessage("Player limits: amount %u, min. security level %s.", pLimit, secName);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleCastCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
Unit* target = getSelectedUnit();
|
|
|
|
if (!target)
|
|
{
|
|
SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
|
|
uint32 spell = extractSpellIdFromLink((char*)args);
|
|
if (!spell)
|
|
return false;
|
|
|
|
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell);
|
|
if (!spellInfo)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_NOSPELLFOUND);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
if (!SpellMgr::IsSpellValid(spellInfo, m_session->GetPlayer()))
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spell);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
char* trig_str = strtok(NULL, " ");
|
|
if (trig_str)
|
|
{
|
|
int l = strlen(trig_str);
|
|
if (strncmp(trig_str, "triggered", l) != 0)
|
|
return false;
|
|
}
|
|
|
|
bool triggered = (trig_str != NULL);
|
|
|
|
m_session->GetPlayer()->CastSpell(target, spell, triggered);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleCastBackCommand(const char *args)
|
|
{
|
|
Creature* caster = getSelectedCreature();
|
|
|
|
if (!caster)
|
|
{
|
|
SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
|
|
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
|
|
uint32 spell = extractSpellIdFromLink((char*)args);
|
|
if (!spell || !sSpellMgr->GetSpellInfo(spell))
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_NOSPELLFOUND);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
char* trig_str = strtok(NULL, " ");
|
|
if (trig_str)
|
|
{
|
|
int l = strlen(trig_str);
|
|
if (strncmp(trig_str, "triggered", l) != 0)
|
|
return false;
|
|
}
|
|
|
|
bool triggered = (trig_str != NULL);
|
|
|
|
caster->CastSpell(m_session->GetPlayer(), spell, triggered);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleCastDistCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
|
|
uint32 spell = extractSpellIdFromLink((char*)args);
|
|
if (!spell)
|
|
return false;
|
|
|
|
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell);
|
|
if (!spellInfo)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_NOSPELLFOUND);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
if (!SpellMgr::IsSpellValid(spellInfo, m_session->GetPlayer()))
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spell);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
char *distStr = strtok(NULL, " ");
|
|
|
|
float dist = 0;
|
|
|
|
if (distStr)
|
|
sscanf(distStr, "%f", &dist);
|
|
|
|
char* trig_str = strtok(NULL, " ");
|
|
if (trig_str)
|
|
{
|
|
int l = strlen(trig_str);
|
|
if (strncmp(trig_str, "triggered", l) != 0)
|
|
return false;
|
|
}
|
|
|
|
bool triggered = (trig_str != NULL);
|
|
|
|
float x, y, z;
|
|
m_session->GetPlayer()->GetClosePoint(x, y, z, dist);
|
|
|
|
m_session->GetPlayer()->CastSpell(x, y, z, spell, triggered);
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleCastTargetCommand(const char *args)
|
|
{
|
|
Creature* caster = getSelectedCreature();
|
|
|
|
if (!caster)
|
|
{
|
|
SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
if (!caster->getVictim())
|
|
{
|
|
SendSysMessage(LANG_SELECTED_TARGET_NOT_HAVE_VICTIM);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
|
|
uint32 spell = extractSpellIdFromLink((char*)args);
|
|
if (!spell || !sSpellMgr->GetSpellInfo(spell))
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_NOSPELLFOUND);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
char* trig_str = strtok(NULL, " ");
|
|
if (trig_str)
|
|
{
|
|
int l = strlen(trig_str);
|
|
if (strncmp(trig_str, "triggered", l) != 0)
|
|
return false;
|
|
}
|
|
|
|
bool triggered = (trig_str != NULL);
|
|
|
|
caster->CastSpell(caster->getVictim(), spell, triggered);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleCastDestCommand(const char *args)
|
|
{
|
|
Unit* caster = getSelectedUnit();
|
|
if (!caster)
|
|
{
|
|
SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
|
|
uint32 spell = extractSpellIdFromLink((char*)args);
|
|
if (!spell || !sSpellMgr->GetSpellInfo(spell))
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_NOSPELLFOUND);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
char* px = strtok(NULL, " ");
|
|
char* py = strtok(NULL, " ");
|
|
char* pz = strtok(NULL, " ");
|
|
|
|
if (!px || !py || !pz)
|
|
return false;
|
|
|
|
float x = (float)atof(px);
|
|
float y = (float)atof(py);
|
|
float z = (float)atof(pz);
|
|
|
|
char* trig_str = strtok(NULL, " ");
|
|
if (trig_str)
|
|
{
|
|
int l = strlen(trig_str);
|
|
if (strncmp(trig_str, "triggered", l) != 0)
|
|
return false;
|
|
}
|
|
|
|
bool triggered = (trig_str != NULL);
|
|
|
|
caster->CastSpell(x, y, z, spell, triggered);
|
|
|
|
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
|
|
*/
|
|
bool ChatHandler::HandleComeToMeCommand(const char *args)
|
|
{
|
|
char* newFlagStr = strtok((char*)args, " ");
|
|
|
|
if (!newFlagStr)
|
|
return false;
|
|
|
|
Creature* caster = getSelectedCreature();
|
|
if (!caster)
|
|
{
|
|
SendSysMessage(LANG_SELECT_CREATURE);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
Player* player = m_session->GetPlayer();
|
|
|
|
caster->GetMotionMaster()->MovePoint(0, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ());
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleCastSelfCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
Unit* target = getSelectedUnit();
|
|
|
|
if (!target)
|
|
{
|
|
SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
|
|
uint32 spell = extractSpellIdFromLink((char*)args);
|
|
if (!spell)
|
|
return false;
|
|
|
|
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell);
|
|
if (!spellInfo)
|
|
return false;
|
|
|
|
if (!SpellMgr::IsSpellValid(spellInfo, m_session->GetPlayer()))
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spell);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
target->CastSpell(target, spell, false);
|
|
|
|
return true;
|
|
}
|
|
|
|
std::string GetTimeString(uint64 time)
|
|
{
|
|
uint64 days = time / DAY, hours = (time % DAY) / HOUR, minute = (time % HOUR) / MINUTE;
|
|
std::ostringstream ss;
|
|
if (days) ss << days << "d ";
|
|
if (hours) ss << hours << "h ";
|
|
ss << minute << 'm';
|
|
return ss.str();
|
|
}
|
|
|
|
bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/)
|
|
{
|
|
Player* player = getSelectedPlayer();
|
|
if (!player) player = m_session->GetPlayer();
|
|
uint32 counter = 0;
|
|
for (uint8 i = 0; i < MAX_DIFFICULTY; ++i)
|
|
{
|
|
Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i));
|
|
for (Player::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr)
|
|
{
|
|
InstanceSave* save = itr->second.save;
|
|
std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
|
|
PSendSysMessage("map: %d inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
|
|
counter++;
|
|
}
|
|
}
|
|
PSendSysMessage("player binds: %d", counter);
|
|
counter = 0;
|
|
Group* group = player->GetGroup();
|
|
if (group)
|
|
{
|
|
for (uint8 i = 0; i < MAX_DIFFICULTY; ++i)
|
|
{
|
|
Group::BoundInstancesMap &binds = group->GetBoundInstances(Difficulty(i));
|
|
for (Group::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr)
|
|
{
|
|
InstanceSave* save = itr->second.save;
|
|
std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
|
|
PSendSysMessage("map: %d inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
|
|
counter++;
|
|
}
|
|
}
|
|
}
|
|
PSendSysMessage("group binds: %d", counter);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleInstanceUnbindCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
Player* player = getSelectedPlayer();
|
|
if (!player)
|
|
player = m_session->GetPlayer();
|
|
|
|
char* map = strtok((char*)args, " ");
|
|
char* pDiff = strtok(NULL, " ");
|
|
int8 diff = -1;
|
|
if (pDiff)
|
|
diff = atoi(pDiff);
|
|
uint16 counter = 0;
|
|
uint16 MapId = 0;
|
|
|
|
if (strcmp(map, "all"))
|
|
{
|
|
MapId = uint16(atoi(map));
|
|
if (!MapId)
|
|
return false;
|
|
}
|
|
|
|
for (uint8 i = 0; i < MAX_DIFFICULTY; ++i)
|
|
{
|
|
Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i));
|
|
for (Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();)
|
|
{
|
|
InstanceSave* save = itr->second.save;
|
|
if (itr->first != player->GetMapId() && (!MapId || MapId == itr->first) && (diff == -1 || diff == save->GetDifficulty()))
|
|
{
|
|
std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
|
|
PSendSysMessage("unbinding map: %d inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
|
|
player->UnbindInstance(itr, Difficulty(i));
|
|
counter++;
|
|
}
|
|
else
|
|
++itr;
|
|
}
|
|
}
|
|
PSendSysMessage("instances unbound: %d", counter);
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleInstanceStatsCommand(const char* /*args*/)
|
|
{
|
|
PSendSysMessage("instances loaded: %d", sMapMgr->GetNumInstances());
|
|
PSendSysMessage("players in instances: %d", sMapMgr->GetNumPlayersInInstances());
|
|
PSendSysMessage("instance saves: %d", sInstanceSaveMgr->GetNumInstanceSaves());
|
|
PSendSysMessage("players bound: %d", sInstanceSaveMgr->GetNumBoundPlayersTotal());
|
|
PSendSysMessage("groups bound: %d", sInstanceSaveMgr->GetNumBoundGroupsTotal());
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleInstanceSaveDataCommand(const char * /*args*/)
|
|
{
|
|
Player* player = m_session->GetPlayer();
|
|
|
|
Map* map = player->GetMap();
|
|
if (!map->IsDungeon())
|
|
{
|
|
PSendSysMessage("Map is not a dungeon.");
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
if (!((InstanceMap*)map)->GetInstanceScript())
|
|
{
|
|
PSendSysMessage("Map has no instance data.");
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
((InstanceMap*)map)->GetInstanceScript()->SaveToDB();
|
|
return true;
|
|
}
|
|
|
|
/// Define the 'Message of the day' for the realm
|
|
bool ChatHandler::HandleServerSetMotdCommand(const char *args)
|
|
{
|
|
sWorld->SetMotd(args);
|
|
PSendSysMessage(LANG_MOTD_NEW, args);
|
|
return true;
|
|
}
|
|
|
|
/// Set whether we accept new clients
|
|
bool ChatHandler::HandleServerSetClosedCommand(const char *args)
|
|
{
|
|
if (strncmp(args, "on", 3) == 0)
|
|
{
|
|
SendSysMessage(LANG_WORLD_CLOSED);
|
|
sWorld->SetClosed(true);
|
|
return true;
|
|
}
|
|
else if (strncmp(args, "off", 4) == 0)
|
|
{
|
|
SendSysMessage(LANG_WORLD_OPENED);
|
|
sWorld->SetClosed(false);
|
|
return true;
|
|
}
|
|
|
|
SendSysMessage(LANG_USE_BOL);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
//Send items by mail
|
|
bool ChatHandler::HandleSendItemsCommand(const char *args)
|
|
{
|
|
// format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12]
|
|
Player* receiver;
|
|
uint64 receiver_guid;
|
|
std::string receiver_name;
|
|
if (!extractPlayerTarget((char*)args, &receiver, &receiver_guid, &receiver_name))
|
|
return false;
|
|
|
|
char* tail1 = strtok(NULL, "");
|
|
if (!tail1)
|
|
return false;
|
|
|
|
char* msgSubject = extractQuotedArg(tail1);
|
|
if (!msgSubject)
|
|
return false;
|
|
|
|
char* tail2 = strtok(NULL, "");
|
|
if (!tail2)
|
|
return false;
|
|
|
|
char* msgText = 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* itemIdStr = strtok(itemStr, ":");
|
|
char* itemCountStr = strtok(NULL, " ");
|
|
|
|
uint32 item_id = atoi(itemIdStr);
|
|
if (!item_id)
|
|
return false;
|
|
|
|
ItemTemplate const* item_proto = sObjectMgr->GetItemTemplate(item_id);
|
|
if (!item_proto)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
uint32 item_count = itemCountStr ? atoi(itemCountStr) : 1;
|
|
if (item_count < 1 || (item_proto->MaxCount > 0 && item_count > uint32(item_proto->MaxCount)))
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, item_count, item_id);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
while (item_count > item_proto->GetMaxStackSize())
|
|
{
|
|
items.push_back(ItemPair(item_id, item_proto->GetMaxStackSize()));
|
|
item_count -= item_proto->GetMaxStackSize();
|
|
}
|
|
|
|
items.push_back(ItemPair(item_id, item_count));
|
|
|
|
if (items.size() > MAX_MAIL_ITEMS)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_MAIL_ITEMS_LIMIT, MAX_MAIL_ITEMS);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// from console show not existed sender
|
|
MailSender sender(MAIL_NORMAL, m_session ? m_session->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, m_session ? m_session->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(receiver_guid)), sender);
|
|
CharacterDatabase.CommitTransaction(trans);
|
|
|
|
std::string nameLink = playerLink(receiver_name);
|
|
PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
|
|
return true;
|
|
}
|
|
|
|
///Send money by mail
|
|
bool ChatHandler::HandleSendMoneyCommand(const char *args)
|
|
{
|
|
/// format: name "subject text" "mail text" money
|
|
|
|
Player* receiver;
|
|
uint64 receiver_guid;
|
|
std::string receiver_name;
|
|
if (!extractPlayerTarget((char*)args, &receiver, &receiver_guid, &receiver_name))
|
|
return false;
|
|
|
|
char* tail1 = strtok(NULL, "");
|
|
if (!tail1)
|
|
return false;
|
|
|
|
char* msgSubject = extractQuotedArg(tail1);
|
|
if (!msgSubject)
|
|
return false;
|
|
|
|
char* tail2 = strtok(NULL, "");
|
|
if (!tail2)
|
|
return false;
|
|
|
|
char* msgText = extractQuotedArg(tail2);
|
|
if (!msgText)
|
|
return false;
|
|
|
|
char* money_str = strtok(NULL, "");
|
|
int32 money = money_str ? atoi(money_str) : 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, m_session ? m_session->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM);
|
|
|
|
SQLTransaction trans = CharacterDatabase.BeginTransaction();
|
|
|
|
MailDraft(subject, text)
|
|
.AddMoney(money)
|
|
.SendMailTo(trans, MailReceiver(receiver, GUID_LOPART(receiver_guid)), sender);
|
|
|
|
CharacterDatabase.CommitTransaction(trans);
|
|
|
|
std::string nameLink = playerLink(receiver_name);
|
|
PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
|
|
return true;
|
|
}
|
|
|
|
/// Send a message to a player in game
|
|
bool ChatHandler::HandleSendMessageCommand(const char *args)
|
|
{
|
|
///- Find the player
|
|
Player* rPlayer;
|
|
if (!extractPlayerTarget((char*)args, &rPlayer))
|
|
return false;
|
|
|
|
char* msg_str = strtok(NULL, "");
|
|
if (!msg_str)
|
|
return false;
|
|
|
|
///- Check that he is not logging out.
|
|
if (rPlayer->GetSession()->isLogingOut())
|
|
{
|
|
SendSysMessage(LANG_PLAYER_NOT_FOUND);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
///- Send the message
|
|
//Use SendAreaTriggerMessage for fastest delivery.
|
|
rPlayer->GetSession()->SendAreaTriggerMessage("%s", msg_str);
|
|
rPlayer->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r");
|
|
|
|
//Confirmation message
|
|
std::string nameLink = GetNameLink(rPlayer);
|
|
PSendSysMessage(LANG_SENDMESSAGE, nameLink.c_str(), msg_str);
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleFlushArenaPointsCommand(const char * /*args*/)
|
|
{
|
|
sArenaTeamMgr->DistributeArenaPoints();
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleChannelSetOwnership(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
char *channel = strtok((char*)args, " ");
|
|
char *argstr = strtok(NULL, "");
|
|
|
|
if (!channel || !argstr)
|
|
return false;
|
|
|
|
Player* player = m_session->GetPlayer();
|
|
Channel* chn = NULL;
|
|
|
|
if (ChannelMgr* cMgr = channelMgr(player->GetTeam()))
|
|
chn = cMgr->GetChannel(channel, player);
|
|
|
|
if (strcmp(argstr, "on") == 0)
|
|
{
|
|
if (chn)
|
|
chn->SetOwnership(true);
|
|
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHANNEL_OWNERSHIP);
|
|
stmt->setUInt8 (0, 1);
|
|
stmt->setString(1, channel);
|
|
CharacterDatabase.Execute(stmt);
|
|
PSendSysMessage(LANG_CHANNEL_ENABLE_OWNERSHIP, channel);
|
|
}
|
|
else if (strcmp(argstr, "off") == 0)
|
|
{
|
|
if (chn)
|
|
chn->SetOwnership(false);
|
|
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHANNEL_OWNERSHIP);
|
|
stmt->setUInt8 (0, 0);
|
|
stmt->setString(1, channel);
|
|
CharacterDatabase.Execute(stmt);
|
|
PSendSysMessage(LANG_CHANNEL_DISABLE_OWNERSHIP, channel);
|
|
}
|
|
else
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandlePlayAllCommand(const char *args)
|
|
{
|
|
if (!*args)
|
|
return false;
|
|
|
|
uint32 soundId = atoi((char*)args);
|
|
|
|
if (!sSoundEntriesStore.LookupEntry(soundId))
|
|
{
|
|
PSendSysMessage(LANG_SOUND_NOT_EXIST, soundId);
|
|
SetSentErrorMessage(true);
|
|
return false;
|
|
}
|
|
|
|
WorldPacket data(SMSG_PLAY_SOUND, 4);
|
|
data << uint32(soundId) << m_session->GetPlayer()->GetGUID();
|
|
sWorld->SendGlobalMessage(&data);
|
|
|
|
PSendSysMessage(LANG_COMMAND_PLAYED_TO_ALL, soundId);
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleFreezeCommand(const char *args)
|
|
{
|
|
std::string name;
|
|
Player* player;
|
|
char *TargetName = strtok((char*)args, " "); //get entered name
|
|
if (!TargetName) //if no name entered use target
|
|
{
|
|
player = getSelectedPlayer();
|
|
if (player) //prevent crash with creature as target
|
|
{
|
|
name = player->GetName();
|
|
normalizePlayerName(name);
|
|
}
|
|
}
|
|
else // if name entered
|
|
{
|
|
name = TargetName;
|
|
normalizePlayerName(name);
|
|
player = sObjectAccessor->FindPlayerByName(name.c_str());
|
|
}
|
|
|
|
if (!player)
|
|
{
|
|
SendSysMessage(LANG_COMMAND_FREEZE_WRONG);
|
|
return true;
|
|
}
|
|
|
|
if (player == m_session->GetPlayer())
|
|
{
|
|
SendSysMessage(LANG_COMMAND_FREEZE_ERROR);
|
|
return true;
|
|
}
|
|
|
|
//effect
|
|
if (player && player != m_session->GetPlayer())
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_FREEZE, name.c_str());
|
|
|
|
//stop combat + make player unattackable + duel stop + stop some spells
|
|
player->setFaction(35);
|
|
player->CombatStop();
|
|
if (player->IsNonMeleeSpellCasted(true))
|
|
player->InterruptNonMeleeSpells(true);
|
|
player->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
|
|
|
//if player class = hunter || warlock remove pet if alive
|
|
if ((player->getClass() == CLASS_HUNTER) || (player->getClass() == CLASS_WARLOCK))
|
|
{
|
|
if (Pet* pet = player->GetPet())
|
|
{
|
|
pet->SavePetToDB(PET_SAVE_AS_CURRENT);
|
|
// not let dismiss dead pet
|
|
if (pet && pet->isAlive())
|
|
player->RemovePet(pet, PET_SAVE_NOT_IN_SLOT);
|
|
}
|
|
}
|
|
|
|
//m_session->GetPlayer()->CastSpell(player, spellID, false);
|
|
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(9454))
|
|
Aura::TryRefreshStackOrCreate(spellInfo, MAX_EFFECT_MASK, player, player);
|
|
|
|
//save player
|
|
player->SaveToDB();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleUnFreezeCommand(const char *args)
|
|
{
|
|
std::string name;
|
|
Player* player;
|
|
char *TargetName = strtok((char*)args, " "); //get entered name
|
|
if (!TargetName) //if no name entered use target
|
|
{
|
|
player = getSelectedPlayer();
|
|
if (player) //prevent crash with creature as target
|
|
name = player->GetName();
|
|
}
|
|
|
|
else // if name entered
|
|
{
|
|
name = TargetName;
|
|
normalizePlayerName(name);
|
|
player = sObjectAccessor->FindPlayerByName(name.c_str());
|
|
}
|
|
|
|
//effect
|
|
if (player)
|
|
{
|
|
PSendSysMessage(LANG_COMMAND_UNFREEZE, name.c_str());
|
|
|
|
//Reset player faction + allow combat + allow duels
|
|
player->setFactionForRace(player->getRace());
|
|
player->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
|
|
|
//allow movement and spells
|
|
player->RemoveAurasDueToSpell(9454);
|
|
|
|
//save player
|
|
player->SaveToDB();
|
|
}
|
|
|
|
if (!player)
|
|
{
|
|
if (TargetName)
|
|
{
|
|
// Check for offline players
|
|
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_GUID_BY_NAME);
|
|
stmt->setString(0, name);
|
|
PreparedQueryResult result = CharacterDatabase.Query(stmt);
|
|
|
|
if (!result)
|
|
{
|
|
SendSysMessage(LANG_COMMAND_FREEZE_WRONG);
|
|
return true;
|
|
}
|
|
//if player found: delete his freeze aura
|
|
Field* fields=result->Fetch();
|
|
uint64 pguid = fields[0].GetUInt64();
|
|
|
|
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_AURA_FROZEN);
|
|
stmt->setUInt32(0, pguid);
|
|
CharacterDatabase.Execute(stmt);
|
|
|
|
PSendSysMessage(LANG_COMMAND_UNFREEZE, name.c_str());
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
SendSysMessage(LANG_COMMAND_FREEZE_WRONG);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleListFreezeCommand(const char * /*args*/)
|
|
{
|
|
// Get names from DB
|
|
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_AURA_FROZEN);
|
|
|
|
PreparedQueryResult result = CharacterDatabase.Query(stmt);
|
|
|
|
if (!result)
|
|
{
|
|
SendSysMessage(LANG_COMMAND_NO_FROZEN_PLAYERS);
|
|
return true;
|
|
}
|
|
//Header of the names
|
|
PSendSysMessage(LANG_COMMAND_LIST_FREEZE);
|
|
|
|
//Output of the results
|
|
do
|
|
{
|
|
Field* fields = result->Fetch();
|
|
std::string fplayers = fields[0].GetString();
|
|
PSendSysMessage(LANG_COMMAND_FROZEN_PLAYERS, fplayers.c_str());
|
|
} while (result->NextRow());
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleGroupLeaderCommand(const char *args)
|
|
{
|
|
Player* player = NULL;
|
|
Group* group = NULL;
|
|
uint64 guid = 0;
|
|
char* cname = strtok((char*)args, " ");
|
|
|
|
if (GetPlayerGroupAndGUIDByName(cname, player, group, guid))
|
|
if (group && group->GetLeaderGUID() != guid)
|
|
{
|
|
group->ChangeLeader(guid);
|
|
group->SendUpdate();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleGroupDisbandCommand(const char *args)
|
|
{
|
|
Player* player = NULL;
|
|
Group* group = NULL;
|
|
uint64 guid = 0;
|
|
char* cname = strtok((char*)args, " ");
|
|
|
|
if (GetPlayerGroupAndGUIDByName(cname, player, group, guid))
|
|
if (group)
|
|
group->Disband();
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleGroupRemoveCommand(const char *args)
|
|
{
|
|
Player* player = NULL;
|
|
Group* group = NULL;
|
|
uint64 guid = 0;
|
|
char* cname = strtok((char*)args, " ");
|
|
|
|
if (GetPlayerGroupAndGUIDByName(cname, player, group, guid, true))
|
|
if (group)
|
|
group->RemoveMember(guid);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandlePossessCommand(const char * /*args*/)
|
|
{
|
|
Unit* unit = getSelectedUnit();
|
|
if (!unit)
|
|
return false;
|
|
|
|
m_session->GetPlayer()->CastSpell(unit, 530, true);
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleUnPossessCommand(const char * /*args*/)
|
|
{
|
|
Unit* unit = getSelectedUnit();
|
|
if (!unit)
|
|
unit = m_session->GetPlayer();
|
|
|
|
unit->RemoveCharmAuras();
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleBindSightCommand(const char * /*args*/)
|
|
{
|
|
Unit* unit = getSelectedUnit();
|
|
if (!unit)
|
|
return false;
|
|
|
|
m_session->GetPlayer()->CastSpell(unit, 6277, true);
|
|
return true;
|
|
}
|
|
|
|
bool ChatHandler::HandleUnbindSightCommand(const char * /*args*/)
|
|
{
|
|
Player* player = m_session->GetPlayer();
|
|
|
|
if (player->isPossessing())
|
|
return false;
|
|
|
|
player->StopCastingBindSight();
|
|
return true;
|
|
}
|