diff options
Diffstat (limited to 'src/server/scripts/Commands')
| -rw-r--r-- | src/server/scripts/Commands/CMakeLists.txt | 12 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_cast.cpp | 310 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_character.cpp | 679 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_instance.cpp | 193 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_list.cpp | 469 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_misc.cpp | 9 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_modify.cpp | 89 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_reset.cpp | 310 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_server.cpp | 445 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_tele.cpp | 9 |
10 files changed, 2424 insertions, 101 deletions
diff --git a/src/server/scripts/Commands/CMakeLists.txt b/src/server/scripts/Commands/CMakeLists.txt index 86fe984e197..c27b51a1ca2 100644 --- a/src/server/scripts/Commands/CMakeLists.txt +++ b/src/server/scripts/Commands/CMakeLists.txt @@ -12,30 +12,30 @@ set(scripts_STAT_SRCS ${scripts_STAT_SRCS} Commands/cs_account.cpp Commands/cs_achievement.cpp + Commands/cs_cast.cpp + Commands/cs_character.cpp Commands/cs_debug.cpp Commands/cs_event.cpp Commands/cs_gm.cpp Commands/cs_go.cpp Commands/cs_gobject.cpp Commands/cs_honor.cpp + Commands/cs_instance.cpp Commands/cs_learn.cpp + Commands/cs_list.cpp Commands/cs_misc.cpp Commands/cs_modify.cpp Commands/cs_npc.cpp Commands/cs_quest.cpp Commands/cs_reload.cpp + Commands/cs_reset.cpp Commands/cs_tele.cpp + Commands/cs_server.cpp Commands/cs_titles.cpp Commands/cs_wp.cpp -# Commands/cs_character.cpp -# Commands/cs_list.cpp # Commands/cs_lookup.cpp # Commands/cs_pdump.cpp # Commands/cs_guild.cpp -# Commands/cs_cast.cpp -# Commands/cs_reset.cpp -# Commands/cs_instance.cpp -# Commands/cs_server.cpp # Commands/cs_channel.cpp # Commands/cs_pet.cpp # Commands/cs_ticket.cpp diff --git a/src/server/scripts/Commands/cs_cast.cpp b/src/server/scripts/Commands/cs_cast.cpp new file mode 100644 index 00000000000..33983411427 --- /dev/null +++ b/src/server/scripts/Commands/cs_cast.cpp @@ -0,0 +1,310 @@ +/* + * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> + * + * 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/>. + */ + +/* ScriptData +Name: cast_commandscript +%Complete: 100 +Comment: All cast related commands +Category: commandscripts +EndScriptData */ + +#include "ScriptMgr.h" +#include "Chat.h" + +class cast_commandscript : public CommandScript +{ +public: + cast_commandscript() : CommandScript("cast_commandscript") { } + + ChatCommand* GetCommands() const + { + static ChatCommand castCommandTable[] = + { + { "back", SEC_ADMINISTRATOR, false, &HandleCastBackCommand, "", NULL }, + { "dist", SEC_ADMINISTRATOR, false, &HandleCastDistCommand, "", NULL }, + { "self", SEC_ADMINISTRATOR, false, &HandleCastSelfCommand, "", NULL }, + { "target", SEC_ADMINISTRATOR, false, &HandleCastTargetCommad, "", NULL }, + { "dest", SEC_ADMINISTRATOR, false, &HandleCastDestCommand, "", NULL }, + { "", SEC_ADMINISTRATOR, false, &HandleCastCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand commandTable[] = + { + { "cast", SEC_ADMINISTRATOR, false, NULL, "", castCommandTable }, + { NULL, 0, false, NULL, "", NULL } + }; + return commandTable; + } + + static bool HandleCastCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + Unit* target = handler->getSelectedUnit(); + if (!target) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spellId = handler->extractSpellIdFromLink((char*)args); + if (!spellId) + return false; + + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); + if (!spellInfo) + { + handler->PSendSysMessage(LANG_COMMAND_NOSPELLFOUND); + handler->SetSentErrorMessage(true); + return false; + } + + if (!SpellMgr::IsSpellValid(spellInfo, handler->GetSession()->GetPlayer())) + { + handler->PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spellId); + handler->SetSentErrorMessage(true); + return false; + } + + char* triggeredStr = strtok(NULL, " "); + if (triggeredStr) + { + int l = strlen(triggeredStr); + if (strncmp(triggeredStr, "triggered", l) != 0) + return false; + } + + bool triggered = (triggeredStr != NULL); + + handler->GetSession()->GetPlayer()->CastSpell(target, spellId, triggered); + + return true; + } + + static bool HandleCastBackCommand(ChatHandler* handler, char const* args) + { + Creature* caster = handler->getSelectedCreature(); + if (!caster) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spellId = handler->extractSpellIdFromLink((char*)args); + if (!spellId || !sSpellMgr->GetSpellInfo(spellId)) + { + handler->PSendSysMessage(LANG_COMMAND_NOSPELLFOUND); + handler->SetSentErrorMessage(true); + return false; + } + + char* triggeredStr = strtok(NULL, " "); + if (triggeredStr) + { + int l = strlen(triggeredStr); + if (strncmp(triggeredStr, "triggered", l) != 0) + return false; + } + + bool triggered = (triggeredStr != NULL); + + caster->CastSpell(handler->GetSession()->GetPlayer(), spellId, triggered); + + return true; + } + + static bool HandleCastDistCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spellId = handler->extractSpellIdFromLink((char*)args); + if (!spellId) + return false; + + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); + if (!spellInfo) + { + handler->PSendSysMessage(LANG_COMMAND_NOSPELLFOUND); + handler->SetSentErrorMessage(true); + return false; + } + + if (!SpellMgr::IsSpellValid(spellInfo, handler->GetSession()->GetPlayer())) + { + handler->PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spellId); + handler->SetSentErrorMessage(true); + return false; + } + + char* distStr = strtok(NULL, " "); + + float dist = 0; + + if (distStr) + sscanf(distStr, "%f", &dist); + + char* triggeredStr = strtok(NULL, " "); + if (triggeredStr) + { + int l = strlen(triggeredStr); + if (strncmp(triggeredStr, "triggered", l) != 0) + return false; + } + + bool triggered = (triggeredStr != NULL); + + float x, y, z; + handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, dist); + + handler->GetSession()->GetPlayer()->CastSpell(x, y, z, spellId, triggered); + + return true; + } + + static bool HandleCastSelfCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + Unit* target = handler->getSelectedUnit(); + if (!target) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spellId = handler->extractSpellIdFromLink((char*)args); + if (!spellId) + return false; + + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); + if (!spellInfo) + return false; + + if (!SpellMgr::IsSpellValid(spellInfo, handler->GetSession()->GetPlayer())) + { + handler->PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spellId); + handler->SetSentErrorMessage(true); + return false; + } + + target->CastSpell(target, spellId, false); + + return true; + } + + static bool HandleCastTargetCommad(ChatHandler* handler, char const* args) + { + Creature* caster = handler->getSelectedCreature(); + if (!caster) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + if (!caster->getVictim()) + { + handler->SendSysMessage(LANG_SELECTED_TARGET_NOT_HAVE_VICTIM); + handler->SetSentErrorMessage(true); + return false; + } + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spellId = handler->extractSpellIdFromLink((char*)args); + if (!spellId || !sSpellMgr->GetSpellInfo(spellId)) + { + handler->PSendSysMessage(LANG_COMMAND_NOSPELLFOUND); + handler->SetSentErrorMessage(true); + return false; + } + + char* triggeredStr = strtok(NULL, " "); + if (triggeredStr) + { + int l = strlen(triggeredStr); + if (strncmp(triggeredStr, "triggered", l) != 0) + return false; + } + + bool triggered = (triggeredStr != NULL); + + caster->CastSpell(caster->getVictim(), spellId, triggered); + + return true; + } + + static bool HandleCastDestCommand(ChatHandler* handler, char const* args) + { + Unit* caster = handler->getSelectedUnit(); + if (!caster) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spellId = handler->extractSpellIdFromLink((char*)args); + if (!spellId || !sSpellMgr->GetSpellInfo(spellId)) + { + handler->PSendSysMessage(LANG_COMMAND_NOSPELLFOUND); + handler->SetSentErrorMessage(true); + return false; + } + + char* posX = strtok(NULL, " "); + char* posY = strtok(NULL, " "); + char* posZ = strtok(NULL, " "); + + if (!posX || !posY || !posZ) + return false; + + float x = float(atof(posX)); + float y = float(atof(posY)); + float z = float(atof(posZ)); + + char* triggeredStr = strtok(NULL, " "); + if (triggeredStr) + { + int l = strlen(triggeredStr); + if (strncmp(triggeredStr, "triggered", l) != 0) + return false; + } + + bool triggered = (triggeredStr != NULL); + + caster->CastSpell(x, y, z, spellId, triggered); + + return true; + } +}; + +void AddSC_cast_commandscript() +{ + new cast_commandscript(); +} diff --git a/src/server/scripts/Commands/cs_character.cpp b/src/server/scripts/Commands/cs_character.cpp new file mode 100644 index 00000000000..e6d397ead2b --- /dev/null +++ b/src/server/scripts/Commands/cs_character.cpp @@ -0,0 +1,679 @@ +/* + * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> + * + * 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/>. + */ + +/* ScriptData +Name: character_commandscript +%Complete: 100 +Comment: All character related commands +Category: commandscripts +EndScriptData */ + +#include "ScriptMgr.h" +#include "Chat.h" +#include "AccountMgr.h" +#include "ObjectMgr.h" + +class character_commandscript : public CommandScript +{ +public: + character_commandscript() : CommandScript("character_commandscript") { } + + ChatCommand* GetCommands() const + { + static ChatCommand characterDeletedCommandTable[] = + { + { "delete", SEC_CONSOLE, true, &HandleCharacterDeletedDeleteCommand, "", NULL }, + { "list", SEC_ADMINISTRATOR, true, &HandleCharacterDeletedListCommand, "", NULL }, + { "restore", SEC_ADMINISTRATOR, true, &HandleCharacterDeletedRestoreCommand, "", NULL }, + { "old", SEC_CONSOLE, true, &HandleCharacterDeletedOldCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + + static ChatCommand characterCommandTable[] = + { + { "customize", SEC_GAMEMASTER, true, &HandleCharacterCustomizeCommand, "", NULL }, + { "changefaction", SEC_GAMEMASTER, true, &HandleCharacterChangeFactionCommand, "", NULL }, + { "changerace", SEC_GAMEMASTER, true, &HandleCharacterChangeRaceCommand, "", NULL }, + { "deleted", SEC_GAMEMASTER, true, NULL, "", characterDeletedCommandTable}, + { "erase", SEC_CONSOLE, true, &HandleCharacterEraseCommand, "", NULL }, + { "level", SEC_ADMINISTRATOR, true, &HandleCharacterLevelCommand, "", NULL }, + { "rename", SEC_GAMEMASTER, true, &HandleCharacterRenameCommand, "", NULL }, + { "reputation", SEC_GAMEMASTER, true, &HandleCharacterReputationCommand, "", NULL }, + { "titles", SEC_GAMEMASTER, true, &HandleCharacterTitlesCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + + static ChatCommand commandTable[] = + { + { "character", SEC_GAMEMASTER, true, NULL, "", characterCommandTable}, + { NULL, 0, false, NULL, "", NULL } + }; + return commandTable; + } + + // Stores informations about a deleted character + struct DeletedInfo + { + uint32 lowGuid; ///< the low GUID from the character + std::string name; ///< the character name + uint32 accountId; ///< the account id + std::string accountName; ///< the account name + time_t deleteDate; ///< the date at which the character has been deleted + }; + + typedef std::list<DeletedInfo> DeletedInfoList; + + /** + * Collects all GUIDs (and related info) from deleted characters which are still in the database. + * + * @param foundList a reference to an std::list which will be filled with info data + * @param searchString the search string which either contains a player GUID or a part fo the character-name + * @return returns false if there was a problem while selecting the characters (e.g. player name not normalizeable) + */ + static bool GetDeletedCharacterInfoList(DeletedInfoList& foundList, std::string searchString) + { + PreparedQueryResult result; + PreparedStatement* stmt; + if (!searchString.empty()) + { + // search by GUID + if (isNumeric(searchString.c_str())) + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_DEL_INFO_BY_GUID); + stmt->setUInt32(0, uint32(atoi(searchString.c_str()))); + result = CharacterDatabase.Query(stmt); + } + // search by name + else + { + if (!normalizePlayerName(searchString)) + return false; + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_DEL_INFO_BY_NAME); + stmt->setString(0, searchString); + result = CharacterDatabase.Query(stmt); + } + } + else + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_DEL_INFO); + result = CharacterDatabase.Query(stmt); + } + + if (result) + { + do + { + Field* fields = result->Fetch(); + + DeletedInfo info; + + info.lowGuid = fields[0].GetUInt32(); + info.name = fields[1].GetString(); + info.accountId = fields[2].GetUInt32(); + + // account name will be empty for not existed account + AccountMgr::GetName(info.accountId, info.accountName); + info.deleteDate = time_t(fields[3].GetUInt32()); + foundList.push_back(info); + } + while (result->NextRow()); + } + + return true; + } + + /** + * Shows all deleted characters which matches the given search string, expected non empty list + * + * @see HandleCharacterDeletedListCommand + * @see HandleCharacterDeletedRestoreCommand + * @see HandleCharacterDeletedDeleteCommand + * @see DeletedInfoList + * + * @param foundList contains a list with all found deleted characters + */ + static void HandleCharacterDeletedListHelper(DeletedInfoList const& foundList, ChatHandler* handler) + { + if (!handler->GetSession()) + { + handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_BAR); + handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_HEADER); + handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_BAR); + } + + for (DeletedInfoList::const_iterator itr = foundList.begin(); itr != foundList.end(); ++itr) + { + std::string dateStr = TimeToTimestampStr(itr->deleteDate); + + if (!handler->GetSession()) + handler->PSendSysMessage(LANG_CHARACTER_DELETED_LIST_LINE_CONSOLE, + itr->lowGuid, itr->name.c_str(), itr->accountName.empty() ? "<Not existed>" : itr->accountName.c_str(), + itr->accountId, dateStr.c_str()); + else + handler->PSendSysMessage(LANG_CHARACTER_DELETED_LIST_LINE_CHAT, + itr->lowGuid, itr->name.c_str(), itr->accountName.empty() ? "<Not existed>" : itr->accountName.c_str(), + itr->accountId, dateStr.c_str()); + } + + if (!handler->GetSession()) + handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_BAR); + } + + /** + * Restore a previously deleted character + * + * @see HandleCharacterDeletedListHelper + * @see HandleCharacterDeletedRestoreCommand + * @see HandleCharacterDeletedDeleteCommand + * @see DeletedInfoList + * + * @param delInfo the informations about the character which will be restored + */ + static void HandleCharacterDeletedRestoreHelper(DeletedInfo const& delInfo, ChatHandler* handler) + { + if (delInfo.accountName.empty()) // account not exist + { + handler->PSendSysMessage(LANG_CHARACTER_DELETED_SKIP_ACCOUNT, delInfo.name.c_str(), delInfo.lowGuid, delInfo.accountId); + return; + } + + // check character count + uint32 charcount = AccountMgr::GetCharactersCount(delInfo.accountId); + if (charcount >= 10) + { + handler->PSendSysMessage(LANG_CHARACTER_DELETED_SKIP_FULL, delInfo.name.c_str(), delInfo.lowGuid, delInfo.accountId); + return; + } + + if (sObjectMgr->GetPlayerGUIDByName(delInfo.name)) + { + handler->PSendSysMessage(LANG_CHARACTER_DELETED_SKIP_NAME, delInfo.name.c_str(), delInfo.lowGuid, delInfo.accountId); + return; + } + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_RESTORE_DELETE_INFO); + stmt->setString(0, delInfo.name); + stmt->setUInt32(1, delInfo.accountId); + stmt->setUInt32(2, delInfo.lowGuid); + CharacterDatabase.Execute(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_NAME_DATA); + stmt->setUInt32(0, delInfo.lowGuid); + if (PreparedQueryResult result = CharacterDatabase.Query(stmt)) + sWorld->AddCharacterNameData(delInfo.lowGuid, delInfo.name, (*result)[2].GetUInt8(), (*result)[0].GetUInt8(), (*result)[1].GetUInt8()); + } + + static bool HandleCharacterTitlesCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + Player* target; + if (!handler->extractPlayerTarget((char*)args, &target)) + return false; + + LocaleConstant loc = handler->GetSessionDbcLocale(); + char const* targetName = target->GetName(); + char const* knownStr = handler->GetTrinityString(LANG_KNOWN); + + // Search in CharTitles.dbc + for (uint32 id = 0; id < sCharTitlesStore.GetNumRows(); id++) + { + CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(id); + + if (titleInfo && target->HasTitle(titleInfo)) + { + std::string name = titleInfo->name; + if (name.empty()) + continue; + + char const* activeStr = target && target->GetUInt32Value(PLAYER_CHOSEN_TITLE) == titleInfo->bit_index + ? handler->GetTrinityString(LANG_ACTIVE) + : ""; + + char titleNameStr[80]; + snprintf(titleNameStr, 80, name.c_str(), targetName); + + // send title in "id (idx:idx) - [namedlink locale]" format + if (handler->GetSession()) + handler->PSendSysMessage(LANG_TITLE_LIST_CHAT, id, titleInfo->bit_index, id, titleNameStr, localeNames[loc], knownStr, activeStr); + else + handler->PSendSysMessage(LANG_TITLE_LIST_CONSOLE, id, titleInfo->bit_index, name.c_str(), localeNames[loc], knownStr, activeStr); + } + } + + return true; + } + + //rename characters + static bool HandleCharacterRenameCommand(ChatHandler* handler, char const* args) + { + Player* target; + uint64 targetGuid; + std::string targetName; + if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) + return false; + + if (target) + { + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + handler->PSendSysMessage(LANG_RENAME_PLAYER, handler->GetNameLink(target).c_str()); + target->SetAtLoginFlag(AT_LOGIN_RENAME); + } + else + { + // check offline security + if (handler->HasLowerSecurity(NULL, targetGuid)) + return false; + + std::string oldNameLink = handler->playerLink(targetName); + handler->PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid)); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); + stmt->setUInt16(0, uint16(AT_LOGIN_RENAME)); + stmt->setUInt32(1, GUID_LOPART(targetGuid)); + CharacterDatabase.Execute(stmt); + } + + return true; + } + + static bool HandleCharacterLevelCommand(ChatHandler* handler, char const* args) + { + char* nameStr; + char* levelStr; + handler->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 targetGuid; + std::string targetName; + if (!handler->extractPlayerTarget(nameStr, &target, &targetGuid, &targetName)) + return false; + + int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromDB(targetGuid); + 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; + + handler->HandleCharacterLevel(target, targetGuid, oldlevel, newlevel); + if (!handler->GetSession() || handler->GetSession()->GetPlayer() != target) // including player == NULL + { + std::string nameLink = handler->playerLink(targetName); + handler->PSendSysMessage(LANG_YOU_CHANGE_LVL, nameLink.c_str(), newlevel); + } + + return true; + } + + // customize characters + static bool HandleCharacterCustomizeCommand(ChatHandler* handler, char const* args) + { + Player* target; + uint64 targetGuid; + std::string targetName; + if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) + return false; + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); + stmt->setUInt16(0, uint16(AT_LOGIN_CUSTOMIZE)); + if (target) + { + handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER, handler->GetNameLink(target).c_str()); + target->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE); + stmt->setUInt32(1, target->GetGUIDLow()); + } + else + { + std::string oldNameLink = handler->playerLink(targetName); + stmt->setUInt32(1, GUID_LOPART(targetGuid)); + handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid)); + } + CharacterDatabase.Execute(stmt); + + return true; + } + + static bool HandleCharacterChangeFactionCommand(ChatHandler* handler, char const* args) + { + Player* target; + uint64 targetGuid; + std::string targetName; + + if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) + return false; + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); + stmt->setUInt16(0, uint16(AT_LOGIN_CHANGE_FACTION)); + if (target) + { + handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER, handler->GetNameLink(target).c_str()); + target->SetAtLoginFlag(AT_LOGIN_CHANGE_FACTION); + stmt->setUInt32(1, target->GetGUIDLow()); + } + else + { + std::string oldNameLink = handler->playerLink(targetName); + handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid)); + stmt->setUInt32(1, GUID_LOPART(targetGuid)); + } + CharacterDatabase.Execute(stmt); + + return true; + } + + static bool HandleCharacterChangeRaceCommand(ChatHandler* handler, char const* args) + { + Player* target; + uint64 targetGuid; + std::string targetName; + if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) + return false; + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); + stmt->setUInt16(0, uint16(AT_LOGIN_CHANGE_RACE)); + if (target) + { + // TODO : add text into database + handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER, handler->GetNameLink(target).c_str()); + target->SetAtLoginFlag(AT_LOGIN_CHANGE_RACE); + stmt->setUInt32(1, target->GetGUIDLow()); + } + else + { + std::string oldNameLink = handler->playerLink(targetName); + // TODO : add text into database + handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid)); + stmt->setUInt32(1, GUID_LOPART(targetGuid)); + } + CharacterDatabase.Execute(stmt); + + return true; + } + + static bool HandleCharacterReputationCommand(ChatHandler* handler, char const* args) + { + Player* target; + if (!handler->extractPlayerTarget((char*)args, &target)) + return false; + + LocaleConstant loc = handler->GetSessionDbcLocale(); + + FactionStateList const& targetFSL = target->GetReputationMgr().GetStateList(); + for (FactionStateList::const_iterator itr = targetFSL.begin(); itr != targetFSL.end(); ++itr) + { + FactionState const& faction = itr->second; + FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction.ID); + char const* factionName = factionEntry ? factionEntry->name : "#Not found#"; + ReputationRank rank = target->GetReputationMgr().GetRank(factionEntry); + std::string rankName = handler->GetTrinityString(ReputationRankStrIndex[rank]); + std::ostringstream ss; + if (handler->GetSession()) + ss << faction.ID << " - |cffffffff|Hfaction:" << faction.ID << "|h[" << factionName << ' ' << localeNames[loc] << "]|h|r"; + else + ss << faction.ID << " - " << factionName << ' ' << localeNames[loc]; + + ss << ' ' << rankName << " (" << target->GetReputationMgr().GetReputation(factionEntry) << ')'; + + if (faction.Flags & FACTION_FLAG_VISIBLE) + ss << handler->GetTrinityString(LANG_FACTION_VISIBLE); + if (faction.Flags & FACTION_FLAG_AT_WAR) + ss << handler->GetTrinityString(LANG_FACTION_ATWAR); + if (faction.Flags & FACTION_FLAG_PEACE_FORCED) + ss << handler->GetTrinityString(LANG_FACTION_PEACE_FORCED); + if (faction.Flags & FACTION_FLAG_HIDDEN) + ss << handler->GetTrinityString(LANG_FACTION_HIDDEN); + if (faction.Flags & FACTION_FLAG_INVISIBLE_FORCED) + ss << handler->GetTrinityString(LANG_FACTION_INVISIBLE_FORCED); + if (faction.Flags & FACTION_FLAG_INACTIVE) + ss << handler->GetTrinityString(LANG_FACTION_INACTIVE); + + handler->SendSysMessage(ss.str().c_str()); + } + + return true; + } + + /** + * Handles the '.character deleted list' command, which shows all deleted characters which matches the given search string + * + * @see HandleCharacterDeletedListHelper + * @see HandleCharacterDeletedRestoreCommand + * @see HandleCharacterDeletedDeleteCommand + * @see DeletedInfoList + * + * @param args the search string which either contains a player GUID or a part fo the character-name + */ + static bool HandleCharacterDeletedListCommand(ChatHandler* handler, char const* args) + { + DeletedInfoList foundList; + if (!GetDeletedCharacterInfoList(foundList, args)) + return false; + + // if no characters have been found, output a warning + if (foundList.empty()) + { + handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_EMPTY); + return false; + } + + HandleCharacterDeletedListHelper(foundList, handler); + + return true; + } + + /** + * Handles the '.character deleted restore' command, which restores all deleted characters which matches the given search string + * + * The command automatically calls '.character deleted list' command with the search string to show all restored characters. + * + * @see HandleCharacterDeletedRestoreHelper + * @see HandleCharacterDeletedListCommand + * @see HandleCharacterDeletedDeleteCommand + * + * @param args the search string which either contains a player GUID or a part of the character-name + */ + static bool HandleCharacterDeletedRestoreCommand(ChatHandler* handler, char const* args) + { + // It is required to submit at least one argument + if (!*args) + return false; + + std::string searchString; + std::string newCharName; + uint32 newAccount = 0; + + // GCC by some strange reason fail build code without temporary variable + std::istringstream params(args); + params >> searchString >> newCharName >> newAccount; + + DeletedInfoList foundList; + if (!GetDeletedCharacterInfoList(foundList, searchString)) + return false; + + if (foundList.empty()) + { + handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_EMPTY); + return false; + } + + handler->SendSysMessage(LANG_CHARACTER_DELETED_RESTORE); + HandleCharacterDeletedListHelper(foundList, handler); + + if (newCharName.empty()) + { + // Drop not existed account cases + for (DeletedInfoList::iterator itr = foundList.begin(); itr != foundList.end(); ++itr) + HandleCharacterDeletedRestoreHelper(*itr, handler); + } + else if (foundList.size() == 1 && normalizePlayerName(newCharName)) + { + DeletedInfo delInfo = foundList.front(); + + // update name + delInfo.name = newCharName; + + // if new account provided update deleted info + if (newAccount && newAccount != delInfo.accountId) + { + delInfo.accountId = newAccount; + AccountMgr::GetName(newAccount, delInfo.accountName); + } + + HandleCharacterDeletedRestoreHelper(delInfo, handler); + } + else + handler->SendSysMessage(LANG_CHARACTER_DELETED_ERR_RENAME); + + return true; + } + + /** + * Handles the '.character deleted delete' command, which completely deletes all deleted characters which matches the given search string + * + * @see Player::GetDeletedCharacterGUIDs + * @see Player::DeleteFromDB + * @see HandleCharacterDeletedListCommand + * @see HandleCharacterDeletedRestoreCommand + * + * @param args the search string which either contains a player GUID or a part fo the character-name + */ + static bool HandleCharacterDeletedDeleteCommand(ChatHandler* handler, char const* args) + { + // It is required to submit at least one argument + if (!*args) + return false; + + DeletedInfoList foundList; + if (!GetDeletedCharacterInfoList(foundList, args)) + return false; + + if (foundList.empty()) + { + handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_EMPTY); + return false; + } + + handler->SendSysMessage(LANG_CHARACTER_DELETED_DELETE); + HandleCharacterDeletedListHelper(foundList, handler); + + // Call the appropriate function to delete them (current account for deleted characters is 0) + for (DeletedInfoList::const_iterator itr = foundList.begin(); itr != foundList.end(); ++itr) + Player::DeleteFromDB(itr->lowGuid, 0, false, true); + + return true; + } + + /** + * Handles the '.character deleted old' command, which completely deletes all deleted characters deleted with some days ago + * + * @see Player::DeleteOldCharacters + * @see Player::DeleteFromDB + * @see HandleCharacterDeletedDeleteCommand + * @see HandleCharacterDeletedListCommand + * @see HandleCharacterDeletedRestoreCommand + * + * @param args the search string which either contains a player GUID or a part fo the character-name + */ + static bool HandleCharacterDeletedOldCommand(ChatHandler* /*handler*/, char const* args) + { + int32 keepDays = sWorld->getIntConfig(CONFIG_CHARDELETE_KEEP_DAYS); + + char* daysStr = strtok((char*)args, " "); + if (daysStr) + { + if (!isNumeric(daysStr)) + return false; + + keepDays = atoi(daysStr); + if (keepDays < 0) + return false; + } + // config option value 0 -> disabled and can't be used + else if (keepDays <= 0) + return false; + + Player::DeleteOldCharacters(uint32(keepDays)); + + return true; + } + + static bool HandleCharacterEraseCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + char* characterName_str = strtok((char*)args, " "); + if (!characterName_str) + return false; + + std::string characterName = characterName_str; + if (!normalizePlayerName(characterName)) + return false; + + uint64 characterGuid; + uint32 accountId; + + Player* player = sObjectAccessor->FindPlayerByName(characterName.c_str()); + if (player) + { + characterGuid = player->GetGUID(); + accountId = player->GetSession()->GetAccountId(); + player->GetSession()->KickPlayer(); + } + else + { + characterGuid = sObjectMgr->GetPlayerGUIDByName(characterName); + if (!characterGuid) + { + handler->PSendSysMessage(LANG_NO_PLAYER, characterName.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + accountId = sObjectMgr->GetPlayerAccountIdByGUID(characterGuid); + } + + std::string accountName; + AccountMgr::GetName(accountId, accountName); + + Player::DeleteFromDB(characterGuid, accountId, true, true); + handler->PSendSysMessage(LANG_CHARACTER_DELETED, characterName.c_str(), GUID_LOPART(characterGuid), accountName.c_str(), accountId); + + return true; + } +}; + +void AddSC_character_commandscript() +{ + new character_commandscript(); +} diff --git a/src/server/scripts/Commands/cs_instance.cpp b/src/server/scripts/Commands/cs_instance.cpp new file mode 100644 index 00000000000..f51727af2ef --- /dev/null +++ b/src/server/scripts/Commands/cs_instance.cpp @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> + * + * 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/>. + */ + +/* ScriptData +Name: instance_commandscript +%Complete: 100 +Comment: All instance related commands +Category: commandscripts +EndScriptData */ + +#include "ScriptMgr.h" +#include "Chat.h" +#include "Group.h" +#include "InstanceSaveMgr.h" +#include "InstanceScript.h" +#include "MapManager.h" + +class instance_commandscript : public CommandScript +{ +public: + instance_commandscript() : CommandScript("instance_commandscript") { } + + ChatCommand* GetCommands() const + { + static ChatCommand instanceCommandTable[] = + { + { "listbinds", SEC_ADMINISTRATOR, false, &HandleInstanceListBindsCommand, "", NULL }, + { "unbind", SEC_ADMINISTRATOR, false, &HandleInstanceUnbindCommand, "", NULL }, + { "stats", SEC_ADMINISTRATOR, true, &HandleInstanceStatsCommand, "", NULL }, + { "savedata", SEC_ADMINISTRATOR, false, &HandleInstanceSaveDataCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + + static ChatCommand commandTable[] = + { + { "instance", SEC_ADMINISTRATOR, true, NULL, "", instanceCommandTable }, + { NULL, 0, false, NULL, "", NULL } + }; + + return commandTable; + } + + static 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(); + } + + static bool HandleInstanceListBindsCommand(ChatHandler* handler, char const* /*args*/) + { + Player* player = handler->getSelectedPlayer(); + if (!player) + player = handler->GetSession()->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)); + handler->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++; + } + } + handler->PSendSysMessage("player binds: %d", counter); + + counter = 0; + if (Group* group = player->GetGroup()) + { + 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)); + handler->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++; + } + } + } + handler->PSendSysMessage("group binds: %d", counter); + + return true; + } + + static bool HandleInstanceUnbindCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + Player* player = handler->getSelectedPlayer(); + if (!player) + player = handler->GetSession()->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)); + handler->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; + } + } + handler->PSendSysMessage("instances unbound: %d", counter); + + return true; + } + + static bool HandleInstanceStatsCommand(ChatHandler* handler, char const* /*args*/) + { + handler->PSendSysMessage("instances loaded: %d", sMapMgr->GetNumInstances()); + handler->PSendSysMessage("players in instances: %d", sMapMgr->GetNumPlayersInInstances()); + handler->PSendSysMessage("instance saves: %d", sInstanceSaveMgr->GetNumInstanceSaves()); + handler->PSendSysMessage("players bound: %d", sInstanceSaveMgr->GetNumBoundPlayersTotal()); + handler->PSendSysMessage("groups bound: %d", sInstanceSaveMgr->GetNumBoundGroupsTotal()); + + return true; + } + + static bool HandleInstanceSaveDataCommand(ChatHandler* handler, char const* /*args*/) + { + Player* player = handler->GetSession()->GetPlayer(); + Map* map = player->GetMap(); + if (!map->IsDungeon()) + { + handler->PSendSysMessage("Map is not a dungeon."); + handler->SetSentErrorMessage(true); + return false; + } + + if (!((InstanceMap*)map)->GetInstanceScript()) + { + handler->PSendSysMessage("Map has no instance data."); + handler->SetSentErrorMessage(true); + return false; + } + + ((InstanceMap*)map)->GetInstanceScript()->SaveToDB(); + + return true; + } +}; + +void AddSC_instance_commandscript() +{ + new instance_commandscript(); +} diff --git a/src/server/scripts/Commands/cs_list.cpp b/src/server/scripts/Commands/cs_list.cpp new file mode 100644 index 00000000000..8dd7f8e2cde --- /dev/null +++ b/src/server/scripts/Commands/cs_list.cpp @@ -0,0 +1,469 @@ +/* + * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> + * + * 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/>. + */ + +/* ScriptData +Name: list_commandscript +%Complete: 100 +Comment: All list related commands +Category: commandscripts +EndScriptData */ + +#include "ScriptMgr.h" +#include "Chat.h" +#include "SpellAuraEffects.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" + +class list_commandscript : public CommandScript +{ +public: + list_commandscript() : CommandScript("list_commandscript") { } + + ChatCommand* GetCommands() const + { + static ChatCommand listCommandTable[] = + { + { "creature", SEC_ADMINISTRATOR, true, &HandleListCreatureCommand, "", NULL }, + { "item", SEC_ADMINISTRATOR, true, &HandleListItemCommand, "", NULL }, + { "object", SEC_ADMINISTRATOR, true, &HandleListObjectCommand, "", NULL }, + { "auras", SEC_ADMINISTRATOR, false, &HandleListAurasCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand commandTable[] = + { + { "list", SEC_ADMINISTRATOR, true, NULL, "", listCommandTable }, + { NULL, 0, false, NULL, "", NULL } + }; + return commandTable; + } + + static bool HandleListCreatureCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r + char* id = handler->extractKeyFromLink((char*)args, "Hcreature_entry"); + if (!id) + return false; + + uint32 creatureId = atol(id); + if (!creatureId) + { + handler->PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, creatureId); + handler->SetSentErrorMessage(true); + return false; + } + + CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creatureId); + if (!cInfo) + { + handler->PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, creatureId); + handler->SetSentErrorMessage(true); + return false; + } + + char* countStr = strtok(NULL, " "); + uint32 count = countStr ? atol(countStr) : 10; + + if (count < 0) + return false; + + QueryResult result; + + uint32 creatureCount = 0; + result = WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'", creatureId); + if (result) + creatureCount = (*result)[0].GetUInt64(); + + if (handler->GetSession()) + { + Player* player = handler->GetSession()->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(), creatureId, count); + } + else + result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM creature WHERE id = '%u' LIMIT %u", + creatureId, 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(); + uint16 mapId = fields[4].GetUInt16(); + + if (handler->GetSession()) + handler->PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name.c_str(), x, y, z, mapId); + else + handler->PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name.c_str(), x, y, z, mapId); + } + while (result->NextRow()); + } + + handler->PSendSysMessage(LANG_COMMAND_LISTCREATUREMESSAGE, creatureId, creatureCount); + + return true; + } + + static bool HandleListItemCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + char* id = handler->extractKeyFromLink((char*)args, "Hitem"); + if (!id) + return false; + + uint32 itemId = atol(id); + if (!itemId) + { + handler->PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId); + handler->SetSentErrorMessage(true); + return false; + } + + ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemId); + if (!itemTemplate) + { + handler->PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId); + handler->SetSentErrorMessage(true); + return false; + } + + char* countStr = strtok(NULL, " "); + uint32 count = countStr ? atol(countStr) : 10; + + if (count < 0) + return false; + + PreparedQueryResult result; + + // inventory case + uint32 inventoryCount = 0; + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_INVENTORY_COUNT_ITEM); + stmt->setUInt32(0, itemId); + result = CharacterDatabase.Query(stmt); + + if (result) + inventoryCount = (*result)[0].GetUInt64(); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_INVENTORY_ITEM_BY_ENTRY); + stmt->setUInt32(0, itemId); + stmt->setUInt32(1, count); + result = CharacterDatabase.Query(stmt); + + if (result) + { + do + { + Field* fields = result->Fetch(); + uint32 itemGuid = fields[0].GetUInt32(); + uint32 itemBag = fields[1].GetUInt32(); + uint8 itemSlot = fields[2].GetUInt8(); + uint32 ownerGuid = fields[3].GetUInt32(); + uint32 ownerAccountId = fields[4].GetUInt32(); + std::string ownerName = fields[5].GetString(); + + char const* itemPos = 0; + if (Player::IsEquipmentPos(itemBag, itemSlot)) + itemPos = "[equipped]"; + else if (Player::IsInventoryPos(itemBag, itemSlot)) + itemPos = "[in inventory]"; + else if (Player::IsBankPos(itemBag, itemSlot)) + itemPos = "[in bank]"; + else + itemPos = ""; + + handler->PSendSysMessage(LANG_ITEMLIST_SLOT, itemGuid, ownerName.c_str(), ownerGuid, ownerAccountId, itemPos); + } + while (result->NextRow()); + + uint32 resultCount = uint32(result->GetRowCount()); + + if (count > resultCount) + count -= resultCount; + else if (count) + count = 0; + } + + // mail case + uint32 mailCount = 0; + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_COUNT_ITEM); + stmt->setUInt32(0, itemId); + result = CharacterDatabase.Query(stmt); + + if (result) + mailCount = (*result)[0].GetUInt64(); + + if (count > 0) + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_ITEMS_BY_ENTRY); + stmt->setUInt32(0, itemId); + stmt->setUInt32(1, count); + result = CharacterDatabase.Query(stmt); + } + else + result = PreparedQueryResult(NULL); + + if (result) + { + do + { + Field* fields = result->Fetch(); + uint32 itemGuid = fields[0].GetUInt32(); + uint32 itemSender = fields[1].GetUInt32(); + uint32 itemReceiver = fields[2].GetUInt32(); + uint32 itemSenderAccountId = fields[3].GetUInt32(); + std::string itemSenderName = fields[4].GetString(); + uint32 itemReceiverAccount = fields[5].GetUInt32(); + std::string itemReceiverName = fields[6].GetString(); + + char const* itemPos = "[in mail]"; + + handler->PSendSysMessage(LANG_ITEMLIST_MAIL, itemGuid, itemSenderName.c_str(), itemSender, itemSenderAccountId, itemReceiverName.c_str(), itemReceiver, itemReceiverAccount, itemPos); + } + while (result->NextRow()); + + uint32 resultCount = uint32(result->GetRowCount()); + + if (count > resultCount) + count -= resultCount; + else if (count) + count = 0; + } + + // auction case + uint32 auctionCount = 0; + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_AUCTIONHOUSE_COUNT_ITEM); + stmt->setUInt32(0, itemId); + result = CharacterDatabase.Query(stmt); + + if (result) + auctionCount = (*result)[0].GetUInt64(); + + if (count > 0) + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_AUCTIONHOUSE_ITEM_BY_ENTRY); + stmt->setUInt32(0, itemId); + stmt->setUInt32(1, count); + result = CharacterDatabase.Query(stmt); + } + else + result = PreparedQueryResult(NULL); + + if (result) + { + do + { + Field* fields = result->Fetch(); + uint32 itemGuid = fields[0].GetUInt32(); + uint32 owner = fields[1].GetUInt32(); + uint32 ownerAccountId = fields[2].GetUInt32(); + std::string ownerName = fields[3].GetString(); + + char const* itemPos = "[in auction]"; + + handler->PSendSysMessage(LANG_ITEMLIST_AUCTION, itemGuid, ownerName.c_str(), owner, ownerAccountId, itemPos); + } + while (result->NextRow()); + } + + // guild bank case + uint32 guildCount = 0; + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_BANK_COUNT_ITEM); + stmt->setUInt32(0, itemId); + result = CharacterDatabase.Query(stmt); + + if (result) + guildCount = (*result)[0].GetUInt64(); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_BANK_ITEM_BY_ENTRY); + stmt->setUInt32(0, itemId); + stmt->setUInt32(1, count); + result = CharacterDatabase.Query(stmt); + + if (result) + { + do + { + Field* fields = result->Fetch(); + uint32 itemGuid = fields[0].GetUInt32(); + uint32 guildGuid = fields[1].GetUInt32(); + std::string guildName = fields[2].GetString(); + + char const* itemPos = "[in guild bank]"; + + handler->PSendSysMessage(LANG_ITEMLIST_GUILD, itemGuid, guildName.c_str(), guildGuid, itemPos); + } + while (result->NextRow()); + + uint32 resultCount = uint32(result->GetRowCount()); + + if (count > resultCount) + count -= resultCount; + else if (count) + count = 0; + } + + if (inventoryCount + mailCount + auctionCount + guildCount == 0) + { + handler->SendSysMessage(LANG_COMMAND_NOITEMFOUND); + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage(LANG_COMMAND_LISTITEMMESSAGE, itemId, inventoryCount + mailCount + auctionCount + guildCount, inventoryCount, mailCount, auctionCount, guildCount); + + return true; + } + + static bool HandleListObjectCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r + char* id = handler->extractKeyFromLink((char*)args, "Hgameobject_entry"); + if (!id) + return false; + + uint32 gameObjectId = atol(id); + if (!gameObjectId) + { + handler->PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, gameObjectId); + handler->SetSentErrorMessage(true); + return false; + } + + GameObjectTemplate const* gInfo = sObjectMgr->GetGameObjectTemplate(gameObjectId); + if (!gInfo) + { + handler->PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, gameObjectId); + handler->SetSentErrorMessage(true); + return false; + } + + char* countStr = strtok(NULL, " "); + uint32 count = countStr ? atol(countStr) : 10; + + if (count < 0) + return false; + + QueryResult result; + + uint32 objectCount = 0; + result = WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'", gameObjectId); + if (result) + objectCount = (*result)[0].GetUInt64(); + + if (handler->GetSession()) + { + Player* player = handler->GetSession()->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(), gameObjectId, count); + } + else + result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, id FROM gameobject WHERE id = '%u' LIMIT %u", + gameObjectId, 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(); + uint16 mapId = fields[4].GetUInt16(); + uint32 entry = fields[5].GetUInt32(); + + if (handler->GetSession()) + handler->PSendSysMessage(LANG_GO_LIST_CHAT, guid, entry, guid, gInfo->name.c_str(), x, y, z, mapId); + else + handler->PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, gInfo->name.c_str(), x, y, z, mapId); + } + while (result->NextRow()); + } + + handler->PSendSysMessage(LANG_COMMAND_LISTOBJMESSAGE, gameObjectId, objectCount); + + return true; + } + + static bool HandleListAurasCommand(ChatHandler* handler, char const* /*args*/) + { + Unit* unit = handler->getSelectedUnit(); + if (!unit) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + char const* talentStr = handler->GetTrinityString(LANG_TALENT); + char const* passiveStr = handler->GetTrinityString(LANG_PASSIVE); + + Unit::AuraApplicationMap const& auras = unit->GetAppliedAuras(); + handler->PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, auras.size()); + for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.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; + + std::ostringstream ss_name; + ss_name << "|cffffffff|Hspell:" << aura->GetId() << "|h[" << name << "]|h|r"; + + handler->PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, aura->GetId(), (handler->GetSession() ? 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& auraList = unit->GetAuraEffectsByType(AuraType(i)); + if (auraList.empty()) + continue; + + handler->PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, auraList.size(), i); + + for (Unit::AuraEffectList::const_iterator itr = auraList.begin(); itr != auraList.end(); ++itr) + handler->PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(), (*itr)->GetAmount()); + } + + return true; + } +}; + +void AddSC_list_commandscript() +{ + new list_commandscript(); +} diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 2deac95d287..4aa61bbc297 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -135,15 +135,14 @@ public: else
handler->PSendSysMessage("no VMAP available for area info");
- /*handler->PSendSysMessage(LANG_MAP_POSITION,
- object->GetMapId(), (mapEntry ? mapEntry->name[handler->GetSessionDbcLocale()] : "<unknown>"),
- zoneId, (zoneEntry ? zoneEntry->area_name[handler->GetSessionDbcLocale()] : "<unknown>"),
- areaId, (areaEntry ? areaEntry->area_name[handler->GetSessionDbcLocale()] : "<unknown>"),
+ handler->PSendSysMessage(LANG_MAP_POSITION,
+ object->GetMapId(), (mapEntry ? mapEntry->name : "<unknown>"),
+ zoneId, (zoneEntry ? zoneEntry->area_name : "<unknown>"),
+ areaId, (areaEntry ? areaEntry->area_name : "<unknown>"),
object->GetPhaseMask(),
object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), object->GetOrientation(),
cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), object->GetInstanceId(),
zoneX, zoneY, groundZ, floorZ, haveMap, haveVMap);
- */
LiquidData liquidStatus;
ZLiquidStatus status = map->getLiquidStatus(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), MAP_ALL_LIQUIDS, &liquidStatus);
diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp index 0de3637586c..57d13fd2fa1 100644 --- a/src/server/scripts/Commands/cs_modify.cpp +++ b/src/server/scripts/Commands/cs_modify.cpp @@ -64,15 +64,14 @@ public: { "standstate", SEC_GAMEMASTER, false, &HandleModifyStandStateCommand, "", NULL }, { "phase", SEC_ADMINISTRATOR, false, &HandleModifyPhaseCommand, "", NULL }, { "gender", SEC_GAMEMASTER, false, &HandleModifyGenderCommand, "", NULL }, - { "collision", SEC_GAMEMASTER, false, &HandleModifyCollisionCommand, "", NULL }, - { "speed", SEC_MODERATOR, false, NULL, "", modifyspeedCommandTable }, + { "speed", SEC_MODERATOR, false, NULL, "", modifyspeedCommandTable }, { NULL, 0, false, NULL, "", NULL } }; static ChatCommand commandTable[] = { { "morph", SEC_GAMEMASTER, false, &HandleModifyMorphCommand, "", NULL }, { "demorph", SEC_GAMEMASTER, false, &HandleDeMorphCommand, "", NULL }, - { "modify", SEC_MODERATOR, false, NULL, "", modifyCommandTable }, + { "modify", SEC_MODERATOR, false, NULL, "", modifyCommandTable }, { NULL, 0, false, NULL, "", NULL } }; return commandTable; @@ -1391,7 +1390,7 @@ public: if (!target) target = handler->GetSession()->GetPlayer(); - // check online security + // check online security else if (target->GetTypeId() == TYPEID_PLAYER && handler->HasLowerSecurity(target->ToPlayer(), 0)) return false; @@ -1399,88 +1398,6 @@ public: return true; } - - static bool HandleModifyCollisionCommand(ChatHandler* handler, const char* args) - { - if (!*args) - return false; - - Player* target = handler->getSelectedPlayer(); - - if (!target) - { - handler->PSendSysMessage(LANG_PLAYER_NOT_FOUND); - handler->SetSentErrorMessage(true); - return false; - } - - std::string param = (char*)args; - - if (param == "on") - { - // enable collision - WorldPacket data; - uint64 guid = target->GetGUID(); - uint8* bytes = (uint8*)&guid; - - data.Initialize(SMSG_MOVE_SPLINE_ENABLE_COLLISION, 1 + 8); - data.WriteByteMask(bytes[7]); - data.WriteByteMask(bytes[5]); - data.WriteByteMask(bytes[4]); - data.WriteByteMask(bytes[0]); - data.WriteByteMask(bytes[1]); - data.WriteByteMask(bytes[6]); - data.WriteByteMask(bytes[2]); - data.WriteByteMask(bytes[3]); - - data.WriteByteSeq(bytes[6]); - data.WriteByteSeq(bytes[3]); - data.WriteByteSeq(bytes[2]); - data.WriteByteSeq(bytes[7]); - data.WriteByteSeq(bytes[4]); - data.WriteByteSeq(bytes[1]); - data.WriteByteSeq(bytes[5]); - data.WriteByteSeq(bytes[0]); - - target->SendMessageToSet(&data, true); - handler->SendSysMessage("Enabled Collision"); - return true; - } - - if (param == "off") - { - // disable collision - WorldPacket data; - uint64 guid = target->GetGUID(); - uint8* bytes = (uint8*)&guid; - - data.Initialize(SMSG_MOVE_SPLINE_DISABLE_COLLISION, 1 + 8); - data.WriteByteMask(bytes[4]); - data.WriteByteMask(bytes[7]); - data.WriteByteMask(bytes[5]); - data.WriteByteMask(bytes[3]); - data.WriteByteMask(bytes[2]); - data.WriteByteMask(bytes[1]); - data.WriteByteMask(bytes[6]); - data.WriteByteMask(bytes[0]); - - data.WriteByteSeq(bytes[6]); - data.WriteByteSeq(bytes[0]); - data.WriteByteSeq(bytes[5]); - data.WriteByteSeq(bytes[4]); - data.WriteByteSeq(bytes[7]); - data.WriteByteSeq(bytes[3]); - data.WriteByteSeq(bytes[1]); - data.WriteByteSeq(bytes[2]); - - target->SendMessageToSet(&data, true); - handler->SendSysMessage("Disabled Collision"); - return true; - } - - return false; - } - }; void AddSC_modify_commandscript() diff --git a/src/server/scripts/Commands/cs_reset.cpp b/src/server/scripts/Commands/cs_reset.cpp new file mode 100644 index 00000000000..a8294dc9ddb --- /dev/null +++ b/src/server/scripts/Commands/cs_reset.cpp @@ -0,0 +1,310 @@ +/* + * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> + * + * 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/>. + */ + +/* ScriptData +Name: reset_commandscript +%Complete: 100 +Comment: All reset related commands +Category: commandscripts +EndScriptData */ + +#include "ScriptMgr.h" +#include "Chat.h" +#include "ObjectAccessor.h" + +class reset_commandscript : public CommandScript +{ +public: + reset_commandscript() : CommandScript("reset_commandscript") { } + + ChatCommand* GetCommands() const + { + static ChatCommand resetCommandTable[] = + { + { "achievements", SEC_ADMINISTRATOR, true, &HandleResetAchievementsCommand, "", NULL }, + { "honor", SEC_ADMINISTRATOR, true, &HandleResetHonorCommand, "", NULL }, + { "level", SEC_ADMINISTRATOR, true, &HandleResetLevelCommand, "", NULL }, + { "spells", SEC_ADMINISTRATOR, true, &HandleResetSpellsCommand, "", NULL }, + { "stats", SEC_ADMINISTRATOR, true, &HandleResetStatsCommand, "", NULL }, + { "talents", SEC_ADMINISTRATOR, true, &HandleResetTalentsCommand, "", NULL }, + { "all", SEC_ADMINISTRATOR, true, &HandleResetAllCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand commandTable[] = + { + { "reset", SEC_ADMINISTRATOR, true, NULL, "", resetCommandTable }, + { NULL, 0, false, NULL, "", NULL } + }; + return commandTable; + } + + static bool HandleResetAchievementsCommand(ChatHandler* handler, char const* args) + { + Player* target; + uint64 targetGuid; + if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid)) + return false; + + if (target) + target->GetAchievementMgr().Reset(); + else + AchievementMgr::DeleteFromDB(GUID_LOPART(targetGuid)); + + return true; + } + + static bool HandleResetHonorCommand(ChatHandler* handler, char const* args) + { + Player* target; + if (!handler->extractPlayerTarget((char*)args, &target)) + return false; + + target->SetUInt32Value(PLAYER_FIELD_KILLS, 0); + target->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, 0); + target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL); + + return true; + } + + static bool HandleResetStatsOrLevelHelper(Player* player) + { + ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(player->getClass()); + if (!classEntry) + { + sLog->outError("Class %u not found in DBC (Wrong DBC files?)", player->getClass()); + return false; + } + + uint8 powerType = classEntry->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; + } + + static bool HandleResetLevelCommand(ChatHandler* handler, char const* args) + { + Player* target; + if (!handler->extractPlayerTarget((char*)args, &target)) + return false; + + if (!HandleResetStatsOrLevelHelper(target)) + return false; + + uint8 oldLevel = target->getLevel(); + + // set starting level + uint32 startLevel = target->getClass() != CLASS_DEATH_KNIGHT + ? sWorld->getIntConfig(CONFIG_START_PLAYER_LEVEL) + : sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL); + + target->_ApplyAllLevelScaleItemMods(false); + target->SetLevel(startLevel); + 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; + } + + static bool HandleResetSpellsCommand(ChatHandler* handler, char const* args) + { + Player* target; + uint64 targetGuid; + std::string targetName; + if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) + return false; + + if (target) + { + target->resetSpells(/* bool myClassOnly */); + + ChatHandler(target).SendSysMessage(LANG_RESET_SPELLS); + if (!handler->GetSession() || handler->GetSession()->GetPlayer() != target) + handler->PSendSysMessage(LANG_RESET_SPELLS_ONLINE, handler->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); + + handler->PSendSysMessage(LANG_RESET_SPELLS_OFFLINE, targetName.c_str()); + } + + return true; + } + + static bool HandleResetStatsCommand(ChatHandler* handler, char const* args) + { + Player* target; + if (!handler->extractPlayerTarget((char*)args, &target)) + return false; + + if (!HandleResetStatsOrLevelHelper(target)) + return false; + + target->InitRunes(); + target->InitStatsForLevel(true); + target->InitTaxiNodesForLevel(); + target->InitGlyphsForLevel(); + target->InitTalentForLevel(); + + return true; + } + + static bool HandleResetTalentsCommand(ChatHandler* handler, char const* args) + { + Player* target; + uint64 targetGuid; + std::string targetName; + if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) + { + // Try reset talents as Hunter Pet + Creature* creature = handler->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 (!handler->GetSession() || handler->GetSession()->GetPlayer() != owner->ToPlayer()) + handler->PSendSysMessage(LANG_RESET_PET_TALENTS_ONLINE, handler->GetNameLink(owner->ToPlayer()).c_str()); + } + return true; + } + + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + if (target) + { + target->ResetTalents(true); + target->SendTalentsInfoData(false); + ChatHandler(target).SendSysMessage(LANG_RESET_TALENTS); + if (!handler->GetSession() || handler->GetSession()->GetPlayer() != target) + handler->PSendSysMessage(LANG_RESET_TALENTS_ONLINE, handler->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 = handler->playerLink(targetName); + handler->PSendSysMessage(LANG_RESET_TALENTS_OFFLINE, nameLink.c_str()); + return true; + } + + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + static bool HandleResetAllCommand(ChatHandler* handler, char const* 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 (!handler->GetSession()) + handler->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 (!handler->GetSession()) + handler->SendSysMessage(LANG_RESETALL_TALENTS); + } + else + { + handler->PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE, args); + handler->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; + } +}; + +void AddSC_reset_commandscript() +{ + new reset_commandscript(); +} diff --git a/src/server/scripts/Commands/cs_server.cpp b/src/server/scripts/Commands/cs_server.cpp new file mode 100644 index 00000000000..8f10af5fe2a --- /dev/null +++ b/src/server/scripts/Commands/cs_server.cpp @@ -0,0 +1,445 @@ +/* + * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> + * + * 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/>. + */ + +/* ScriptData +Name: server_commandscript +%Complete: 100 +Comment: All server related commands +Category: commandscripts +EndScriptData */ + +#include "ScriptMgr.h" +#include "Chat.h" +#include "SystemConfig.h" +#include "Config.h" +#include "ObjectAccessor.h" + +class server_commandscript : public CommandScript +{ +public: + server_commandscript() : CommandScript("server_commandscript") { } + + ChatCommand* GetCommands() const + { + static ChatCommand serverIdleRestartCommandTable[] = + { + { "cancel", SEC_ADMINISTRATOR, true, &HandleServerShutDownCancelCommand, "", NULL }, + { "" , SEC_ADMINISTRATOR, true, &HandleServerIdleRestartCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + + static ChatCommand serverIdleShutdownCommandTable[] = + { + { "cancel", SEC_ADMINISTRATOR, true, &HandleServerShutDownCancelCommand, "", NULL }, + { "" , SEC_ADMINISTRATOR, true, &HandleServerIdleShutDownCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + + static ChatCommand serverRestartCommandTable[] = + { + { "cancel", SEC_ADMINISTRATOR, true, &HandleServerShutDownCancelCommand, "", NULL }, + { "" , SEC_ADMINISTRATOR, true, &HandleServerRestartCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + + static ChatCommand serverShutdownCommandTable[] = + { + { "cancel", SEC_ADMINISTRATOR, true, &HandleServerShutDownCancelCommand, "", NULL }, + { "" , SEC_ADMINISTRATOR, true, &HandleServerShutDownCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + + static ChatCommand serverSetCommandTable[] = + { + { "difftime", SEC_CONSOLE, true, &HandleServerSetDiffTimeCommand, "", NULL }, + { "loglevel", SEC_CONSOLE, true, &HandleServerSetLogLevelCommand, "", NULL }, + { "logfilelevel", SEC_CONSOLE, true, &HandleServerSetLogFileLevelCommand, "", NULL }, + { "motd", SEC_ADMINISTRATOR, true, &HandleServerSetMotdCommand, "", NULL }, + { "closed", SEC_ADMINISTRATOR, true, &HandleServerSetClosedCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + + static ChatCommand serverCommandTable[] = + { + { "corpses", SEC_GAMEMASTER, true, &HandleServerCorpsesCommand, "", NULL }, + { "exit", SEC_CONSOLE, true, &HandleServerExitCommand, "", NULL }, + { "idlerestart", SEC_ADMINISTRATOR, true, NULL, "", serverIdleRestartCommandTable }, + { "idleshutdown", SEC_ADMINISTRATOR, true, NULL, "", serverIdleShutdownCommandTable }, + { "info", SEC_PLAYER, true, &HandleServerInfoCommand, "", NULL }, + { "motd", SEC_PLAYER, true, &HandleServerMotdCommand, "", NULL }, + { "plimit", SEC_ADMINISTRATOR, true, &HandleServerPLimitCommand, "", NULL }, + { "restart", SEC_ADMINISTRATOR, true, NULL, "", serverRestartCommandTable }, + { "shutdown", SEC_ADMINISTRATOR, true, NULL, "", serverShutdownCommandTable }, + { "set", SEC_ADMINISTRATOR, true, NULL, "", serverSetCommandTable }, + { "togglequerylog", SEC_CONSOLE, true, &HandleServerToggleQueryLogging, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + + static ChatCommand commandTable[] = + { + { "server", SEC_ADMINISTRATOR, true, NULL, "", serverCommandTable }, + { NULL, 0, false, NULL, "", NULL } + }; + return commandTable; + } + + // Triggering corpses expire check in world + static bool HandleServerCorpsesCommand(ChatHandler* /*handler*/, char const* /*args*/) + { + sObjectAccessor->RemoveOldCorpses(); + return true; + } + + static bool HandleServerInfoCommand(ChatHandler* handler, char const* /*args*/) + { + uint32 playersNum = sWorld->GetPlayerCount(); + uint32 maxPlayersNum = sWorld->GetMaxPlayerCount(); + uint32 activeClientsNum = sWorld->GetActiveSessionCount(); + uint32 queuedClientsNum = sWorld->GetQueuedSessionCount(); + uint32 maxActiveClientsNum = sWorld->GetMaxActiveSessionCount(); + uint32 maxQueuedClientsNum = sWorld->GetMaxQueuedSessionCount(); + std::string uptime = secsToTimeString(sWorld->GetUptime()); + uint32 updateTime = sWorld->GetUpdateTime(); + + handler->SendSysMessage(_FULLVERSION); + handler->PSendSysMessage(LANG_CONNECTED_PLAYERS, playersNum, maxPlayersNum); + handler->PSendSysMessage(LANG_CONNECTED_USERS, activeClientsNum, maxActiveClientsNum, queuedClientsNum, maxQueuedClientsNum); + handler->PSendSysMessage(LANG_UPTIME, uptime.c_str()); + handler->PSendSysMessage(LANG_UPDATE_DIFF, updateTime); + // Can't use sWorld->ShutdownMsg here in case of console command + if (sWorld->IsShuttingDown()) + handler->PSendSysMessage(LANG_SHUTDOWN_TIMELEFT, secsToTimeString(sWorld->GetShutDownTimeLeft()).c_str()); + + return true; + } + // Display the 'Message of the day' for the realm + static bool HandleServerMotdCommand(ChatHandler* handler, char const* /*args*/) + { + handler->PSendSysMessage(LANG_MOTD_CURRENT, sWorld->GetMotd()); + return true; + } + + static bool HandleServerPLimitCommand(ChatHandler* handler, char const* args) + { + if (*args) + { + char* paramStr = strtok((char*)args, " "); + if (!paramStr) + return false; + + int32 limit = strlen(paramStr); + + if (strncmp(paramStr, "player", limit) == 0) + sWorld->SetPlayerSecurityLimit(SEC_PLAYER); + else if (strncmp(paramStr, "moderator", limit) == 0) + sWorld->SetPlayerSecurityLimit(SEC_MODERATOR); + else if (strncmp(paramStr, "gamemaster", limit) == 0) + sWorld->SetPlayerSecurityLimit(SEC_GAMEMASTER); + else if (strncmp(paramStr, "administrator", limit) == 0) + sWorld->SetPlayerSecurityLimit(SEC_ADMINISTRATOR); + else if (strncmp(paramStr, "reset", limit) == 0) + { + sWorld->SetPlayerAmountLimit(ConfigMgr::GetIntDefault("PlayerLimit", 100)); + sWorld->LoadDBAllowedSecurityLevel(); + } + else + { + int32 value = atoi(paramStr); + if (value < 0) + sWorld->SetPlayerSecurityLimit(AccountTypes(-value)); + else + sWorld->SetPlayerAmountLimit(uint32(value)); + } + } + + uint32 playerAmountLimit = 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; + } + handler->PSendSysMessage("Player limits: amount %u, min. security level %s.", playerAmountLimit, secName); + + return true; + } + + static bool HandleServerShutDownCancelCommand(ChatHandler* /*handler*/, char const* /*args*/) + { + sWorld->ShutdownCancel(); + + return true; + } + + static bool HandleServerShutDownCommand(ChatHandler* /*handler*/, char const* args) + { + if (!*args) + return false; + + char* timeStr = strtok((char*) args, " "); + char* exitCodeStr = strtok(NULL, ""); + + int32 time = atoi(timeStr); + + // Prevent interpret wrong arg value as 0 secs shutdown time + if ((time == 0 && (timeStr[0] != '0' || timeStr[1] != '\0')) || time < 0) + return false; + + if (exitCodeStr) + { + int32 exitCode = atoi(exitCodeStr); + + // Handle atoi() errors + if (exitCode == 0 && (exitCodeStr[0] != '0' || exitCodeStr[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; + } + + static bool HandleServerRestartCommand(ChatHandler* /*handler*/, char const* args) + { + if (!*args) + return false; + + char* timeStr = strtok((char*) args, " "); + char* exitCodeStr = strtok(NULL, ""); + + int32 time = atoi(timeStr); + + // Prevent interpret wrong arg value as 0 secs shutdown time + if ((time == 0 && (timeStr[0] != '0' || timeStr[1] != '\0')) || time < 0) + return false; + + if (exitCodeStr) + { + int32 exitCode = atoi(exitCodeStr); + + // Handle atoi() errors + if (exitCode == 0 && (exitCodeStr[0] != '0' || exitCodeStr[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; + } + + static bool HandleServerIdleRestartCommand(ChatHandler* /*handler*/, char const* args) + { + if (!*args) + return false; + + char* timeStr = strtok((char*) args, " "); + char* exitCodeStr = strtok(NULL, ""); + + int32 time = atoi(timeStr); + + // Prevent interpret wrong arg value as 0 secs shutdown time + if ((time == 0 && (timeStr[0] != '0' || timeStr[1] != '\0')) || time < 0) + return false; + + if (exitCodeStr) + { + int32 exitCode = atoi(exitCodeStr); + + // Handle atoi() errors + if (exitCode == 0 && (exitCodeStr[0] != '0' || exitCodeStr[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; + } + + static bool HandleServerIdleShutDownCommand(ChatHandler* /*handler*/, char const* args) + { + if (!*args) + return false; + + char* timeStr = strtok((char*) args, " "); + char* exitCodeStr = strtok(NULL, ""); + + int32 time = atoi(timeStr); + + // Prevent interpret wrong arg value as 0 secs shutdown time + if ((time == 0 && (timeStr[0] != '0' || timeStr[1] != '\0')) || time < 0) + return false; + + if (exitCodeStr) + { + int32 exitCode = atoi(exitCodeStr); + + // Handle atoi() errors + if (exitCode == 0 && (exitCodeStr[0] != '0' || exitCodeStr[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; + } + + // Exit the realm + static bool HandleServerExitCommand(ChatHandler* handler, char const* /*args*/) + { + handler->SendSysMessage(LANG_COMMAND_EXIT); + World::StopNow(SHUTDOWN_EXIT_CODE); + return true; + } + + // Define the 'Message of the day' for the realm + static bool HandleServerSetMotdCommand(ChatHandler* handler, char const* args) + { + sWorld->SetMotd(args); + handler->PSendSysMessage(LANG_MOTD_NEW, args); + return true; + } + + // Set whether we accept new clients + static bool HandleServerSetClosedCommand(ChatHandler* handler, char const* args) + { + if (strncmp(args, "on", 3) == 0) + { + handler->SendSysMessage(LANG_WORLD_CLOSED); + sWorld->SetClosed(true); + return true; + } + else if (strncmp(args, "off", 4) == 0) + { + handler->SendSysMessage(LANG_WORLD_OPENED); + sWorld->SetClosed(false); + return true; + } + + handler->SendSysMessage(LANG_USE_BOL); + handler->SetSentErrorMessage(true); + return false; + } + + // Set the level of logging + static bool HandleServerSetLogFileLevelCommand(ChatHandler* /*handler*/, char const* args) + { + if (!*args) + return false; + + char* newLevel = strtok((char*)args, " "); + if (!newLevel) + return false; + + sLog->SetLogFileLevel(newLevel); + return true; + } + + // Set the level of logging + static bool HandleServerSetLogLevelCommand(ChatHandler* /*handler*/, char const* args) + { + if (!*args) + return false; + + char* newLevel = strtok((char*)args, " "); + if (!newLevel) + return false; + + sLog->SetLogLevel(newLevel); + return true; + } + + // set diff time record interval + static bool HandleServerSetDiffTimeCommand(ChatHandler* /*handler*/, char const* args) + { + if (!*args) + return false; + + char* newTimeStr = strtok((char*)args, " "); + if (!newTimeStr) + return false; + + int32 newTime = atoi(newTimeStr); + if (newTime < 0) + return false; + + sWorld->SetRecordDiffInterval(newTime); + printf("Record diff every %u ms\n", newTime); + + return true; + } + + // toggle sql driver query logging + static bool HandleServerToggleQueryLogging(ChatHandler* handler, char const* /*args*/) + { + sLog->SetSQLDriverQueryLogging(!sLog->GetSQLDriverQueryLogging()); + + if (sLog->GetSQLDriverQueryLogging()) + handler->PSendSysMessage(LANG_SQLDRIVER_QUERY_LOGGING_ENABLED); + else + handler->PSendSysMessage(LANG_SQLDRIVER_QUERY_LOGGING_DISABLED); + return true; + } +}; + +void AddSC_server_commandscript() +{ + new server_commandscript(); +} diff --git a/src/server/scripts/Commands/cs_tele.cpp b/src/server/scripts/Commands/cs_tele.cpp index ca7c3af7fde..8f390d17cd4 100644 --- a/src/server/scripts/Commands/cs_tele.cpp +++ b/src/server/scripts/Commands/cs_tele.cpp @@ -97,15 +97,16 @@ public: if (!*args) return false; - std::string name = args; - - if (!sObjectMgr->DeleteGameTele(name)) + // id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r + GameTele const* tele = handler->extractGameTeleFromLink((char*)args); + if (!tele) { handler->SendSysMessage(LANG_COMMAND_TELE_NOTFOUND); handler->SetSentErrorMessage(true); return false; } - + std::string name = tele->name; + sObjectMgr->DeleteGameTele(name); handler->SendSysMessage(LANG_COMMAND_TP_DELETED); return true; } |
