From 55ce180f2867700b28921d99f9a0cb9c83330c91 Mon Sep 17 00:00:00 2001 From: Spp Date: Fri, 3 Aug 2012 14:20:18 +0200 Subject: Core/Logging: Add Asyncronous logging with Loggers ("What to log") and Appenders ("Where to log") system. Will allow to select to full log some parts of core while others are not even logged. - Logging System is asyncronous to improve performance. - Each msg and Logger has a Log Type and Log Level assigned. Each msg is assigned the Logger of same Log Type or "root" Logger is selected if there is no Logger configured for the given Log Type - Loggers have a list of Appenders to send the msg to. The Msg in the Logger is not sent to Appenders if the msg LogLevel is lower than Logger LogLevel. - There are three (at the moment) types of Appenders: Console, File or DB (this is WIP, not working ATM). Msg is not written to the resource if msg LogLevel is lower than Appender LogLevel. - Appender and Console Log levels can be changed while server is active with command '.set loglevel (a/l) name level' Explanation of use with Sample config: Appender.Console.Type=1 (1 = Console) Appender.Console.Level=2 (2 = Debug) Appender.Server.Type=2 (2 = File) Appender.Server.Level=3 (3 = Info) Appender.Server.File=Server.log Appender.SQL.Type=2 (2 = File) Appender.SQL.Level=1 (1 = Trace) Appender.SQL.File=sql.log Appenders=Console Server (NOTE: SQL has not been included here... that will make core ignore the config for "SQL" as it's not in this list) Logger.root.Type=0 (0 = Default - if it's not created by config, server will create it with LogLevel = DISABLED) Logger.root.Level=5 (5 = Error) Logger.root.Appenders=Console Logger.SQL.Type=26 (26 = SQL) Logger.SQL.Level=3 (2 = Debug) Logger.SQL.Appenders=Console Server SQL Logger.SomeRandomName.Type=24 (24 = Guild) Logger.SomeRandomName.Level=5 (5 = Error) Loggers=root SQL SomeRandomName * At loading Appender SQL will be ignored, as it's not present on "Appenders" * sLog->outDebug(LOG_FILTER_GUILD, "Some log msg related to Guilds") - Msg is sent to Logger of Type LOG_FILTER_GUILD (24). Logger with name SomeRandomName is found but it's LogLevel = 5 and Msg LogLevel=2... Msg is not logged * sLog->outError(LOG_FILTER_GUILD, "Some error log msg related to Guilds") - Msg is sent to Logger of Type LOG_FILTER_GUILD (24). Logger with name SomeRandomeName is found with proper LogLevel but Logger does not have any Appenders assigned to that logger... Msg is not logged * sLog->outDebug(LOG_FILTER_SQL, "Some msg related to SQLs") - Msg is sent to Logger SQL (matches type), as it matches LogLevel the msg is sent to Appenders Console, Server and SQL - Appender Console has lower Log Level: Msg is logged to Console - Appender Server has higher Log Level: Msg is not logged to file - Appender SQL has lower Log Level: Msg is logged to file sql.log * sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Some msg related to Battelgrounds") - Msg is sent to Logger root (Type 0) as no Logger was found with Type LOG_FILTER_BATTLEGROUND (13). As Logger has higher LogLevel msg is not sent to any appender * sLog->outError(LOG_FILTER_BATTLEGROUND, "Some error msg related to Battelgrounds") - Msg is sent to Logger root (Type 0) as no Logger was found with Type LOG_FILTER_BATTLEGROUND (13). Msg has lower LogLevel and is sent to Appender Console - Appender Console has lower LogLevel: Msg is logged to Console --- src/server/shared/Logging/AppenderDB.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/server/shared/Logging/AppenderDB.cpp (limited to 'src/server/shared/Logging/AppenderDB.cpp') diff --git a/src/server/shared/Logging/AppenderDB.cpp b/src/server/shared/Logging/AppenderDB.cpp new file mode 100644 index 00000000000..6f3737adf4d --- /dev/null +++ b/src/server/shared/Logging/AppenderDB.cpp @@ -0,0 +1,30 @@ +#include "AppenderDB.h" + +/* FIXME +#include "DatabaseWorkerPool.h" +#include "Implementation/LoginDatabase.h" // For logging +extern DatabaseWorkerPool LoginDatabase; +*/ + +AppenderDB::AppenderDB(uint8 id, std::string const& name, LogLevel level, uint8 realmId): +Appender(id, name, APPENDER_DB, level), realm(realmId), enable(false) +{ +} + +AppenderDB::~AppenderDB() +{ +} + +void AppenderDB::_write(LogMessage& /*message*/) +{ +/* FIXME + if (enable) + LoginDatabase.PExecute("INSERT INTO logs (time, realm, type, severity, string) " + "VALUES (" UI64FMTD ", %u, %u, '%s');", message.mtime, realm, message.type, message.level, message.text.c_str()); +*/ +} + +void AppenderDB::setEnable(bool _enable) +{ + enable = _enable; +} -- cgit v1.2.3 From 10891028279762eb14688ec07bc22dffe3b26886 Mon Sep 17 00:00:00 2001 From: Spp Date: Fri, 3 Aug 2012 17:29:43 +0200 Subject: Add missing Copyright headers and some clarification to config files... ¬¬ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/server/authserver/authserver.conf.dist | 161 ++++++------ src/server/shared/Logging/Appender.cpp | 17 ++ src/server/shared/Logging/Appender.h | 17 ++ src/server/shared/Logging/AppenderConsole.cpp | 17 ++ src/server/shared/Logging/AppenderConsole.h | 17 ++ src/server/shared/Logging/AppenderDB.cpp | 17 ++ src/server/shared/Logging/AppenderDB.h | 17 ++ src/server/shared/Logging/AppenderFile.cpp | 17 ++ src/server/shared/Logging/AppenderFile.h | 17 ++ src/server/shared/Logging/LogOperation.cpp | 17 ++ src/server/shared/Logging/LogOperation.h | 17 ++ src/server/shared/Logging/LogWorker.cpp | 17 ++ src/server/shared/Logging/LogWorker.h | 17 ++ src/server/shared/Logging/Logger.cpp | 17 ++ src/server/shared/Logging/Logger.h | 17 ++ src/server/worldserver/worldserver.conf.dist | 347 +++++++++++++------------- 16 files changed, 497 insertions(+), 249 deletions(-) (limited to 'src/server/shared/Logging/AppenderDB.cpp') diff --git a/src/server/authserver/authserver.conf.dist b/src/server/authserver/authserver.conf.dist index 875d952b14c..93bbc9e3872 100644 --- a/src/server/authserver/authserver.conf.dist +++ b/src/server/authserver/authserver.conf.dist @@ -68,6 +68,89 @@ BindIP = "0.0.0.0" PidFile = "" +# +# UseProcessors +# Description: Processors mask for Windows based multi-processor systems. +# Default: 0 - (Selected by OS) +# 1+ - (Bit mask value of selected processors) + +UseProcessors = 0 + +# +# ProcessPriority +# Description: Process priority setting for Windows based systems. +# Default: 1 - (High) +# 0 - (Normal) + +ProcessPriority = 1 + +# +# RealmsStateUpdateDelay +# Description: Time (in seconds) between realm list updates. +# Default: 20 - (Enabled) +# 0 - (Disabled) + +RealmsStateUpdateDelay = 20 + +# +# WrongPass.MaxCount +# Description: Number of login attemps with wrong password before the account or IP will be +# banned. +# Default: 0 - (Disabled) +# 1+ - (Enabled) + +WrongPass.MaxCount = 0 + +# +# WrongPass.BanTime +# Description: Time (in seconds) for banning account or IP for invalid login attempts. +# Default: 600 - (10 minutes) +# 0 - (Permanent ban) + +WrongPass.BanTime = 600 + +# +# WrongPass.BanType +# Description: Ban type for invalid login attempts. +# Default: 0 - (Ban IP) +# 1 - (Ban Account) + +WrongPass.BanType = 0 + +# +################################################################################################### + +################################################################################################### +# MYSQL SETTINGS +# +# LoginDatabaseInfo +# Description: Database connection settings for the realm server. +# Example: "hostname;port;username;password;database" +# ".;somenumber;username;password;database" - (Use named pipes on Windows +# "enable-named-pipe" to [mysqld] +# section my.ini) +# ".;/path/to/unix_socket;username;password;database" - (use Unix sockets on +# Unix/Linux) +# Default: "127.0.0.1;3306;trinity;trinity;auth" + +LoginDatabaseInfo = "127.0.0.1;3306;trinity;trinity;auth" + +# +# LoginDatabase.WorkerThreads +# Description: The amount of worker threads spawned to handle asynchronous (delayed) MySQL +# statements. Each worker thread is mirrored with its own connection to the +# Default: 1 + +LoginDatabase.WorkerThreads = 1 + +# +################################################################################################### + +################################################################################################### +# +# Logging system options. +# Note: As it uses dynamic option naming, all options related to one appender or logger are grouped. +# # # Appender config values: Given a appender "name" the following options # can be read: @@ -187,81 +270,3 @@ Appender.Auth.Mode=w Logger.root.Type=0 Logger.root.Level=3 Logger.root.Appenders=Console Auth - -# -# UseProcessors -# Description: Processors mask for Windows based multi-processor systems. -# Default: 0 - (Selected by OS) -# 1+ - (Bit mask value of selected processors) - -UseProcessors = 0 - -# -# ProcessPriority -# Description: Process priority setting for Windows based systems. -# Default: 1 - (High) -# 0 - (Normal) - -ProcessPriority = 1 - -# -# RealmsStateUpdateDelay -# Description: Time (in seconds) between realm list updates. -# Default: 20 - (Enabled) -# 0 - (Disabled) - -RealmsStateUpdateDelay = 20 - -# -# WrongPass.MaxCount -# Description: Number of login attemps with wrong password before the account or IP will be -# banned. -# Default: 0 - (Disabled) -# 1+ - (Enabled) - -WrongPass.MaxCount = 0 - -# -# WrongPass.BanTime -# Description: Time (in seconds) for banning account or IP for invalid login attempts. -# Default: 600 - (10 minutes) -# 0 - (Permanent ban) - -WrongPass.BanTime = 600 - -# -# WrongPass.BanType -# Description: Ban type for invalid login attempts. -# Default: 0 - (Ban IP) -# 1 - (Ban Account) - -WrongPass.BanType = 0 - -# -################################################################################################### - -################################################################################################### -# MYSQL SETTINGS -# -# LoginDatabaseInfo -# Description: Database connection settings for the realm server. -# Example: "hostname;port;username;password;database" -# ".;somenumber;username;password;database" - (Use named pipes on Windows -# "enable-named-pipe" to [mysqld] -# section my.ini) -# ".;/path/to/unix_socket;username;password;database" - (use Unix sockets on -# Unix/Linux) -# Default: "127.0.0.1;3306;trinity;trinity;auth" - -LoginDatabaseInfo = "127.0.0.1;3306;trinity;trinity;auth" - -# -# LoginDatabase.WorkerThreads -# Description: The amount of worker threads spawned to handle asynchronous (delayed) MySQL -# statements. Each worker thread is mirrored with its own connection to the -# Default: 1 - -LoginDatabase.WorkerThreads = 1 - -# -################################################################################################### diff --git a/src/server/shared/Logging/Appender.cpp b/src/server/shared/Logging/Appender.cpp index 38d58f1ffb5..0b92e74c1e9 100644 --- a/src/server/shared/Logging/Appender.cpp +++ b/src/server/shared/Logging/Appender.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2008-2012 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + #include "Appender.h" #include "Common.h" diff --git a/src/server/shared/Logging/Appender.h b/src/server/shared/Logging/Appender.h index c32f51e5a88..3105f0e6bb4 100644 --- a/src/server/shared/Logging/Appender.h +++ b/src/server/shared/Logging/Appender.h @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2008-2012 TrinityCore + * + * 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 . + */ + #ifndef APPENDER_H #define APPENDER_H diff --git a/src/server/shared/Logging/AppenderConsole.cpp b/src/server/shared/Logging/AppenderConsole.cpp index ad81a883bfa..30c7cc4d135 100644 --- a/src/server/shared/Logging/AppenderConsole.cpp +++ b/src/server/shared/Logging/AppenderConsole.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2008-2012 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + #include "AppenderConsole.h" #include "Config.h" #include "Util.h" diff --git a/src/server/shared/Logging/AppenderConsole.h b/src/server/shared/Logging/AppenderConsole.h index a9f46cf9c4a..b81fe6dde57 100644 --- a/src/server/shared/Logging/AppenderConsole.h +++ b/src/server/shared/Logging/AppenderConsole.h @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2008-2012 TrinityCore + * + * 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 . + */ + #ifndef APPENDERCONSOLE_H #define APPENDERCONSOLE_H diff --git a/src/server/shared/Logging/AppenderDB.cpp b/src/server/shared/Logging/AppenderDB.cpp index 6f3737adf4d..63af9176193 100644 --- a/src/server/shared/Logging/AppenderDB.cpp +++ b/src/server/shared/Logging/AppenderDB.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2008-2012 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + #include "AppenderDB.h" /* FIXME diff --git a/src/server/shared/Logging/AppenderDB.h b/src/server/shared/Logging/AppenderDB.h index ca15fc1a1d5..4399195b181 100644 --- a/src/server/shared/Logging/AppenderDB.h +++ b/src/server/shared/Logging/AppenderDB.h @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2008-2012 TrinityCore + * + * 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 . + */ + #ifndef APPENDERDB_H #define APPENDERDB_H diff --git a/src/server/shared/Logging/AppenderFile.cpp b/src/server/shared/Logging/AppenderFile.cpp index 30c1f271c96..93c02913aeb 100644 --- a/src/server/shared/Logging/AppenderFile.cpp +++ b/src/server/shared/Logging/AppenderFile.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2008-2012 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + #include "AppenderFile.h" #include "Common.h" diff --git a/src/server/shared/Logging/AppenderFile.h b/src/server/shared/Logging/AppenderFile.h index a01ea947334..bbc500f9e76 100644 --- a/src/server/shared/Logging/AppenderFile.h +++ b/src/server/shared/Logging/AppenderFile.h @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2008-2012 TrinityCore + * + * 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 . + */ + #ifndef APPENDERFILE_H #define APPENDERFILE_H diff --git a/src/server/shared/Logging/LogOperation.cpp b/src/server/shared/Logging/LogOperation.cpp index 59368e519cd..b36dd3a8b1e 100644 --- a/src/server/shared/Logging/LogOperation.cpp +++ b/src/server/shared/Logging/LogOperation.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2008-2012 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + #include "LogOperation.h" #include "Logger.h" diff --git a/src/server/shared/Logging/LogOperation.h b/src/server/shared/Logging/LogOperation.h index 046ff44e62e..d872670d756 100644 --- a/src/server/shared/Logging/LogOperation.h +++ b/src/server/shared/Logging/LogOperation.h @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2008-2012 TrinityCore + * + * 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 . + */ + #ifndef LOGOPERATION_H #define LOGOPERATION_H diff --git a/src/server/shared/Logging/LogWorker.cpp b/src/server/shared/Logging/LogWorker.cpp index 4dc71f7f878..a12faaf224c 100644 --- a/src/server/shared/Logging/LogWorker.cpp +++ b/src/server/shared/Logging/LogWorker.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2008-2012 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + #include "LogWorker.h" LogWorker::LogWorker() diff --git a/src/server/shared/Logging/LogWorker.h b/src/server/shared/Logging/LogWorker.h index fe51be5376c..ea1744f9790 100644 --- a/src/server/shared/Logging/LogWorker.h +++ b/src/server/shared/Logging/LogWorker.h @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2008-2012 TrinityCore + * + * 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 . + */ + #ifndef LOGWORKER_H #define LOGWORKER_H diff --git a/src/server/shared/Logging/Logger.cpp b/src/server/shared/Logging/Logger.cpp index 7464012c0ac..10276eb3acb 100644 --- a/src/server/shared/Logging/Logger.cpp +++ b/src/server/shared/Logging/Logger.cpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2008-2012 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + #include "Logger.h" Logger::Logger(): name(""), type(LOG_FILTER_GENERAL), level(LOG_LEVEL_DISABLED) diff --git a/src/server/shared/Logging/Logger.h b/src/server/shared/Logging/Logger.h index 10b3991a537..9d13f08620f 100644 --- a/src/server/shared/Logging/Logger.h +++ b/src/server/shared/Logging/Logger.h @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2008-2012 TrinityCore + * + * 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 . + */ + #ifndef LOGGER_H #define LOGGER_H diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 01dbd5eaf2d..99cb415dc98 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -403,177 +403,6 @@ PersistentCharacterCleanFlags = 0 PidFile = "" -# -# Appender config values: Given a appender "name" the following options -# can be read: -# -# Appender.name.Type -# Description: Type of appender. Extra appender config options -# will be read depending on this value -# Default: 0 - (None) -# 1 - (Console) -# 2 - (File) -# 3 - (DB) -# -# Appender.name.Level -# Description: Appender level of logging -# Default: 0 - (Disabled) -# 1 - (Trace) -# 2 - (Debug) -# 3 - (Info) -# 4 - (Warn) -# 5 - (Error) -# 6 - (Fatal) -# -# Appender.name.Colors -# Description: Colors for log messages -# (Format: "fatal error warn info debug trace"). -# (Only used with Type = 1) -# Default: "" - no colors -# Colors: 0 - BLACK -# 1 - RED -# 2 - GREEN -# 3 - BROWN -# 4 - BLUE -# 5 - MAGENTA -# 6 - CYAN -# 7 - GREY -# 8 - YELLOW -# 9 - LRED -# 10 - LGREEN -# 11 - LBLUE -# 12 - LMAGENTA -# 13 - LCYAN -# 14 - WHITE -# Example: "13 11 9 5 3 1" -# -# Appender.name.File -# Description: Name of the file -# Allows to use one "%u" to create dynamic files -# (Only used with Type = 2) -# -# Appender.name.Mode -# Description: Mode to open the file -# (Only used with Type = 2) -# Default: a - (Append) -# w - (Overwrite) -# -# Appender.name.Backup -# Description: Make a backup of existing file before overwrite -# (Only used with Mode = w) -# Default: 0 - false -# 1 - true -# -# Appender.name.Timestamp -# Description: Append timestamp to the log file name. -# Logname_YYYY-MM-DD_HH-MM-SS.Ext for Logname.Ext -# (Only used with Type = 2) -# -# Logger config values: Given a logger "name" the following options -# can be read: -# -# Logger.name.Type -# Description: Type of logger. Logs anything related to... -# If no logger with type = 0 exists core will create -# it but disabled. Logger with type = 0 is the -# default one, used when there is no other specific -# logger configured for other logger types -# Default: 0 - Default. Each type that has no config will -# rely on this one. Core will create this logger -# (disabled) if it's not configured -# 1 - Units that doesn't fit in other categories -# 2 - Pets -# 3 - Vehicles -# 4 - C++ AI, instance scripts, etc. -# 5 - DB AI, such as SAI, EAI, CreatureAI -# 6 - DB map scripts -# 7 - Network input/output, -# such as packet handlers and netcode logs -# 8 - Spellsystem and aurasystem -# 9 - Achievement system -# 10 - Condition system -# 11 - Pool system -# 12 - Auction house -# 13 - Arena's and battlegrounds -# 14 - Outdoor PVP -# 15 - Chat system -# 16 - LFG system -# 17 - Maps, instances (not scripts), -# grids, cells, visibility, etc. -# 18 - Player that doesn't fit in other categories. -# 19 - Player loading from DB -# (Player::_LoadXXX functions) -# 20 - Items -# 21 - Player skills (do not confuse with spells) -# 22 - Player chat logs -# 23 - loot -# 24 - guilds -# 25 - transports -# 26 - SQL. DB errors and SQL Driver -# 27 - GM Commands -# 28 - Remote Access Commands -# 29 - Warden -# 30 - Authserver -# 31 - Worldserver -# 32 - Game Events -# 33 - Calendar -# -# Logger.name.Level -# Description: Logger level of logging -# Default: 0 - (Disabled) -# 1 - (Trace) -# 2 - (Debug) -# 3 - (Info) -# 4 - (Warn) -# 5 - (Error) -# 6 - (Fatal) -# -# Logger.name.Appenders -# Description: List of appenders linked to logger -# (Using spaces as separator). - -# -# Appenders -# Description: List of Appenders to read from config -# (Using spaces as separator). -# Default: "Console Server" -# -# Loggers -# Description: List of Loggers to read from config -# (Using spaces as separator). -# Default: "root" - -Loggers=root GM SQL -Appenders=Console Server GM SQL - -Appender.Console.Type=1 -Appender.Console.Level=2 - -Appender.Server.Type=2 -Appender.Server.Level=2 -Appender.Server.File=Server.log -Appender.Server.Mode=w - -Appender.GM.Type=2 -Appender.GM.Level=2 -Appender.GM.File=gm_#%u.log - -Appender.SQL.Type=2 -Appender.SQL.Level=2 -Appender.SQL.File=SQL.log - -Logger.root.Type=0 -Logger.root.Level=3 -Logger.root.Appenders=Console Server - -Logger.SQL.Type=26 -Logger.SQL.Level=3 -Logger.SQL.Appenders=Console Server SQL - -Logger.GM.Type=27 -Logger.GM.Level=3 -Logger.GM.Appenders=Console Server GM - # # ChatLogs.Channel # Description: Log custom channel chat. @@ -648,6 +477,7 @@ ChatLogs.Addon = 0 ChatLogs.BattleGround = 0 +# Extended Logging system configuration moved to end of file (on purpose) # ################################################################################################### @@ -2746,3 +2576,178 @@ PlayerDump.DisallowOverwrite = 1 # ################################################################################################### + +################################################################################################### +# +# Logging system options. +# Note: As it uses dynamic option naming, all options related to one appender or logger are grouped. +# +# +# Appender config values: Given a appender "name" the following options +# can be read: +# +# Appender.name.Type +# Description: Type of appender. Extra appender config options +# will be read depending on this value +# Default: 0 - (None) +# 1 - (Console) +# 2 - (File) +# 3 - (DB) +# +# Appender.name.Level +# Description: Appender level of logging +# Default: 0 - (Disabled) +# 1 - (Trace) +# 2 - (Debug) +# 3 - (Info) +# 4 - (Warn) +# 5 - (Error) +# 6 - (Fatal) +# +# Appender.name.Colors +# Description: Colors for log messages +# (Format: "fatal error warn info debug trace"). +# (Only used with Type = 1) +# Default: "" - no colors +# Colors: 0 - BLACK +# 1 - RED +# 2 - GREEN +# 3 - BROWN +# 4 - BLUE +# 5 - MAGENTA +# 6 - CYAN +# 7 - GREY +# 8 - YELLOW +# 9 - LRED +# 10 - LGREEN +# 11 - LBLUE +# 12 - LMAGENTA +# 13 - LCYAN +# 14 - WHITE +# Example: "13 11 9 5 3 1" +# +# Appender.name.File +# Description: Name of the file +# Allows to use one "%u" to create dynamic files +# (Only used with Type = 2) +# +# Appender.name.Mode +# Description: Mode to open the file +# (Only used with Type = 2) +# Default: a - (Append) +# w - (Overwrite) +# +# Appender.name.Backup +# Description: Make a backup of existing file before overwrite +# (Only used with Mode = w) +# Default: 0 - false +# 1 - true +# +# Appender.name.Timestamp +# Description: Append timestamp to the log file name. +# Logname_YYYY-MM-DD_HH-MM-SS.Ext for Logname.Ext +# (Only used with Type = 2) +# +# Logger config values: Given a logger "name" the following options +# can be read: +# +# Logger.name.Type +# Description: Type of logger. Logs anything related to... +# If no logger with type = 0 exists core will create +# it but disabled. Logger with type = 0 is the +# default one, used when there is no other specific +# logger configured for other logger types +# Default: 0 - Default. Each type that has no config will +# rely on this one. Core will create this logger +# (disabled) if it's not configured +# 1 - Units that doesn't fit in other categories +# 2 - Pets +# 3 - Vehicles +# 4 - C++ AI, instance scripts, etc. +# 5 - DB AI, such as SAI, EAI, CreatureAI +# 6 - DB map scripts +# 7 - Network input/output, +# such as packet handlers and netcode logs +# 8 - Spellsystem and aurasystem +# 9 - Achievement system +# 10 - Condition system +# 11 - Pool system +# 12 - Auction house +# 13 - Arena's and battlegrounds +# 14 - Outdoor PVP +# 15 - Chat system +# 16 - LFG system +# 17 - Maps, instances (not scripts), +# grids, cells, visibility, etc. +# 18 - Player that doesn't fit in other categories. +# 19 - Player loading from DB +# (Player::_LoadXXX functions) +# 20 - Items +# 21 - Player skills (do not confuse with spells) +# 22 - Player chat logs +# 23 - loot +# 24 - guilds +# 25 - transports +# 26 - SQL. DB errors and SQL Driver +# 27 - GM Commands +# 28 - Remote Access Commands +# 29 - Warden +# 30 - Authserver +# 31 - Worldserver +# 32 - Game Events +# 33 - Calendar +# +# Logger.name.Level +# Description: Logger level of logging +# Default: 0 - (Disabled) +# 1 - (Trace) +# 2 - (Debug) +# 3 - (Info) +# 4 - (Warn) +# 5 - (Error) +# 6 - (Fatal) +# +# Logger.name.Appenders +# Description: List of appenders linked to logger +# (Using spaces as separator). +# +# Appenders +# Description: List of Appenders to read from config +# (Using spaces as separator). +# Default: "Console Server" +# +# Loggers +# Description: List of Loggers to read from config +# (Using spaces as separator). +# Default: "root" + +Loggers=root GM SQL +Appenders=Console Server GM SQL + +Appender.Console.Type=1 +Appender.Console.Level=2 + +Appender.Server.Type=2 +Appender.Server.Level=2 +Appender.Server.File=Server.log +Appender.Server.Mode=w + +Appender.GM.Type=2 +Appender.GM.Level=2 +Appender.GM.File=gm_#%u.log + +Appender.SQL.Type=2 +Appender.SQL.Level=2 +Appender.SQL.File=SQL.log + +Logger.root.Type=0 +Logger.root.Level=3 +Logger.root.Appenders=Console Server + +Logger.SQL.Type=26 +Logger.SQL.Level=3 +Logger.SQL.Appenders=Console Server SQL + +Logger.GM.Type=27 +Logger.GM.Level=3 +Logger.GM.Appenders=Console Server GM -- cgit v1.2.3 From 6d21515939388c5f24e3954880a21bea10c35173 Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 6 Aug 2012 13:20:24 +0200 Subject: Core/Logging: Implement logging to database --- sql/updates/auth/2012_08_06_00_auth_logs.sql | 2 ++ src/server/shared/Logging/AppenderDB.cpp | 27 +++++++++++++++------------ 2 files changed, 17 insertions(+), 12 deletions(-) create mode 100644 sql/updates/auth/2012_08_06_00_auth_logs.sql (limited to 'src/server/shared/Logging/AppenderDB.cpp') diff --git a/sql/updates/auth/2012_08_06_00_auth_logs.sql b/sql/updates/auth/2012_08_06_00_auth_logs.sql new file mode 100644 index 00000000000..04e90e7d208 --- /dev/null +++ b/sql/updates/auth/2012_08_06_00_auth_logs.sql @@ -0,0 +1,2 @@ +ALTER TABLE `logs` ADD COLUMN `level` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `type`; + diff --git a/src/server/shared/Logging/AppenderDB.cpp b/src/server/shared/Logging/AppenderDB.cpp index 63af9176193..0254ec72bd0 100644 --- a/src/server/shared/Logging/AppenderDB.cpp +++ b/src/server/shared/Logging/AppenderDB.cpp @@ -16,12 +16,7 @@ */ #include "AppenderDB.h" - -/* FIXME -#include "DatabaseWorkerPool.h" -#include "Implementation/LoginDatabase.h" // For logging -extern DatabaseWorkerPool LoginDatabase; -*/ +#include "Database/DatabaseEnv.h" AppenderDB::AppenderDB(uint8 id, std::string const& name, LogLevel level, uint8 realmId): Appender(id, name, APPENDER_DB, level), realm(realmId), enable(false) @@ -32,13 +27,21 @@ AppenderDB::~AppenderDB() { } -void AppenderDB::_write(LogMessage& /*message*/) +void AppenderDB::_write(LogMessage& message) { -/* FIXME - if (enable) - LoginDatabase.PExecute("INSERT INTO logs (time, realm, type, severity, string) " - "VALUES (" UI64FMTD ", %u, %u, '%s');", message.mtime, realm, message.type, message.level, message.text.c_str()); -*/ + if (!enable) + return; + switch (message.type) + { + case LOG_FILTER_SQL: + case LOG_FILTER_SQL_DRIVER: + case LOG_FILTER_SQL_DEV: + break; // Avoid infinite loop, PExecute triggers Logging with LOG_FILTER_SQL type + default: + LoginDatabase.PExecute("INSERT INTO logs (time, realm, type, level, string) " + "VALUES (" UI64FMTD ", %u, %u, %u, '%s');", message.mtime, realm, message.type, message.level, message.text.c_str()); + break; + } } void AppenderDB::setEnable(bool _enable) -- cgit v1.2.3 From 4a5a077b655664e2daa98dfe3e7e781605734027 Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 6 Aug 2012 13:36:34 +0200 Subject: Core/Logging: Use prepared statements in AppenderDB --- src/server/shared/Database/Implementation/LoginDatabase.cpp | 2 +- src/server/shared/Logging/AppenderDB.cpp | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'src/server/shared/Logging/AppenderDB.cpp') diff --git a/src/server/shared/Database/Implementation/LoginDatabase.cpp b/src/server/shared/Database/Implementation/LoginDatabase.cpp index 028d927a720..31d9f5ec1f6 100755 --- a/src/server/shared/Database/Implementation/LoginDatabase.cpp +++ b/src/server/shared/Database/Implementation/LoginDatabase.cpp @@ -59,7 +59,7 @@ void LoginDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(LOGIN_INS_REALM_CHARACTERS_INIT, "INSERT INTO realmcharacters (realmid, acctid, numchars) SELECT realmlist.id, account.id, 0 FROM realmlist, account LEFT JOIN realmcharacters ON acctid=account.id WHERE acctid IS NULL", CONNECTION_ASYNC); PREPARE_STATEMENT(LOGIN_UPD_EXPANSION, "UPDATE account SET expansion = ? WHERE id = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(LOGIN_UPD_ACCOUNT_LOCK, "UPDATE account SET locked = ? WHERE id = ?", CONNECTION_ASYNC); - PREPARE_STATEMENT(LOGIN_INS_LOG, "INSERT INTO logs (time, realm, type, string) VALUES (UNIX_TIMESTAMP(), ? , ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(LOGIN_INS_LOG, "INSERT INTO logs (time, realm, type, level, string) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC); PREPARE_STATEMENT(LOGIN_UPD_USERNAME, "UPDATE account SET v = 0, s = 0, username = ?, sha_pass_hash = ? WHERE id = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(LOGIN_UPD_PASSWORD, "UPDATE account SET v = 0, s = 0, sha_pass_hash = ? WHERE id = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(LOGIN_UPD_MUTE_TIME, "UPDATE account SET mutetime = ? WHERE id = ?", CONNECTION_ASYNC); diff --git a/src/server/shared/Logging/AppenderDB.cpp b/src/server/shared/Logging/AppenderDB.cpp index 0254ec72bd0..8836be2b24a 100644 --- a/src/server/shared/Logging/AppenderDB.cpp +++ b/src/server/shared/Logging/AppenderDB.cpp @@ -37,9 +37,14 @@ void AppenderDB::_write(LogMessage& message) case LOG_FILTER_SQL_DRIVER: case LOG_FILTER_SQL_DEV: break; // Avoid infinite loop, PExecute triggers Logging with LOG_FILTER_SQL type - default: - LoginDatabase.PExecute("INSERT INTO logs (time, realm, type, level, string) " - "VALUES (" UI64FMTD ", %u, %u, %u, '%s');", message.mtime, realm, message.type, message.level, message.text.c_str()); + default: + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(LOGIN_INS_LOG); + stmt->setUInt64(0, message.mtime); + stmt->setUInt32(1, realm); + stmt->setUInt8(2, message.type); + stmt->setUInt8(3, message.level); + stmt->setString(4, message.text); + LoginDatabase.Execute(stmt); break; } } -- cgit v1.2.3 From 5aa54ca0e97b48194376e504ad5d2b91cc8abdd1 Mon Sep 17 00:00:00 2001 From: kandera Date: Mon, 6 Aug 2012 13:02:11 -0300 Subject: Update src/server/shared/Logging/AppenderDB.cpp Core/Appender: fix typo --- src/server/shared/Logging/AppenderDB.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/server/shared/Logging/AppenderDB.cpp') diff --git a/src/server/shared/Logging/AppenderDB.cpp b/src/server/shared/Logging/AppenderDB.cpp index 8836be2b24a..76abfca2d85 100644 --- a/src/server/shared/Logging/AppenderDB.cpp +++ b/src/server/shared/Logging/AppenderDB.cpp @@ -38,7 +38,7 @@ void AppenderDB::_write(LogMessage& message) case LOG_FILTER_SQL_DEV: break; // Avoid infinite loop, PExecute triggers Logging with LOG_FILTER_SQL type default: - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(LOGIN_INS_LOG); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_LOG); stmt->setUInt64(0, message.mtime); stmt->setUInt32(1, realm); stmt->setUInt8(2, message.type); -- cgit v1.2.3 From ca2bc35713895adebbae30e1b371d9ff2d970bff Mon Sep 17 00:00:00 2001 From: Nay Date: Wed, 15 Aug 2012 21:30:55 +0100 Subject: Misc: CRLF to LF, whitespace cleanup and tabs to spaces --- doc/LoggingHOWTO.txt | 82 +- src/server/scripts/Commands/cs_disable.cpp | 14 +- src/server/scripts/Commands/cs_misc.cpp | 5758 ++++++++++++++-------------- src/server/shared/Logging/AppenderDB.cpp | 2 +- src/server/shared/Logging/Log.cpp | 2 +- 5 files changed, 2929 insertions(+), 2929 deletions(-) (limited to 'src/server/shared/Logging/AppenderDB.cpp') diff --git a/doc/LoggingHOWTO.txt b/doc/LoggingHOWTO.txt index 12850eb06cf..4e61812d7d8 100644 --- a/doc/LoggingHOWTO.txt +++ b/doc/LoggingHOWTO.txt @@ -23,7 +23,7 @@ For example, sLog->outInfo(...) is a logging request of level INFO. A logging request is said to be enabled if its level is higher than or equal to the level of its logger. Otherwise, the request is said to be disabled. A logger -without an assigned level will inherit one from the hierarchy +without an assigned level will inherit one from the hierarchy Example Logger Name Assigned Level Inherited Level @@ -72,16 +72,16 @@ Its a list of elements separated by comma where each element has its own meaning 4 - (Warn) 5 - (Error) 6 - (Fatal) - Flags: Define some extra modifications to do to logging message + Flags: Define some extra modifications to do to logging message 1 - Prefix Timestamp to the text 2 - Prefix Log Level to the text 4 - Prefix Log Filter type to the text 8 - Append timestamp to the log file name. Format: YYYY-MM-DD_HH-MM-SS - (Only used with Type = 2) + (Only used with Type = 2) 16 - Make a backup of existing file before overwrite - (Only used with Mode = w) + (Only used with Mode = w) -Depending on the type, elements optional1 and optional2 will take different +Depending on the type, elements optional1 and optional2 will take different Colors (read as optional1 if Type = Console) Format: "fatal error warn info debug trace" @@ -111,22 +111,22 @@ Depending on the type, elements optional1 and optional2 will take different Example: Appender.Console1=1,2,6 - - Creates new appender to log to console any message with log level DEBUG - or higher and prefixes log type and level to the message. - - Appender.Console2=1,5,1,13 11 9 5 3 1 - - Creates new appender to log to console any message with log level ERROR - or higher and prefixes timestamp to the message using colored text. - - Appender.File=2,2,7,Auth.log,w - - Creates new appender to log to file "Auth.log" any message with log level - DEBUG or higher and prefixes timestamp, type and level to message - + + Creates new appender to log to console any message with log level DEBUG + or higher and prefixes log type and level to the message. + + Appender.Console2=1,5,1,13 11 9 5 3 1 + + Creates new appender to log to console any message with log level ERROR + or higher and prefixes timestamp to the message using colored text. + + Appender.File=2,2,7,Auth.log,w + + Creates new appender to log to file "Auth.log" any message with log level + DEBUG or higher and prefixes timestamp, type and level to message + In the example, having two different loggers to log to console is perfectly -legal but redundant. +legal but redundant. Once we have the list of loggers to read, system will try to configure a new logger from its config line. Logger config line follows the format: @@ -188,7 +188,7 @@ Its a list of elements separated by comma where each element has its own meaning 6 - (Fatal) AppenderList: List of appenders linked to logger (Using spaces as separator). - + --- EXAMPLES --- EXAMPLE 1 @@ -198,23 +198,23 @@ logs for this server run. File should prefix timestamp, type and log level to the messages. Console should prefix type and log level. Appenders=Console Server - Loggers=Root + Loggers=Root Appender.Console=1,5,6 Appender.Server=2,5,7,Server.log,w Logger.Root=0,5,Console Server Lets trace how system will log two different messages: 1) sLog->outError(LOG_FILTER_GUILD, "Guild 1 created"); - System will try to find logger of type GUILD, as no logger is configured - for GUILD it will use Root logger. As message Log Level is equal or higher - than the Log level of logger the message is sent to the Appenders - configured in the Logger. "Console" and "Server". - Console will write: "ERROR [GUILD ] Guild 1 created" - Server will write to file "2012-08-15 ERROR [GUILD ] Guild 1 created" - + System will try to find logger of type GUILD, as no logger is configured + for GUILD it will use Root logger. As message Log Level is equal or higher + than the Log level of logger the message is sent to the Appenders + configured in the Logger. "Console" and "Server". + Console will write: "ERROR [GUILD ] Guild 1 created" + Server will write to file "2012-08-15 ERROR [GUILD ] Guild 1 created" + 2) sLog->outInfo(LOG_FILTER_CHARACTER, "Player Name Logged in"); - System will try to find logger of type CHARACTER, as no logger is - configured for CHARACTER it will use Root logger. As message Log Level is + System will try to find logger of type CHARACTER, as no logger is + configured for CHARACTER it will use Root logger. As message Log Level is not equal or higher than the Log level of logger the message its discarted. EXAMPLE 2 @@ -223,23 +223,23 @@ Same example that above, but now i want to see all messages of level INFO on file and server file should add timestamp on creation. Appenders=Console Server - Loggers=Root + Loggers=Root Appender.Console=1,5,6 Appender.Server=2,4,15,Server.log Logger.Root=0,4,Console Server Lets trace how system will log two different messages: 1) sLog->outError(LOG_FILTER_GUILD, "Guild 1 created"); - Performs exactly as example 1. + Performs exactly as example 1. 2) sLog->outInfo(LOG_FILTER_CHARACTER, "Player Name Logged in"); - System will try to find logger of type CHARACTER, as no logger is - configured for CHARACTER it will use Root logger. As message Log Level is + System will try to find logger of type CHARACTER, as no logger is + configured for CHARACTER it will use Root logger. As message Log Level is equal or higher than the Log level of logger the message is sent to the - Appenders configured in the Logger. "Console" and "Server". + Appenders configured in the Logger. "Console" and "Server". Console will discard msg as Log Level is not higher or equal to this - appender - Server will write to file - "2012-08-15 INFO [CHARACTER ] Guild 1 Player Name Logged in" + appender + Server will write to file + "2012-08-15 INFO [CHARACTER ] Guild 1 Player Name Logged in" EXAMPLE 3 As a dev, i may be interested in logging just a particular part of the core @@ -249,11 +249,11 @@ so i want SQLDEV to be logged to file without prefixes. All other messages should only be logged to console, GUILD to TRACE and CHARACTER to INFO Appenders=Console SQLDev - Loggers=Guild Characters SQLDev + Loggers=Guild Characters SQLDev Appender.Console=1,1 Appender.SQLDev=2,2,0,SQLDev.log Logger.Guild=24,1,Console - Logger.Characters=34,3,Console + Logger.Characters=34,3,Console Logger.SQLDev=37,3,SQLDev With this config, any message logger with a Log type different to GUILD, diff --git a/src/server/scripts/Commands/cs_disable.cpp b/src/server/scripts/Commands/cs_disable.cpp index a2a80edd43b..0bb376b08dd 100644 --- a/src/server/scripts/Commands/cs_disable.cpp +++ b/src/server/scripts/Commands/cs_disable.cpp @@ -62,7 +62,7 @@ public: { "add", SEC_ADMINISTRATOR, true, NULL, "", addDisableCommandTable }, { "remove", SEC_ADMINISTRATOR, true, NULL, "", removeDisableCommandTable }, { NULL, 0, false, NULL, "", NULL } - }; + }; static ChatCommand commandTable[] = { { "disable", SEC_ADMINISTRATOR, false, NULL, "", disableCommandTable }, @@ -88,7 +88,7 @@ public: uint32 entry = uint32(atoi(entryStr)); std::string disableTypeStr = ""; - + switch (disableType) { case DISABLE_TYPE_SPELL: @@ -171,12 +171,12 @@ public: default: break; } - + PreparedStatement* stmt = NULL; stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_DISABLES); stmt->setUInt32(0, entry); - stmt->setUInt8(1, disableType); - PreparedQueryResult result = WorldDatabase.Query(stmt); + stmt->setUInt8(1, disableType); + PreparedQueryResult result = WorldDatabase.Query(stmt); if (result) { handler->PSendSysMessage("This %s (Id: %u) is already disabled.", disableTypeStr.c_str(), entry); @@ -290,8 +290,8 @@ public: PreparedStatement* stmt = NULL; stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_DISABLES); stmt->setUInt32(0, entry); - stmt->setUInt8(1, disableType); - PreparedQueryResult result = WorldDatabase.Query(stmt); + stmt->setUInt8(1, disableType); + PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) { handler->PSendSysMessage("This %s (Id: %u) is not disabled.", disableTypeStr.c_str(), entry); diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 80847d7dec4..1edaaf5bcbf 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -1,2879 +1,2879 @@ -/* - * Copyright (C) 2008-2012 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "Chat.h" -#include "ScriptMgr.h" -#include "AccountMgr.h" -#include "ArenaTeamMgr.h" -#include "CellImpl.h" -#include "GridNotifiers.h" -#include "Group.h" -#include "InstanceSaveMgr.h" -#include "MovementGenerator.h" -#include "ObjectAccessor.h" -#include "SpellAuras.h" -#include "TargetedMovementGenerator.h" -#include "WeatherMgr.h" -#include "ace/INET_Addr.h" - -class misc_commandscript : public CommandScript -{ -public: - misc_commandscript() : CommandScript("misc_commandscript") { } - - ChatCommand* GetCommands() const - { - static ChatCommand groupCommandTable[] = - { - { "leader", SEC_ADMINISTRATOR, false, &HandleGroupLeaderCommand, "", NULL }, - { "disband", SEC_ADMINISTRATOR, false, &HandleGroupDisbandCommand, "", NULL }, - { "remove", SEC_ADMINISTRATOR, false, &HandleGroupRemoveCommand, "", NULL }, - { NULL, 0, false, NULL, "", NULL } - }; - static ChatCommand petCommandTable[] = - { - { "create", SEC_GAMEMASTER, false, &HandleCreatePetCommand, "", NULL }, - { "learn", SEC_GAMEMASTER, false, &HandlePetLearnCommand, "", NULL }, - { "unlearn", SEC_GAMEMASTER, false, &HandlePetUnlearnCommand, "", NULL }, - { NULL, 0, false, NULL, "", NULL } - }; - static ChatCommand sendCommandTable[] = - { - { "items", SEC_ADMINISTRATOR, true, &HandleSendItemsCommand, "", NULL }, - { "mail", SEC_MODERATOR, true, &HandleSendMailCommand, "", NULL }, - { "message", SEC_ADMINISTRATOR, true, &HandleSendMessageCommand, "", NULL }, - { "money", SEC_ADMINISTRATOR, true, &HandleSendMoneyCommand, "", NULL }, - { NULL, 0, false, NULL, "", NULL } - }; - static ChatCommand commandTable[] = - { - { "dev", SEC_ADMINISTRATOR, false, &HandleDevCommand, "", NULL }, - { "gps", SEC_ADMINISTRATOR, false, &HandleGPSCommand, "", NULL }, - { "aura", SEC_ADMINISTRATOR, false, &HandleAuraCommand, "", NULL }, - { "unaura", SEC_ADMINISTRATOR, false, &HandleUnAuraCommand, "", NULL }, - { "appear", SEC_MODERATOR, false, &HandleAppearCommand, "", NULL }, - { "summon", SEC_MODERATOR, false, &HandleSummonCommand, "", NULL }, - { "groupsummon", SEC_MODERATOR, false, &HandleGroupSummonCommand, "", NULL }, - { "commands", SEC_PLAYER, true, &HandleCommandsCommand, "", NULL }, - { "die", SEC_ADMINISTRATOR, false, &HandleDieCommand, "", NULL }, - { "revive", SEC_ADMINISTRATOR, true, &HandleReviveCommand, "", NULL }, - { "dismount", SEC_PLAYER, false, &HandleDismountCommand, "", NULL }, - { "guid", SEC_GAMEMASTER, false, &HandleGUIDCommand, "", NULL }, - { "help", SEC_PLAYER, true, &HandleHelpCommand, "", NULL }, - { "itemmove", SEC_GAMEMASTER, false, &HandleItemMoveCommand, "", NULL }, - { "cooldown", SEC_ADMINISTRATOR, false, &HandleCooldownCommand, "", NULL }, - { "distance", SEC_ADMINISTRATOR, false, &HandleGetDistanceCommand, "", NULL }, - { "recall", SEC_MODERATOR, false, &HandleRecallCommand, "", NULL }, - { "save", SEC_PLAYER, false, &HandleSaveCommand, "", NULL }, - { "saveall", SEC_MODERATOR, true, &HandleSaveAllCommand, "", NULL }, - { "kick", SEC_GAMEMASTER, true, &HandleKickPlayerCommand, "", NULL }, - { "start", SEC_PLAYER, false, &HandleStartCommand, "", NULL }, - { "taxicheat", SEC_MODERATOR, false, &HandleTaxiCheatCommand, "", NULL }, - { "linkgrave", SEC_ADMINISTRATOR, false, &HandleLinkGraveCommand, "", NULL }, - { "neargrave", SEC_ADMINISTRATOR, false, &HandleNearGraveCommand, "", NULL }, - { "explorecheat", SEC_ADMINISTRATOR, false, &HandleExploreCheatCommand, "", NULL }, - { "showarea", SEC_ADMINISTRATOR, false, &HandleShowAreaCommand, "", NULL }, - { "hidearea", SEC_ADMINISTRATOR, false, &HandleHideAreaCommand, "", NULL }, - { "additem", SEC_ADMINISTRATOR, false, &HandleAddItemCommand, "", NULL }, - { "additemset", SEC_ADMINISTRATOR, false, &HandleAddItemSetCommand, "", NULL }, - { "bank", SEC_ADMINISTRATOR, false, &HandleBankCommand, "", NULL }, - { "wchange", SEC_ADMINISTRATOR, false, &HandleChangeWeather, "", NULL }, - { "maxskill", SEC_ADMINISTRATOR, false, &HandleMaxSkillCommand, "", NULL }, - { "setskill", SEC_ADMINISTRATOR, false, &HandleSetSkillCommand, "", NULL }, - { "pinfo", SEC_GAMEMASTER, true, &HandlePInfoCommand, "", NULL }, - { "respawn", SEC_ADMINISTRATOR, false, &HandleRespawnCommand, "", NULL }, - { "send", SEC_MODERATOR, true, NULL, "", sendCommandTable }, - { "pet", SEC_GAMEMASTER, false, NULL, "", petCommandTable }, - { "mute", SEC_MODERATOR, true, &HandleMuteCommand, "", NULL }, - { "unmute", SEC_MODERATOR, true, &HandleUnmuteCommand, "", NULL }, - { "movegens", SEC_ADMINISTRATOR, false, &HandleMovegensCommand, "", NULL }, - { "cometome", SEC_ADMINISTRATOR, false, &HandleComeToMeCommand, "", NULL }, - { "damage", SEC_ADMINISTRATOR, false, &HandleDamageCommand, "", NULL }, - { "combatstop", SEC_GAMEMASTER, true, &HandleCombatStopCommand, "", NULL }, - { "flusharenapoints", SEC_ADMINISTRATOR, false, &HandleFlushArenaPointsCommand, "", NULL }, - { "repairitems", SEC_GAMEMASTER, true, &HandleRepairitemsCommand, "", NULL }, - { "waterwalk", SEC_GAMEMASTER, false, &HandleWaterwalkCommand, "", NULL }, - { "freeze", SEC_MODERATOR, false, &HandleFreezeCommand, "", NULL }, - { "unfreeze", SEC_MODERATOR, false, &HandleUnFreezeCommand, "", NULL }, - { "listfreeze", SEC_MODERATOR, false, &HandleListFreezeCommand, "", NULL }, - { "group", SEC_ADMINISTRATOR, false, NULL, "", groupCommandTable }, - { "possess", SEC_ADMINISTRATOR, false, HandlePossessCommand, "", NULL }, - { "unpossess", SEC_ADMINISTRATOR, false, HandleUnPossessCommand, "", NULL }, - { "bindsight", SEC_ADMINISTRATOR, false, HandleBindSightCommand, "", NULL }, - { "unbindsight", SEC_ADMINISTRATOR, false, HandleUnbindSightCommand, "", NULL }, - { "playall", SEC_GAMEMASTER, false, HandlePlayAllCommand, "", NULL }, - { NULL, 0, false, NULL, "", NULL } - }; - return commandTable; - } - - static bool HandleDevCommand(ChatHandler* handler, char const* args) - { - if (!*args) - { - if (handler->GetSession()->GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_DEVELOPER)) - handler->GetSession()->SendNotification(LANG_DEV_ON); - else - handler->GetSession()->SendNotification(LANG_DEV_OFF); - return true; - } - - std::string argstr = (char*)args; - - if (argstr == "on") - { - handler->GetSession()->GetPlayer()->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_DEVELOPER); - handler->GetSession()->SendNotification(LANG_DEV_ON); - return true; - } - - if (argstr == "off") - { - handler->GetSession()->GetPlayer()->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_DEVELOPER); - handler->GetSession()->SendNotification(LANG_DEV_OFF); - return true; - } - - handler->SendSysMessage(LANG_USE_BOL); - handler->SetSentErrorMessage(true); - return false; - } - - static bool HandleGPSCommand(ChatHandler* handler, char const* args) - { - WorldObject* object = NULL; - if (*args) - { - uint64 guid = handler->extractGuidFromLink((char*)args); - if (guid) - object = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*handler->GetSession()->GetPlayer(), guid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT); - - if (!object) - { - handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); - handler->SetSentErrorMessage(true); - return false; - } - } - else - { - object = handler->getSelectedUnit(); - - if (!object) - { - handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - handler->SetSentErrorMessage(true); - return false; - } - } - - CellCoord cellCoord = Trinity::ComputeCellCoord(object->GetPositionX(), object->GetPositionY()); - Cell cell(cellCoord); - - uint32 zoneId, areaId; - object->GetZoneAndAreaId(zoneId, areaId); - - MapEntry const* mapEntry = sMapStore.LookupEntry(object->GetMapId()); - AreaTableEntry const* zoneEntry = GetAreaEntryByAreaID(zoneId); - AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(areaId); - - float zoneX = object->GetPositionX(); - float zoneY = object->GetPositionY(); - - Map2ZoneCoordinates(zoneX, zoneY, zoneId); - - Map const* map = object->GetMap(); - float groundZ = map->GetHeight(object->GetPhaseMask(), object->GetPositionX(), object->GetPositionY(), MAX_HEIGHT); - float floorZ = map->GetHeight(object->GetPhaseMask(), object->GetPositionX(), object->GetPositionY(), object->GetPositionZ()); - - GridCoord gridCoord = Trinity::ComputeGridCoord(object->GetPositionX(), object->GetPositionY()); - - // 63? WHY? - int gridX = 63 - gridCoord.x_coord; - int gridY = 63 - gridCoord.y_coord; - - uint32 haveMap = Map::ExistMap(object->GetMapId(), gridX, gridY) ? 1 : 0; - uint32 haveVMap = Map::ExistVMap(object->GetMapId(), gridX, gridY) ? 1 : 0; - - if (haveVMap) - { - if (map->IsOutdoors(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ())) - handler->PSendSysMessage("You are outdoors"); - else - handler->PSendSysMessage("You are indoors"); - } - else - handler->PSendSysMessage("no VMAP available for area info"); - - handler->PSendSysMessage(LANG_MAP_POSITION, - object->GetMapId(), (mapEntry ? mapEntry->name[handler->GetSessionDbcLocale()] : ""), - zoneId, (zoneEntry ? zoneEntry->area_name[handler->GetSessionDbcLocale()] : ""), - areaId, (areaEntry ? areaEntry->area_name[handler->GetSessionDbcLocale()] : ""), - object->GetPhaseMask(), - object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), object->GetOrientation(), - cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), object->GetInstanceId(), - zoneX, zoneY, groundZ, floorZ, haveMap, haveVMap); - - LiquidData liquidStatus; - ZLiquidStatus status = map->getLiquidStatus(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), MAP_ALL_LIQUIDS, &liquidStatus); - - if (status) - handler->PSendSysMessage(LANG_LIQUID_STATUS, liquidStatus.level, liquidStatus.depth_level, liquidStatus.entry, liquidStatus.type_flags, status); - - return true; - } - - static bool HandleAuraCommand(ChatHandler* handler, char const* args) - { - Unit* target = handler->getSelectedUnit(); - if (!target) - { - handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - handler->SetSentErrorMessage(true); - return false; - } - - // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form - uint32 spellId = handler->extractSpellIdFromLink((char*)args); - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId)) - Aura::TryRefreshStackOrCreate(spellInfo, MAX_EFFECT_MASK, target, target); - - return true; - } - - static bool HandleUnAuraCommand(ChatHandler* handler, char const* args) - { - Unit* target = handler->getSelectedUnit(); - if (!target) - { - handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - handler->SetSentErrorMessage(true); - return false; - } - - std::string argstr = args; - if (argstr == "all") - { - target->RemoveAllAuras(); - return true; - } - - // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form - uint32 spellId = handler->extractSpellIdFromLink((char*)args); - if (!spellId) - return false; - - target->RemoveAurasDueToSpell(spellId); - - return true; - } - // Teleport to Player - static bool HandleAppearCommand(ChatHandler* handler, char const* args) - { - Player* target; - uint64 targetGuid; - std::string targetName; - if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) - return false; - - Player* _player = handler->GetSession()->GetPlayer(); - if (target == _player || targetGuid == _player->GetGUID()) - { - handler->SendSysMessage(LANG_CANT_TELEPORT_SELF); - handler->SetSentErrorMessage(true); - return false; - } - - if (target) - { - // check online security - if (handler->HasLowerSecurity(target, 0)) - return false; - - std::string chrNameLink = handler->playerLink(targetName); - - Map* map = target->GetMap(); - if (map->IsBattlegroundOrArena()) - { - // only allow if gm mode is on - if (!_player->isGameMaster()) - { - handler->PSendSysMessage(LANG_CANNOT_GO_TO_BG_GM, chrNameLink.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - // if both players are in different bgs - else if (_player->GetBattlegroundId() && _player->GetBattlegroundId() != target->GetBattlegroundId()) - _player->LeaveBattleground(false); // Note: should be changed so _player gets no Deserter debuff - - // all's well, set bg id - // when porting out from the bg, it will be reset to 0 - _player->SetBattlegroundId(target->GetBattlegroundId(), target->GetBattlegroundTypeId()); - // remember current position as entry point for return at bg end teleportation - if (!_player->GetMap()->IsBattlegroundOrArena()) - _player->SetBattlegroundEntryPoint(); - } - else if (map->IsDungeon()) - { - // we have to go to instance, and can go to player only if: - // 1) we are in his group (either as leader or as member) - // 2) we are not bound to any group and have GM mode on - if (_player->GetGroup()) - { - // we are in group, we can go only if we are in the player group - if (_player->GetGroup() != target->GetGroup()) - { - handler->PSendSysMessage(LANG_CANNOT_GO_TO_INST_PARTY, chrNameLink.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - } - else - { - // we are not in group, let's verify our GM mode - if (!_player->isGameMaster()) - { - handler->PSendSysMessage(LANG_CANNOT_GO_TO_INST_GM, chrNameLink.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - } - - // if the player or the player's group is bound to another instance - // the player will not be bound to another one - InstancePlayerBind* bind = _player->GetBoundInstance(target->GetMapId(), target->GetDifficulty(map->IsRaid())); - if (!bind) - { - Group* group = _player->GetGroup(); - // if no bind exists, create a solo bind - InstanceGroupBind* gBind = group ? group->GetBoundInstance(target) : NULL; // if no bind exists, create a solo bind - if (!gBind) - if (InstanceSave* save = sInstanceSaveMgr->GetInstanceSave(target->GetInstanceId())) - _player->BindToInstance(save, !save->CanReset()); - } - - if (map->IsRaid()) - _player->SetRaidDifficulty(target->GetRaidDifficulty()); - else - _player->SetDungeonDifficulty(target->GetDungeonDifficulty()); - } - - handler->PSendSysMessage(LANG_APPEARING_AT, chrNameLink.c_str()); - - // stop flight if need - if (_player->isInFlight()) - { - _player->GetMotionMaster()->MovementExpired(); - _player->CleanupAfterTaxiFlight(); - } - // save only in non-flight case - else - _player->SaveRecallPosition(); - - // to point to see at target with same orientation - float x, y, z; - target->GetContactPoint(_player, x, y, z); - - _player->TeleportTo(target->GetMapId(), x, y, z, _player->GetAngle(target), TELE_TO_GM_MODE); - _player->SetPhaseMask(target->GetPhaseMask(), true); - } - else - { - // check offline security - if (handler->HasLowerSecurity(NULL, targetGuid)) - return false; - - std::string nameLink = handler->playerLink(targetName); - - handler->PSendSysMessage(LANG_APPEARING_AT, nameLink.c_str()); - - // to point where player stay (if loaded) - float x, y, z, o; - uint32 map; - bool in_flight; - if (!Player::LoadPositionFromDB(map, x, y, z, o, in_flight, targetGuid)) - return false; - - // stop flight if need - if (_player->isInFlight()) - { - _player->GetMotionMaster()->MovementExpired(); - _player->CleanupAfterTaxiFlight(); - } - // save only in non-flight case - else - _player->SaveRecallPosition(); - - _player->TeleportTo(map, x, y, z, _player->GetOrientation()); - } - - return true; - } - // Summon Player - static bool HandleSummonCommand(ChatHandler* handler, char const* args) - { - Player* target; - uint64 targetGuid; - std::string targetName; - if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) - return false; - - Player* _player = handler->GetSession()->GetPlayer(); - if (target == _player || targetGuid == _player->GetGUID()) - { - handler->PSendSysMessage(LANG_CANT_TELEPORT_SELF); - handler->SetSentErrorMessage(true); - return false; - } - - if (target) - { - std::string nameLink = handler->playerLink(targetName); - // check online security - if (handler->HasLowerSecurity(target, 0)) - return false; - - if (target->IsBeingTeleported()) - { - handler->PSendSysMessage(LANG_IS_TELEPORTED, nameLink.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - - Map* map = handler->GetSession()->GetPlayer()->GetMap(); - - if (map->IsBattlegroundOrArena()) - { - // only allow if gm mode is on - if (!_player->isGameMaster()) - { - handler->PSendSysMessage(LANG_CANNOT_GO_TO_BG_GM, nameLink.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - // if both players are in different bgs - else if (target->GetBattlegroundId() && handler->GetSession()->GetPlayer()->GetBattlegroundId() != target->GetBattlegroundId()) - target->LeaveBattleground(false); // Note: should be changed so target gets no Deserter debuff - - // all's well, set bg id - // when porting out from the bg, it will be reset to 0 - target->SetBattlegroundId(handler->GetSession()->GetPlayer()->GetBattlegroundId(), handler->GetSession()->GetPlayer()->GetBattlegroundTypeId()); - // remember current position as entry point for return at bg end teleportation - if (!target->GetMap()->IsBattlegroundOrArena()) - target->SetBattlegroundEntryPoint(); - } - else if (map->IsDungeon()) - { - Map* map = target->GetMap(); - - if (map->Instanceable() && map->GetInstanceId() != map->GetInstanceId()) - target->UnbindInstance(map->GetInstanceId(), target->GetDungeonDifficulty(), true); - - // we are in instance, and can summon only player in our group with us as lead - if (!handler->GetSession()->GetPlayer()->GetGroup() || !target->GetGroup() || - (target->GetGroup()->GetLeaderGUID() != handler->GetSession()->GetPlayer()->GetGUID()) || - (handler->GetSession()->GetPlayer()->GetGroup()->GetLeaderGUID() != handler->GetSession()->GetPlayer()->GetGUID())) - // the last check is a bit excessive, but let it be, just in case - { - handler->PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST, nameLink.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - } - - handler->PSendSysMessage(LANG_SUMMONING, nameLink.c_str(), ""); - if (handler->needReportToTarget(target)) - ChatHandler(target).PSendSysMessage(LANG_SUMMONED_BY, handler->playerLink(_player->GetName()).c_str()); - - // stop flight if need - if (target->isInFlight()) - { - target->GetMotionMaster()->MovementExpired(); - target->CleanupAfterTaxiFlight(); - } - // save only in non-flight case - else - target->SaveRecallPosition(); - - // before GM - float x, y, z; - handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, target->GetObjectSize()); - target->TeleportTo(handler->GetSession()->GetPlayer()->GetMapId(), x, y, z, target->GetOrientation()); - target->SetPhaseMask(handler->GetSession()->GetPlayer()->GetPhaseMask(), true); - } - else - { - // check offline security - if (handler->HasLowerSecurity(NULL, targetGuid)) - return false; - - std::string nameLink = handler->playerLink(targetName); - - handler->PSendSysMessage(LANG_SUMMONING, nameLink.c_str(), handler->GetTrinityString(LANG_OFFLINE)); - - // in point where GM stay - Player::SavePositionInDB(handler->GetSession()->GetPlayer()->GetMapId(), - handler->GetSession()->GetPlayer()->GetPositionX(), - handler->GetSession()->GetPlayer()->GetPositionY(), - handler->GetSession()->GetPlayer()->GetPositionZ(), - handler->GetSession()->GetPlayer()->GetOrientation(), - handler->GetSession()->GetPlayer()->GetZoneId(), - targetGuid); - } - - return true; - } - // Summon group of player - static bool HandleGroupSummonCommand(ChatHandler* handler, char const* args) - { - Player* target; - if (!handler->extractPlayerTarget((char*)args, &target)) - return false; - - // check online security - if (handler->HasLowerSecurity(target, 0)) - return false; - - Group* group = target->GetGroup(); - - std::string nameLink = handler->GetNameLink(target); - - if (!group) - { - handler->PSendSysMessage(LANG_NOT_IN_GROUP, nameLink.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - - Map* gmMap = handler->GetSession()->GetPlayer()->GetMap(); - bool toInstance = gmMap->Instanceable(); - - // we are in instance, and can summon only player in our group with us as lead - if (toInstance && ( - !handler->GetSession()->GetPlayer()->GetGroup() || (group->GetLeaderGUID() != handler->GetSession()->GetPlayer()->GetGUID()) || - (handler->GetSession()->GetPlayer()->GetGroup()->GetLeaderGUID() != handler->GetSession()->GetPlayer()->GetGUID()))) - // the last check is a bit excessive, but let it be, just in case - { - handler->SendSysMessage(LANG_CANNOT_SUMMON_TO_INST); - handler->SetSentErrorMessage(true); - return false; - } - - for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) - { - Player* player = itr->getSource(); - - if (!player || player == handler->GetSession()->GetPlayer() || !player->GetSession()) - continue; - - // check online security - if (handler->HasLowerSecurity(player, 0)) - return false; - - std::string plNameLink = handler->GetNameLink(player); - - if (player->IsBeingTeleported() == true) - { - handler->PSendSysMessage(LANG_IS_TELEPORTED, plNameLink.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - - if (toInstance) - { - Map* playerMap = player->GetMap(); - - if (playerMap->Instanceable() && playerMap->GetInstanceId() != gmMap->GetInstanceId()) - { - // cannot summon from instance to instance - handler->PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST, plNameLink.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - } - - handler->PSendSysMessage(LANG_SUMMONING, plNameLink.c_str(), ""); - if (handler->needReportToTarget(player)) - ChatHandler(player).PSendSysMessage(LANG_SUMMONED_BY, handler->GetNameLink().c_str()); - - // stop flight if need - if (player->isInFlight()) - { - player->GetMotionMaster()->MovementExpired(); - player->CleanupAfterTaxiFlight(); - } - // save only in non-flight case - else - player->SaveRecallPosition(); - - // before GM - float x, y, z; - handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, player->GetObjectSize()); - player->TeleportTo(handler->GetSession()->GetPlayer()->GetMapId(), x, y, z, player->GetOrientation()); - } - - return true; - } - - static bool HandleCommandsCommand(ChatHandler* handler, char const* /*args*/) - { - handler->ShowHelpForCommand(handler->getCommandTable(), ""); - return true; - } - - static bool HandleDieCommand(ChatHandler* handler, char const* /*args*/) - { - Unit* target = handler->getSelectedUnit(); - - if (!target || !handler->GetSession()->GetPlayer()->GetSelection()) - { - handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - handler->SetSentErrorMessage(true); - return false; - } - - if (target->GetTypeId() == TYPEID_PLAYER) - { - if (handler->HasLowerSecurity((Player*)target, 0, false)) - return false; - } - - if (target->isAlive()) - { - if (sWorld->getBoolConfig(CONFIG_DIE_COMMAND_MODE)) - handler->GetSession()->GetPlayer()->Kill(target); - else - handler->GetSession()->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - } - - return true; - } - - static bool HandleReviveCommand(ChatHandler* handler, char const* args) - { - Player* target; - uint64 targetGuid; - if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid)) - return false; - - if (target) - { - target->ResurrectPlayer(!AccountMgr::IsPlayerAccount(target->GetSession()->GetSecurity()) ? 1.0f : 0.5f); - target->SpawnCorpseBones(); - target->SaveToDB(); - } - else - // will resurrected at login without corpse - sObjectAccessor->ConvertCorpseForPlayer(targetGuid); - - return true; - } - - static bool HandleDismountCommand(ChatHandler* handler, char const* /*args*/) - { - Player* player = handler->GetSession()->GetPlayer(); - - // If player is not mounted, so go out :) - if (!player->IsMounted()) - { - handler->SendSysMessage(LANG_CHAR_NON_MOUNTED); - handler->SetSentErrorMessage(true); - return false; - } - - if (player->isInFlight()) - { - handler->SendSysMessage(LANG_YOU_IN_FLIGHT); - handler->SetSentErrorMessage(true); - return false; - } - - player->Dismount(); - player->RemoveAurasByType(SPELL_AURA_MOUNTED); - return true; - } - - static bool HandleGUIDCommand(ChatHandler* handler, char const* /*args*/) - { - uint64 guid = handler->GetSession()->GetPlayer()->GetSelection(); - - if (guid == 0) - { - handler->SendSysMessage(LANG_NO_SELECTION); - handler->SetSentErrorMessage(true); - return false; - } - - handler->PSendSysMessage(LANG_OBJECT_GUID, GUID_LOPART(guid), GUID_HIPART(guid)); - return true; - } - - static bool HandleHelpCommand(ChatHandler* handler, char const* args) - { - char const* cmd = strtok((char*)args, " "); - if (!cmd) - { - handler->ShowHelpForCommand(handler->getCommandTable(), "help"); - handler->ShowHelpForCommand(handler->getCommandTable(), ""); - } - else - { - if (!handler->ShowHelpForCommand(handler->getCommandTable(), cmd)) - handler->SendSysMessage(LANG_NO_HELP_CMD); - } - - return true; - } - // move item to other slot - static bool HandleItemMoveCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - char const* param1 = strtok((char*)args, " "); - if (!param1) - return false; - - char const* param2 = strtok(NULL, " "); - if (!param2) - return false; - - uint8 srcSlot = uint8(atoi(param1)); - uint8 dstSlot = uint8(atoi(param2)); - - if (srcSlot == dstSlot) - return true; - - if (!handler->GetSession()->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0, srcSlot, true)) - return false; - - if (!handler->GetSession()->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0, dstSlot, false)) - return false; - - uint16 src = ((INVENTORY_SLOT_BAG_0 << 8) | srcSlot); - uint16 dst = ((INVENTORY_SLOT_BAG_0 << 8) | dstSlot); - - handler->GetSession()->GetPlayer()->SwapItem(src, dst); - - return true; - } - - static bool HandleCooldownCommand(ChatHandler* handler, char const* args) - { - Player* target = handler->getSelectedPlayer(); - if (!target) - { - handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); - handler->SetSentErrorMessage(true); - return false; - } - - std::string nameLink = handler->GetNameLink(target); - - if (!*args) - { - target->RemoveAllSpellCooldown(); - handler->PSendSysMessage(LANG_REMOVEALL_COOLDOWN, nameLink.c_str()); - } - else - { - // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form - uint32 spellIid = handler->extractSpellIdFromLink((char*)args); - if (!spellIid) - return false; - - if (!sSpellMgr->GetSpellInfo(spellIid)) - { - handler->PSendSysMessage(LANG_UNKNOWN_SPELL, target == handler->GetSession()->GetPlayer() ? handler->GetTrinityString(LANG_YOU) : nameLink.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - - target->RemoveSpellCooldown(spellIid, true); - handler->PSendSysMessage(LANG_REMOVE_COOLDOWN, spellIid, target == handler->GetSession()->GetPlayer() ? handler->GetTrinityString(LANG_YOU) : nameLink.c_str()); - } - return true; - } - - static bool HandleGetDistanceCommand(ChatHandler* handler, char const* args) - { - WorldObject* obj = NULL; - - if (*args) - { - uint64 guid = handler->extractGuidFromLink((char*)args); - if (guid) - obj = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*handler->GetSession()->GetPlayer(), guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); - - if (!obj) - { - handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); - handler->SetSentErrorMessage(true); - return false; - } - } - else - { - obj = handler->getSelectedUnit(); - - if (!obj) - { - handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - handler->SetSentErrorMessage(true); - return false; - } - } - - handler->PSendSysMessage(LANG_DISTANCE, handler->GetSession()->GetPlayer()->GetDistance(obj), handler->GetSession()->GetPlayer()->GetDistance2d(obj), handler->GetSession()->GetPlayer()->GetExactDist(obj), handler->GetSession()->GetPlayer()->GetExactDist2d(obj)); - return true; - } - // Teleport player to last position - static bool HandleRecallCommand(ChatHandler* handler, char const* args) - { - Player* target; - if (!handler->extractPlayerTarget((char*)args, &target)) - return false; - - // check online security - if (handler->HasLowerSecurity(target, 0)) - return false; - - if (target->IsBeingTeleported()) - { - handler->PSendSysMessage(LANG_IS_TELEPORTED, handler->GetNameLink(target).c_str()); - handler->SetSentErrorMessage(true); - return false; - } - - // stop flight if need - if (target->isInFlight()) - { - target->GetMotionMaster()->MovementExpired(); - target->CleanupAfterTaxiFlight(); - } - - target->TeleportTo(target->m_recallMap, target->m_recallX, target->m_recallY, target->m_recallZ, target->m_recallO); - return true; - } - - static bool HandleSaveCommand(ChatHandler* handler, char const* /*args*/) - { - Player* player = handler->GetSession()->GetPlayer(); - - // save GM account without delay and output message - if (!AccountMgr::IsPlayerAccount(handler->GetSession()->GetSecurity())) - { - if (Player* target = handler->getSelectedPlayer()) - target->SaveToDB(); - else - player->SaveToDB(); - handler->SendSysMessage(LANG_PLAYER_SAVED); - return true; - } - - // save if the player has last been saved over 20 seconds ago - uint32 saveInterval = sWorld->getIntConfig(CONFIG_INTERVAL_SAVE); - if (saveInterval == 0 || (saveInterval > 20 * IN_MILLISECONDS && player->GetSaveTimer() <= saveInterval - 20 * IN_MILLISECONDS)) - player->SaveToDB(); - - return true; - } - - // Save all players in the world - static bool HandleSaveAllCommand(ChatHandler* handler, char const* /*args*/) - { - sObjectAccessor->SaveAllPlayers(); - handler->SendSysMessage(LANG_PLAYERS_SAVED); - return true; - } - - // kick player - static bool HandleKickPlayerCommand(ChatHandler* handler, char const* args) - { - Player* target = NULL; - std::string playerName; - if (!handler->extractPlayerTarget((char*)args, &target, NULL, &playerName)) - return false; - - if (handler->GetSession() && target == handler->GetSession()->GetPlayer()) - { - handler->SendSysMessage(LANG_COMMAND_KICKSELF); - handler->SetSentErrorMessage(true); - return false; - } - - // check online security - if (handler->HasLowerSecurity(target, 0)) - return false; - - if (sWorld->getBoolConfig(CONFIG_SHOW_KICK_IN_WORLD)) - sWorld->SendWorldText(LANG_COMMAND_KICKMESSAGE, playerName.c_str()); - else - handler->PSendSysMessage(LANG_COMMAND_KICKMESSAGE, playerName.c_str()); - - target->GetSession()->KickPlayer(); - - return true; - } - - static bool HandleStartCommand(ChatHandler* handler, char const* /*args*/) - { - Player* player = handler->GetSession()->GetPlayer(); - - if (player->isInFlight()) - { - handler->SendSysMessage(LANG_YOU_IN_FLIGHT); - handler->SetSentErrorMessage(true); - return false; - } - - if (player->isInCombat()) - { - handler->SendSysMessage(LANG_YOU_IN_COMBAT); - handler->SetSentErrorMessage(true); - return false; - } - - if (player->isDead() || player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) - { - // if player is dead and stuck, send ghost to graveyard - player->RepopAtGraveyard(); - return true; - } - - // cast spell Stuck - player->CastSpell(player, 7355, false); - return true; - } - // Enable on\off all taxi paths - static bool HandleTaxiCheatCommand(ChatHandler* handler, char const* args) - { - if (!*args) - { - handler->SendSysMessage(LANG_USE_BOL); - handler->SetSentErrorMessage(true); - return false; - } - - std::string argStr = (char*)args; - - Player* chr = handler->getSelectedPlayer(); - - if (!chr) - chr = handler->GetSession()->GetPlayer(); - else if (handler->HasLowerSecurity(chr, 0)) // check online security - return false; - - if (argStr == "on") - { - chr->SetTaxiCheater(true); - handler->PSendSysMessage(LANG_YOU_GIVE_TAXIS, handler->GetNameLink(chr).c_str()); - if (handler->needReportToTarget(chr)) - ChatHandler(chr).PSendSysMessage(LANG_YOURS_TAXIS_ADDED, handler->GetNameLink().c_str()); - return true; - } - - if (argStr == "off") - { - chr->SetTaxiCheater(false); - handler->PSendSysMessage(LANG_YOU_REMOVE_TAXIS, handler->GetNameLink(chr).c_str()); - if (handler->needReportToTarget(chr)) - ChatHandler(chr).PSendSysMessage(LANG_YOURS_TAXIS_REMOVED, handler->GetNameLink().c_str()); - - return true; - } - - handler->SendSysMessage(LANG_USE_BOL); - handler->SetSentErrorMessage(true); - - return false; - } - - static bool HandleLinkGraveCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - char* px = strtok((char*)args, " "); - if (!px) - return false; - - uint32 graveyardId = uint32(atoi(px)); - - uint32 team; - - char* px2 = strtok(NULL, " "); - - if (!px2) - team = 0; - else if (strncmp(px2, "horde", 6) == 0) - team = HORDE; - else if (strncmp(px2, "alliance", 9) == 0) - team = ALLIANCE; - else - return false; - - WorldSafeLocsEntry const* graveyard = sWorldSafeLocsStore.LookupEntry(graveyardId); - - if (!graveyard) - { - handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST, graveyardId); - handler->SetSentErrorMessage(true); - return false; - } - - Player* player = handler->GetSession()->GetPlayer(); - - uint32 zoneId = player->GetZoneId(); - - AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(zoneId); - if (!areaEntry || areaEntry->zone !=0) - { - handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, graveyardId, zoneId); - handler->SetSentErrorMessage(true); - return false; - } - - if (sObjectMgr->AddGraveYardLink(graveyardId, zoneId, team)) - handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, graveyardId, zoneId); - else - handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, graveyardId, zoneId); - - return true; - } - - static bool HandleNearGraveCommand(ChatHandler* handler, char const* args) - { - uint32 team; - - size_t argStr = strlen(args); - - if (!*args) - team = 0; - else if (strncmp((char*)args, "horde", argStr) == 0) - team = HORDE; - else if (strncmp((char*)args, "alliance", argStr) == 0) - team = ALLIANCE; - else - return false; - - Player* player = handler->GetSession()->GetPlayer(); - uint32 zone_id = player->GetZoneId(); - - WorldSafeLocsEntry const* graveyard = sObjectMgr->GetClosestGraveYard( - player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), team); - - if (graveyard) - { - uint32 graveyardId = graveyard->ID; - - GraveYardData const* data = sObjectMgr->FindGraveYardData(graveyardId, zone_id); - if (!data) - { - handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR, graveyardId); - handler->SetSentErrorMessage(true); - return false; - } - - team = data->team; - - std::string team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_NOTEAM); - - if (team == 0) - team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_ANY); - else if (team == HORDE) - team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_HORDE); - else if (team == ALLIANCE) - team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_ALLIANCE); - - handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, graveyardId, team_name.c_str(), zone_id); - } - else - { - std::string team_name; - - if (team == 0) - team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_ANY); - else if (team == HORDE) - team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_HORDE); - else if (team == ALLIANCE) - team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_ALLIANCE); - - if (team == ~uint32(0)) - handler->PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, zone_id); - else - handler->PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, zone_id, team_name.c_str()); - } - - return true; - } - - static bool HandleExploreCheatCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - int32 flag = int32(atoi((char*)args)); - - Player* playerTarget = handler->getSelectedPlayer(); - if (!playerTarget) - { - handler->SendSysMessage(LANG_NO_CHAR_SELECTED); - handler->SetSentErrorMessage(true); - return false; - } - - if (flag != 0) - { - handler->PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, handler->GetNameLink(playerTarget).c_str()); - if (handler->needReportToTarget(playerTarget)) - ChatHandler(playerTarget).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL, handler->GetNameLink().c_str()); - } - else - { - handler->PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, handler->GetNameLink(playerTarget).c_str()); - if (handler->needReportToTarget(playerTarget)) - ChatHandler(playerTarget).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING, handler->GetNameLink().c_str()); - } - - for (uint8 i = 0; i < PLAYER_EXPLORED_ZONES_SIZE; ++i) - { - if (flag != 0) - handler->GetSession()->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i, 0xFFFFFFFF); - else - handler->GetSession()->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i, 0); - } - - return true; - } - - static bool HandleShowAreaCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - Player* playerTarget = handler->getSelectedPlayer(); - if (!playerTarget) - { - handler->SendSysMessage(LANG_NO_CHAR_SELECTED); - handler->SetSentErrorMessage(true); - return false; - } - - int32 area = GetAreaFlagByAreaID(atoi((char*)args)); - int32 offset = area / 32; - uint32 val = uint32((1 << (area % 32))); - - if (area<0 || offset >= PLAYER_EXPLORED_ZONES_SIZE) - { - handler->SendSysMessage(LANG_BAD_VALUE); - handler->SetSentErrorMessage(true); - return false; - } - - uint32 currFields = playerTarget->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset); - playerTarget->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, uint32((currFields | val))); - - handler->SendSysMessage(LANG_EXPLORE_AREA); - return true; - } - - static bool HandleHideAreaCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - Player* playerTarget = handler->getSelectedPlayer(); - if (!playerTarget) - { - handler->SendSysMessage(LANG_NO_CHAR_SELECTED); - handler->SetSentErrorMessage(true); - return false; - } - - int32 area = GetAreaFlagByAreaID(atoi((char*)args)); - int32 offset = area / 32; - uint32 val = uint32((1 << (area % 32))); - - if (area < 0 || offset >= PLAYER_EXPLORED_ZONES_SIZE) - { - handler->SendSysMessage(LANG_BAD_VALUE); - handler->SetSentErrorMessage(true); - return false; - } - - uint32 currFields = playerTarget->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset); - playerTarget->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, uint32((currFields ^ val))); - - handler->SendSysMessage(LANG_UNEXPLORE_AREA); - return true; - } - - static bool HandleAddItemCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - uint32 itemId = 0; - - if (args[0] == '[') // [name] manual form - { - char const* itemNameStr = strtok((char*)args, "]"); - - if (itemNameStr && itemNameStr[0]) - { - std::string itemName = itemNameStr+1; - WorldDatabase.EscapeString(itemName); - - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_ITEM_TEMPLATE_BY_NAME); - stmt->setString(0, itemName); - PreparedQueryResult result = WorldDatabase.Query(stmt); - - if (!result) - { - handler->PSendSysMessage(LANG_COMMAND_COULDNOTFIND, itemNameStr+1); - handler->SetSentErrorMessage(true); - return false; - } - itemId = result->Fetch()->GetUInt32(); - } - else - return false; - } - else // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r - { - char const* id = handler->extractKeyFromLink((char*)args, "Hitem"); - if (!id) - return false; - itemId = uint32(atol(id)); - } - - char const* ccount = strtok(NULL, " "); - - int32 count = 1; - - if (ccount) - count = strtol(ccount, NULL, 10); - - if (count == 0) - count = 1; - - Player* player = handler->GetSession()->GetPlayer(); - Player* playerTarget = handler->getSelectedPlayer(); - if (!playerTarget) - playerTarget = player; - - sLog->outDebug(LOG_FILTER_GENERAL, handler->GetTrinityString(LANG_ADDITEM), itemId, count); - - ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemId); - if (!itemTemplate) - { - handler->PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId); - handler->SetSentErrorMessage(true); - return false; - } - - // Subtract - if (count < 0) - { - playerTarget->DestroyItemCount(itemId, -count, true, false); - handler->PSendSysMessage(LANG_REMOVEITEM, itemId, -count, handler->GetNameLink(playerTarget).c_str()); - return true; - } - - // Adding items - uint32 noSpaceForCount = 0; - - // check space and find places - ItemPosCountVec dest; - InventoryResult msg = playerTarget->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount); - if (msg != EQUIP_ERR_OK) // convert to possible store amount - count -= noSpaceForCount; - - if (count == 0 || dest.empty()) // can't add any - { - handler->PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount); - handler->SetSentErrorMessage(true); - return false; - } - - Item* item = playerTarget->StoreNewItem(dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId)); - - // remove binding (let GM give it to another player later) - if (player == playerTarget) - for (ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr) - if (Item* item1 = player->GetItemByPos(itr->pos)) - item1->SetBinding(false); - - if (count > 0 && item) - { - player->SendNewItem(item, count, false, true); - if (player != playerTarget) - playerTarget->SendNewItem(item, count, true, false); - } - - if (noSpaceForCount > 0) - handler->PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount); - - return true; - } - - static bool HandleAddItemSetCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - char const* id = handler->extractKeyFromLink((char*)args, "Hitemset"); // number or [name] Shift-click form |color|Hitemset:itemset_id|h[name]|h|r - if (!id) - return false; - - uint32 itemSetId = atol(id); - - // prevent generation all items with itemset field value '0' - if (itemSetId == 0) - { - handler->PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND, itemSetId); - handler->SetSentErrorMessage(true); - return false; - } - - Player* player = handler->GetSession()->GetPlayer(); - Player* playerTarget = handler->getSelectedPlayer(); - if (!playerTarget) - playerTarget = player; - - sLog->outDebug(LOG_FILTER_GENERAL, handler->GetTrinityString(LANG_ADDITEMSET), itemSetId); - - bool found = false; - ItemTemplateContainer const* its = sObjectMgr->GetItemTemplateStore(); - for (ItemTemplateContainer::const_iterator itr = its->begin(); itr != its->end(); ++itr) - { - if (itr->second.ItemSet == itemSetId) - { - found = true; - ItemPosCountVec dest; - InventoryResult msg = playerTarget->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itr->second.ItemId, 1); - if (msg == EQUIP_ERR_OK) - { - Item* item = playerTarget->StoreNewItem(dest, itr->second.ItemId, true); - - // remove binding (let GM give it to another player later) - if (player == playerTarget) - item->SetBinding(false); - - player->SendNewItem(item, 1, false, true); - if (player != playerTarget) - playerTarget->SendNewItem(item, 1, true, false); - } - else - { - player->SendEquipError(msg, NULL, NULL, itr->second.ItemId); - handler->PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itr->second.ItemId, 1); - } - } - } - - if (!found) - { - handler->PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND, itemSetId); - handler->SetSentErrorMessage(true); - return false; - } - - return true; - } - - static bool HandleBankCommand(ChatHandler* handler, char const* /*args*/) - { - handler->GetSession()->SendShowBank(handler->GetSession()->GetPlayer()->GetGUID()); - return true; - } - - static bool HandleChangeWeather(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - // Weather is OFF - if (!sWorld->getBoolConfig(CONFIG_WEATHER)) - { - handler->SendSysMessage(LANG_WEATHER_DISABLED); - handler->SetSentErrorMessage(true); - return false; - } - - // *Change the weather of a cell - char const* px = strtok((char*)args, " "); - char const* py = strtok(NULL, " "); - - if (!px || !py) - return false; - - uint32 type = uint32(atoi(px)); //0 to 3, 0: fine, 1: rain, 2: snow, 3: sand - float grade = float(atof(py)); //0 to 1, sending -1 is instand good weather - - Player* player = handler->GetSession()->GetPlayer(); - uint32 zoneid = player->GetZoneId(); - - Weather* weather = WeatherMgr::FindWeather(zoneid); - - if (!weather) - weather = WeatherMgr::AddWeather(zoneid); - if (!weather) - { - handler->SendSysMessage(LANG_NO_WEATHER); - handler->SetSentErrorMessage(true); - return false; - } - - weather->SetWeather(WeatherType(type), grade); - - return true; - } - - - static bool HandleMaxSkillCommand(ChatHandler* handler, char const* /*args*/) - { - Player* SelectedPlayer = handler->getSelectedPlayer(); - if (!SelectedPlayer) - { - handler->SendSysMessage(LANG_NO_CHAR_SELECTED); - handler->SetSentErrorMessage(true); - return false; - } - - // each skills that have max skill value dependent from level seted to current level max skill value - SelectedPlayer->UpdateSkillsToMaxSkillsForLevel(); - return true; - } - - static bool HandleSetSkillCommand(ChatHandler* handler, char const* args) - { - // number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r - char const* skillStr = handler->extractKeyFromLink((char*)args, "Hskill"); - if (!skillStr) - return false; - - char const* levelStr = strtok(NULL, " "); - if (!levelStr) - return false; - - char const* maxPureSkill = strtok(NULL, " "); - - int32 skill = atoi(skillStr); - if (skill <= 0) - { - handler->PSendSysMessage(LANG_INVALID_SKILL_ID, skill); - handler->SetSentErrorMessage(true); - return false; - } - - int32 level = uint32(atol(levelStr)); - - Player* target = handler->getSelectedPlayer(); - if (!target) - { - handler->SendSysMessage(LANG_NO_CHAR_SELECTED); - handler->SetSentErrorMessage(true); - return false; - } - - SkillLineEntry const* skillLine = sSkillLineStore.LookupEntry(skill); - if (!skillLine) - { - handler->PSendSysMessage(LANG_INVALID_SKILL_ID, skill); - handler->SetSentErrorMessage(true); - return false; - } - - std::string tNameLink = handler->GetNameLink(target); - - if (!target->GetSkillValue(skill)) - { - handler->PSendSysMessage(LANG_SET_SKILL_ERROR, tNameLink.c_str(), skill, skillLine->name[handler->GetSessionDbcLocale()]); - handler->SetSentErrorMessage(true); - return false; - } - - uint16 max = maxPureSkill ? atol (maxPureSkill) : target->GetPureMaxSkillValue(skill); - - if (level <= 0 || level > max || max <= 0) - return false; - - target->SetSkill(skill, target->GetSkillStep(skill), level, max); - handler->PSendSysMessage(LANG_SET_SKILL, skill, skillLine->name[handler->GetSessionDbcLocale()], tNameLink.c_str(), level, max); - - return true; - } - // show info of player - static bool HandlePInfoCommand(ChatHandler* handler, char const* args) - { - Player* target; - uint64 targetGuid; - std::string targetName; - - uint32 parseGUID = MAKE_NEW_GUID(atol((char*)args), 0, HIGHGUID_PLAYER); - - if (sObjectMgr->GetPlayerNameByGUID(parseGUID, targetName)) - { - target = sObjectMgr->GetPlayerByLowGUID(parseGUID); - targetGuid = parseGUID; - } - else if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) - return false; - - uint32 accId = 0; - uint32 money = 0; - uint32 totalPlayerTime = 0; - uint8 level = 0; - uint32 latency = 0; - uint8 race; - uint8 Class; - int64 muteTime = 0; - int64 banTime = -1; - uint32 mapId; - uint32 areaId; - uint32 phase = 0; - - // get additional information from Player object - if (target) - { - // check online security - if (handler->HasLowerSecurity(target, 0)) - return false; - - accId = target->GetSession()->GetAccountId(); - money = target->GetMoney(); - totalPlayerTime = target->GetTotalPlayedTime(); - level = target->getLevel(); - latency = target->GetSession()->GetLatency(); - race = target->getRace(); - Class = target->getClass(); - muteTime = target->GetSession()->m_muteTime; - mapId = target->GetMapId(); - areaId = target->GetAreaId(); - phase = target->GetPhaseMask(); - } - // get additional information from DB - else - { - // check offline security - if (handler->HasLowerSecurity(NULL, targetGuid)) - return false; - - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PINFO); - stmt->setUInt32(0, GUID_LOPART(targetGuid)); - PreparedQueryResult result = CharacterDatabase.Query(stmt); - - if (!result) - return false; - - Field* fields = result->Fetch(); - totalPlayerTime = fields[0].GetUInt32(); - level = fields[1].GetUInt8(); - money = fields[2].GetUInt32(); - accId = fields[3].GetUInt32(); - race = fields[4].GetUInt8(); - Class = fields[5].GetUInt8(); - mapId = fields[6].GetUInt16(); - areaId = fields[7].GetUInt16(); - } - - std::string userName = handler->GetTrinityString(LANG_ERROR); - std::string eMail = handler->GetTrinityString(LANG_ERROR); - std::string lastIp = handler->GetTrinityString(LANG_ERROR); - uint32 security = 0; - std::string lastLogin = handler->GetTrinityString(LANG_ERROR); - - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO); - stmt->setInt32(0, int32(realmID)); - stmt->setUInt32(1, accId); - PreparedQueryResult result = LoginDatabase.Query(stmt); - - if (result) - { - Field* fields = result->Fetch(); - userName = fields[0].GetString(); - security = fields[1].GetUInt8(); - eMail = fields[2].GetString(); - muteTime = fields[5].GetUInt64(); - - if (eMail.empty()) - eMail = "-"; - - if (!handler->GetSession() || handler->GetSession()->GetSecurity() >= AccountTypes(security)) - { - lastIp = fields[3].GetString(); - lastLogin = fields[4].GetString(); - - uint32 ip = inet_addr(lastIp.c_str()); -#if TRINITY_ENDIAN == BIGENDIAN - EndianConvertReverse(ip); -#endif - - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_IP2NATION_COUNTRY); - - stmt->setUInt32(0, ip); - - PreparedQueryResult result2 = WorldDatabase.Query(stmt); - - if (result2) - { - Field* fields2 = result2->Fetch(); - lastIp.append(" ("); - lastIp.append(fields2[0].GetString()); - lastIp.append(")"); - } - } - else - { - lastIp = "-"; - lastLogin = "-"; - } - } - - std::string nameLink = handler->playerLink(targetName); - - handler->PSendSysMessage(LANG_PINFO_ACCOUNT, (target ? "" : handler->GetTrinityString(LANG_OFFLINE)), nameLink.c_str(), GUID_LOPART(targetGuid), userName.c_str(), accId, eMail.c_str(), security, lastIp.c_str(), lastLogin.c_str(), latency); - - std::string bannedby = "unknown"; - std::string banreason = ""; - - stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO_BANS); - stmt->setUInt32(0, accId); - PreparedQueryResult result2 = LoginDatabase.Query(stmt); - if (!result2) - { - stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PINFO_BANS); - stmt->setUInt32(0, GUID_LOPART(targetGuid)); - result2 = CharacterDatabase.Query(stmt); - } - - if (result2) - { - Field* fields = result2->Fetch(); - banTime = int64(fields[1].GetBool() ? 0 : fields[0].GetUInt32()); - bannedby = fields[2].GetString(); - banreason = fields[3].GetString(); - } - - if (muteTime > 0) - handler->PSendSysMessage(LANG_PINFO_MUTE, secsToTimeString(muteTime - time(NULL), true).c_str()); - - if (banTime >= 0) - handler->PSendSysMessage(LANG_PINFO_BAN, banTime > 0 ? secsToTimeString(banTime - time(NULL), true).c_str() : "permanently", bannedby.c_str(), banreason.c_str()); - - std::string raceStr, ClassStr; - switch (race) - { - case RACE_HUMAN: - raceStr = "Human"; - break; - case RACE_ORC: - raceStr = "Orc"; - break; - case RACE_DWARF: - raceStr = "Dwarf"; - break; - case RACE_NIGHTELF: - raceStr = "Night Elf"; - break; - case RACE_UNDEAD_PLAYER: - raceStr = "Undead"; - break; - case RACE_TAUREN: - raceStr = "Tauren"; - break; - case RACE_GNOME: - raceStr = "Gnome"; - break; - case RACE_TROLL: - raceStr = "Troll"; - break; - case RACE_BLOODELF: - raceStr = "Blood Elf"; - break; - case RACE_DRAENEI: - raceStr = "Draenei"; - break; - } - - switch (Class) - { - case CLASS_WARRIOR: - ClassStr = "Warrior"; - break; - case CLASS_PALADIN: - ClassStr = "Paladin"; - break; - case CLASS_HUNTER: - ClassStr = "Hunter"; - break; - case CLASS_ROGUE: - ClassStr = "Rogue"; - break; - case CLASS_PRIEST: - ClassStr = "Priest"; - break; - case CLASS_DEATH_KNIGHT: - ClassStr = "Death Knight"; - break; - case CLASS_SHAMAN: - ClassStr = "Shaman"; - break; - case CLASS_MAGE: - ClassStr = "Mage"; - break; - case CLASS_WARLOCK: - ClassStr = "Warlock"; - break; - case CLASS_DRUID: - ClassStr = "Druid"; - break; - } - - std::string timeStr = secsToTimeString(totalPlayerTime, true, true); - uint32 gold = money /GOLD; - uint32 silv = (money % GOLD) / SILVER; - uint32 copp = (money % GOLD) % SILVER; - handler->PSendSysMessage(LANG_PINFO_LEVEL, raceStr.c_str(), ClassStr.c_str(), timeStr.c_str(), level, gold, silv, copp); - - // Add map, zone, subzone and phase to output - int locale = handler->GetSessionDbcLocale(); - std::string areaName = ""; - std::string zoneName = ""; - - MapEntry const* map = sMapStore.LookupEntry(mapId); - - AreaTableEntry const* area = GetAreaEntryByAreaID(areaId); - if (area) - { - areaName = area->area_name[locale]; - - AreaTableEntry const* zone = GetAreaEntryByAreaID(area->zone); - if (zone) - zoneName = zone->area_name[locale]; - } - - if (target) - { - if (!zoneName.empty()) - handler->PSendSysMessage(LANG_PINFO_MAP_ONLINE, map->name[locale], zoneName.c_str(), areaName.c_str(), phase); - else - handler->PSendSysMessage(LANG_PINFO_MAP_ONLINE, map->name[locale], areaName.c_str(), "", phase); - } - else - handler->PSendSysMessage(LANG_PINFO_MAP_OFFLINE, map->name[locale], areaName.c_str()); - - return true; - } - - static bool HandleRespawnCommand(ChatHandler* handler, char const* /*args*/) - { - Player* player = handler->GetSession()->GetPlayer(); - - // accept only explicitly selected target (not implicitly self targeting case) - Unit* target = handler->getSelectedUnit(); - if (player->GetSelection() && target) - { - if (target->GetTypeId() != TYPEID_UNIT || target->isPet()) - { - handler->SendSysMessage(LANG_SELECT_CREATURE); - handler->SetSentErrorMessage(true); - return false; - } - - if (target->isDead()) - target->ToCreature()->Respawn(); - return true; - } - - CellCoord p(Trinity::ComputeCellCoord(player->GetPositionX(), player->GetPositionY())); - Cell cell(p); - cell.SetNoCreate(); - - Trinity::RespawnDo u_do; - Trinity::WorldObjectWorker worker(player, u_do); - - TypeContainerVisitor, GridTypeMapContainer > obj_worker(worker); - cell.Visit(p, obj_worker, *player->GetMap(), *player, player->GetGridActivationRange()); - - return true; - } - // mute player for some times - static bool HandleMuteCommand(ChatHandler* handler, char const* args) - { - char* nameStr; - char* delayStr; - handler->extractOptFirstArg((char*)args, &nameStr, &delayStr); - if (!delayStr) - return false; - - char const* muteReason = strtok(NULL, "\r"); - std::string muteReasonStr = "No reason"; - if (muteReason != NULL) - muteReasonStr = muteReason; - - Player* target; - uint64 targetGuid; - std::string targetName; - if (!handler->extractPlayerTarget(nameStr, &target, &targetGuid, &targetName)) - return false; - - uint32 accountId = target ? target->GetSession()->GetAccountId() : sObjectMgr->GetPlayerAccountIdByGUID(targetGuid); - - // find only player from same account if any - if (!target) - if (WorldSession* session = sWorld->FindSession(accountId)) - target = session->GetPlayer(); - - uint32 notSpeakTime = uint32(atoi(delayStr)); - - // must have strong lesser security level - if (handler->HasLowerSecurity (target, targetGuid, true)) - return false; - - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME); - - if (target) - { - // Target is online, mute will be in effect right away. - int64 muteTime = time(NULL) + notSpeakTime * MINUTE; - target->GetSession()->m_muteTime = muteTime; - stmt->setInt64(0, muteTime); - ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notSpeakTime, muteReasonStr.c_str()); - } - else - { - // Target is offline, mute will be in effect starting from the next login. - int32 muteTime = -int32(notSpeakTime * MINUTE); - stmt->setInt64(0, muteTime); - } - - stmt->setUInt32(1, accountId); - LoginDatabase.Execute(stmt); - std::string nameLink = handler->playerLink(targetName); - - handler->PSendSysMessage(target ? LANG_YOU_DISABLE_CHAT : LANG_COMMAND_DISABLE_CHAT_DELAYED, nameLink.c_str(), notSpeakTime, muteReasonStr.c_str()); - - return true; - } - - // unmute player - static bool HandleUnmuteCommand(ChatHandler* handler, char const* args) - { - Player* target; - uint64 targetGuid; - std::string targetName; - if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) - return false; - - uint32 accountId = target ? target->GetSession()->GetAccountId() : sObjectMgr->GetPlayerAccountIdByGUID(targetGuid); - - // find only player from same account if any - if (!target) - if (WorldSession* session = sWorld->FindSession(accountId)) - target = session->GetPlayer(); - - // must have strong lesser security level - if (handler->HasLowerSecurity (target, targetGuid, true)) - return false; - - if (target) - { - if (target->CanSpeak()) - { - handler->SendSysMessage(LANG_CHAT_ALREADY_ENABLED); - handler->SetSentErrorMessage(true); - return false; - } - - target->GetSession()->m_muteTime = 0; - } - - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME); - stmt->setInt64(0, 0); - stmt->setUInt32(1, accountId); - LoginDatabase.Execute(stmt); - - if (target) - ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_ENABLED); - - std::string nameLink = handler->playerLink(targetName); - - handler->PSendSysMessage(LANG_YOU_ENABLE_CHAT, nameLink.c_str()); - - return true; - } - - - static bool HandleMovegensCommand(ChatHandler* handler, char const* /*args*/) - { - Unit* unit = handler->getSelectedUnit(); - if (!unit) - { - handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - handler->SetSentErrorMessage(true); - return false; - } - - handler->PSendSysMessage(LANG_MOVEGENS_LIST, (unit->GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature"), unit->GetGUIDLow()); - - MotionMaster* motionMaster = unit->GetMotionMaster(); - float x, y, z; - motionMaster->GetDestination(x, y, z); - - for (uint8 i = 0; i < MAX_MOTION_SLOT; ++i) - { - MovementGenerator* movementGenerator = motionMaster->GetMotionSlot(i); - if (!movementGenerator) - { - handler->SendSysMessage("Empty"); - continue; - } - - switch (movementGenerator->GetMovementGeneratorType()) - { - case IDLE_MOTION_TYPE: - handler->SendSysMessage(LANG_MOVEGENS_IDLE); - break; - case RANDOM_MOTION_TYPE: - handler->SendSysMessage(LANG_MOVEGENS_RANDOM); - break; - case WAYPOINT_MOTION_TYPE: - handler->SendSysMessage(LANG_MOVEGENS_WAYPOINT); - break; - case ANIMAL_RANDOM_MOTION_TYPE: - handler->SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM); - break; - case CONFUSED_MOTION_TYPE: - handler->SendSysMessage(LANG_MOVEGENS_CONFUSED); - break; - case CHASE_MOTION_TYPE: - { - Unit* target = NULL; - if (unit->GetTypeId() == TYPEID_PLAYER) - target = static_cast const*>(movementGenerator)->GetTarget(); - else - target = static_cast const*>(movementGenerator)->GetTarget(); - - if (!target) - handler->SendSysMessage(LANG_MOVEGENS_CHASE_NULL); - else if (target->GetTypeId() == TYPEID_PLAYER) - handler->PSendSysMessage(LANG_MOVEGENS_CHASE_PLAYER, target->GetName(), target->GetGUIDLow()); - else - handler->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 const*>(movementGenerator)->GetTarget(); - else - target = static_cast const*>(movementGenerator)->GetTarget(); - - if (!target) - handler->SendSysMessage(LANG_MOVEGENS_FOLLOW_NULL); - else if (target->GetTypeId() == TYPEID_PLAYER) - handler->PSendSysMessage(LANG_MOVEGENS_FOLLOW_PLAYER, target->GetName(), target->GetGUIDLow()); - else - handler->PSendSysMessage(LANG_MOVEGENS_FOLLOW_CREATURE, target->GetName(), target->GetGUIDLow()); - break; - } - case HOME_MOTION_TYPE: - { - if (unit->GetTypeId() == TYPEID_UNIT) - handler->PSendSysMessage(LANG_MOVEGENS_HOME_CREATURE, x, y, z); - else - handler->SendSysMessage(LANG_MOVEGENS_HOME_PLAYER); - break; - } - case FLIGHT_MOTION_TYPE: - handler->SendSysMessage(LANG_MOVEGENS_FLIGHT); - break; - case POINT_MOTION_TYPE: - { - handler->PSendSysMessage(LANG_MOVEGENS_POINT, x, y, z); - break; - } - case FLEEING_MOTION_TYPE: - handler->SendSysMessage(LANG_MOVEGENS_FEAR); - break; - case DISTRACT_MOTION_TYPE: - handler->SendSysMessage(LANG_MOVEGENS_DISTRACT); - break; - case EFFECT_MOTION_TYPE: - handler->SendSysMessage(LANG_MOVEGENS_EFFECT); - break; - default: - handler->PSendSysMessage(LANG_MOVEGENS_UNKNOWN, movementGenerator->GetMovementGeneratorType()); - break; - } - } - return true; - } - /* - ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator - Without this function 3rd party scripting library will get linking errors (unresolved external) - when attempting to use the PointMovementGenerator - */ - static bool HandleComeToMeCommand(ChatHandler* handler, char const* args) - { - char const* newFlagStr = strtok((char*)args, " "); - if (!newFlagStr) - return false; - - Creature* caster = handler->getSelectedCreature(); - if (!caster) - { - handler->SendSysMessage(LANG_SELECT_CREATURE); - handler->SetSentErrorMessage(true); - return false; - } - - Player* player = handler->GetSession()->GetPlayer(); - - caster->GetMotionMaster()->MovePoint(0, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()); - - return true; - } - - static bool HandleDamageCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - Unit* target = handler->getSelectedUnit(); - if (!target || !handler->GetSession()->GetPlayer()->GetSelection()) - { - handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - handler->SetSentErrorMessage(true); - return false; - } - - if (target->GetTypeId() == TYPEID_PLAYER) - { - if (handler->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) - { - handler->GetSession()->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - if (target != handler->GetSession()->GetPlayer()) - handler->GetSession()->GetPlayer()->SendAttackStateUpdate (HITINFO_AFFECTS_VICTIM, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_HIT, 0); - return true; - } - - 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 = handler->GetSession()->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; - - handler->GetSession()->GetPlayer()->CalcAbsorbResist(target, schoolmask, SPELL_DIRECT_DAMAGE, damage, &absorb, &resist); - - if (damage <= absorb + resist) - return true; - - damage -= absorb + resist; - - handler->GetSession()->GetPlayer()->DealDamageMods(target, damage, &absorb); - handler->GetSession()->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false); - handler->GetSession()->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 = handler->extractSpellIdFromLink((char*)args); - if (!spellid || !sSpellMgr->GetSpellInfo(spellid)) - return false; - - handler->GetSession()->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage); - return true; - } - - static bool HandleCombatStopCommand(ChatHandler* handler, char const* args) - { - Player* target = NULL; - - if (args && strlen(args) > 0) - { - target = sObjectAccessor->FindPlayerByName(args); - if (!target) - { - handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); - handler->SetSentErrorMessage(true); - return false; - } - } - - if (!target) - { - if (!handler->extractPlayerTarget((char*)args, &target)) - return false; - } - - // check online security - if (handler->HasLowerSecurity(target, 0)) - return false; - - target->CombatStop(); - target->getHostileRefManager().deleteReferences(); - return true; - } - - static bool HandleFlushArenaPointsCommand(ChatHandler* /*handler*/, char const* /*args*/) - { - sArenaTeamMgr->DistributeArenaPoints(); - return true; - } - - static bool HandleRepairitemsCommand(ChatHandler* handler, char const* args) - { - Player* target; - if (!handler->extractPlayerTarget((char*)args, &target)) - return false; - - // check online security - if (handler->HasLowerSecurity(target, 0)) - return false; - - // Repair items - target->DurabilityRepairAll(false, 0, false); - - handler->PSendSysMessage(LANG_YOU_REPAIR_ITEMS, handler->GetNameLink(target).c_str()); - if (handler->needReportToTarget(target)) - ChatHandler(target).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED, handler->GetNameLink().c_str()); - - return true; - } - - static bool HandleWaterwalkCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - Player* player = handler->getSelectedPlayer(); - if (!player) - { - handler->PSendSysMessage(LANG_NO_CHAR_SELECTED); - handler->SetSentErrorMessage(true); - return false; - } - - // check online security - if (handler->HasLowerSecurity(player, 0)) - return false; - - if (strncmp(args, "on", 3) == 0) - player->SetMovement(MOVE_WATER_WALK); // ON - else if (strncmp(args, "off", 4) == 0) - player->SetMovement(MOVE_LAND_WALK); // OFF - else - { - handler->SendSysMessage(LANG_USE_BOL); - return false; - } - - handler->PSendSysMessage(LANG_YOU_SET_WATERWALK, args, handler->GetNameLink(player).c_str()); - if (handler->needReportToTarget(player)) - ChatHandler(player).PSendSysMessage(LANG_YOUR_WATERWALK_SET, args, handler->GetNameLink().c_str()); - return true; - } - - // Send mail by command - static bool HandleSendMailCommand(ChatHandler* handler, char const* args) - { - // format: name "subject text" "mail text" - Player* target; - uint64 targetGuid; - std::string targetName; - if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) - return false; - - char* tail1 = strtok(NULL, ""); - if (!tail1) - return false; - - char const* msgSubject = handler->extractQuotedArg(tail1); - if (!msgSubject) - return false; - - char* tail2 = strtok(NULL, ""); - if (!tail2) - return false; - - char const* msgText = handler->extractQuotedArg(tail2); - if (!msgText) - return false; - - // msgSubject, msgText isn't NUL after prev. check - std::string subject = msgSubject; - std::string text = msgText; - - // from console show not existed sender - MailSender sender(MAIL_NORMAL, handler->GetSession() ? handler->GetSession()->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM); - - //- TODO: Fix poor design - SQLTransaction trans = CharacterDatabase.BeginTransaction(); - MailDraft(subject, text) - .SendMailTo(trans, MailReceiver(target, GUID_LOPART(targetGuid)), sender); - - CharacterDatabase.CommitTransaction(trans); - - std::string nameLink = handler->playerLink(targetName); - handler->PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); - return true; - } - // Send items by mail - static bool HandleSendItemsCommand(ChatHandler* handler, char const* args) - { - // format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12] - Player* receiver; - uint64 receiverGuid; - std::string receiverName; - if (!handler->extractPlayerTarget((char*)args, &receiver, &receiverGuid, &receiverName)) - return false; - - char* tail1 = strtok(NULL, ""); - if (!tail1) - return false; - - char const* msgSubject = handler->extractQuotedArg(tail1); - if (!msgSubject) - return false; - - char* tail2 = strtok(NULL, ""); - if (!tail2) - return false; - - char const* msgText = handler->extractQuotedArg(tail2); - if (!msgText) - return false; - - // msgSubject, msgText isn't NUL after prev. check - std::string subject = msgSubject; - std::string text = msgText; - - // extract items - typedef std::pair ItemPair; - typedef std::list< ItemPair > ItemPairs; - ItemPairs items; - - // get all tail string - char* tail = strtok(NULL, ""); - - // get from tail next item str - while (char* itemStr = strtok(tail, " ")) - { - // and get new tail - tail = strtok(NULL, ""); - - // parse item str - char const* itemIdStr = strtok(itemStr, ":"); - char const* itemCountStr = strtok(NULL, " "); - - uint32 itemId = atoi(itemIdStr); - if (!itemId) - return false; - - ItemTemplate const* item_proto = sObjectMgr->GetItemTemplate(itemId); - if (!item_proto) - { - handler->PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId); - handler->SetSentErrorMessage(true); - return false; - } - - uint32 itemCount = itemCountStr ? atoi(itemCountStr) : 1; - if (itemCount < 1 || (item_proto->MaxCount > 0 && itemCount > uint32(item_proto->MaxCount))) - { - handler->PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, itemCount, itemId); - handler->SetSentErrorMessage(true); - return false; - } - - while (itemCount > item_proto->GetMaxStackSize()) - { - items.push_back(ItemPair(itemId, item_proto->GetMaxStackSize())); - itemCount -= item_proto->GetMaxStackSize(); - } - - items.push_back(ItemPair(itemId, itemCount)); - - if (items.size() > MAX_MAIL_ITEMS) - { - handler->PSendSysMessage(LANG_COMMAND_MAIL_ITEMS_LIMIT, MAX_MAIL_ITEMS); - handler->SetSentErrorMessage(true); - return false; - } - } - - // from console show not existed sender - MailSender sender(MAIL_NORMAL, handler->GetSession() ? handler->GetSession()->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM); - - // fill mail - MailDraft draft(subject, text); - - SQLTransaction trans = CharacterDatabase.BeginTransaction(); - - for (ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr) - { - if (Item* item = Item::CreateItem(itr->first, itr->second, handler->GetSession() ? handler->GetSession()->GetPlayer() : 0)) - { - item->SaveToDB(trans); // save for prevent lost at next mail load, if send fail then item will deleted - draft.AddItem(item); - } - } - - draft.SendMailTo(trans, MailReceiver(receiver, GUID_LOPART(receiverGuid)), sender); - CharacterDatabase.CommitTransaction(trans); - - std::string nameLink = handler->playerLink(receiverName); - handler->PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); - return true; - } - /// Send money by mail - static bool HandleSendMoneyCommand(ChatHandler* handler, char const* args) - { - /// format: name "subject text" "mail text" money - - Player* receiver; - uint64 receiverGuid; - std::string receiverName; - if (!handler->extractPlayerTarget((char*)args, &receiver, &receiverGuid, &receiverName)) - return false; - - char* tail1 = strtok(NULL, ""); - if (!tail1) - return false; - - char* msgSubject = handler->extractQuotedArg(tail1); - if (!msgSubject) - return false; - - char* tail2 = strtok(NULL, ""); - if (!tail2) - return false; - - char* msgText = handler->extractQuotedArg(tail2); - if (!msgText) - return false; - - char* moneyStr = strtok(NULL, ""); - int32 money = moneyStr ? atoi(moneyStr) : 0; - if (money <= 0) - return false; - - // msgSubject, msgText isn't NUL after prev. check - std::string subject = msgSubject; - std::string text = msgText; - - // from console show not existed sender - MailSender sender(MAIL_NORMAL, handler->GetSession() ? handler->GetSession()->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM); - - SQLTransaction trans = CharacterDatabase.BeginTransaction(); - - MailDraft(subject, text) - .AddMoney(money) - .SendMailTo(trans, MailReceiver(receiver, GUID_LOPART(receiverGuid)), sender); - - CharacterDatabase.CommitTransaction(trans); - - std::string nameLink = handler->playerLink(receiverName); - handler->PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); - return true; - } - /// Send a message to a player in game - static bool HandleSendMessageCommand(ChatHandler* handler, char const* args) - { - /// - Find the player - Player* player; - if (!handler->extractPlayerTarget((char*)args, &player)) - return false; - - char* msgStr = strtok(NULL, ""); - if (!msgStr) - return false; - - ///- Check that he is not logging out. - if (player->GetSession()->isLogingOut()) - { - handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); - handler->SetSentErrorMessage(true); - return false; - } - - /// - Send the message - // Use SendAreaTriggerMessage for fastest delivery. - player->GetSession()->SendAreaTriggerMessage("%s", msgStr); - player->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r"); - - // Confirmation message - std::string nameLink = handler->GetNameLink(player); - handler->PSendSysMessage(LANG_SENDMESSAGE, nameLink.c_str(), msgStr); - - return true; - } - - static bool HandleCreatePetCommand(ChatHandler* handler, char const* /*args*/) - { - Player* player = handler->GetSession()->GetPlayer(); - Creature* creatureTarget = handler->getSelectedCreature(); - - if (!creatureTarget || creatureTarget->isPet() || creatureTarget->GetTypeId() == TYPEID_PLAYER) - { - handler->PSendSysMessage(LANG_SELECT_CREATURE); - handler->SetSentErrorMessage(true); - return false; - } - - CreatureTemplate const* creatrueTemplate = sObjectMgr->GetCreatureTemplate(creatureTarget->GetEntry()); - // Creatures with family 0 crashes the server - if (!creatrueTemplate->family) - { - handler->PSendSysMessage("This creature cannot be tamed. (family id: 0)."); - handler->SetSentErrorMessage(true); - return false; - } - - if (player->GetPetGUID()) - { - handler->PSendSysMessage("You already have a pet"); - handler->SetSentErrorMessage(true); - return false; - } - - // Everything looks OK, create new pet - Pet* pet = new Pet(player, HUNTER_PET); - if (!pet->CreateBaseAtCreature(creatureTarget)) - { - delete pet; - handler->PSendSysMessage("Error 1"); - return false; - } - - creatureTarget->setDeathState(JUST_DIED); - creatureTarget->RemoveCorpse(); - creatureTarget->SetHealth(0); // just for nice GM-mode view - - pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, player->GetGUID()); - pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, player->getFaction()); - - if (!pet->InitStatsForLevel(creatureTarget->getLevel())) - { - sLog->outError(LOG_FILTER_GENERAL, "InitStatsForLevel() in EffectTameCreature failed! Pet deleted."); - handler->PSendSysMessage("Error 2"); - delete pet; - return false; - } - - // prepare visual effect for levelup - pet->SetUInt32Value(UNIT_FIELD_LEVEL, creatureTarget->getLevel()-1); - - pet->GetCharmInfo()->SetPetNumber(sObjectMgr->GeneratePetNumber(), true); - // this enables pet details window (Shift+P) - pet->InitPetCreateSpells(); - pet->SetFullHealth(); - - pet->GetMap()->AddToMap(pet->ToCreature()); - - // visual effect for levelup - pet->SetUInt32Value(UNIT_FIELD_LEVEL, creatureTarget->getLevel()); - - player->SetMinion(pet, true); - pet->SavePetToDB(PET_SAVE_AS_CURRENT); - player->PetSpellInitialize(); - - return true; - } - - static bool HandlePetLearnCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - Player* player = handler->GetSession()->GetPlayer(); - Pet* pet = player->GetPet(); - - if (!pet) - { - handler->PSendSysMessage("You have no pet"); - handler->SetSentErrorMessage(true); - return false; - } - - uint32 spellId = handler->extractSpellIdFromLink((char*)args); - - if (!spellId || !sSpellMgr->GetSpellInfo(spellId)) - return false; - - // Check if pet already has it - if (pet->HasSpell(spellId)) - { - handler->PSendSysMessage("Pet already has spell: %u", spellId); - handler->SetSentErrorMessage(true); - return false; - } - - // Check if spell is valid - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); - if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo)) - { - handler->PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spellId); - handler->SetSentErrorMessage(true); - return false; - } - - pet->learnSpell(spellId); - - handler->PSendSysMessage("Pet has learned spell %u", spellId); - return true; - } - - static bool HandlePetUnlearnCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - Player* player = handler->GetSession()->GetPlayer(); - Pet* pet = player->GetPet(); - if (!pet) - { - handler->PSendSysMessage("You have no pet"); - handler->SetSentErrorMessage(true); - return false; - } - - uint32 spellId = handler->extractSpellIdFromLink((char*)args); - - if (pet->HasSpell(spellId)) - pet->removeSpell(spellId, false); - else - handler->PSendSysMessage("Pet doesn't have that spell"); - - return true; - } - - static bool HandleFreezeCommand(ChatHandler* handler, char const* args) - { - std::string name; - Player* player; - char const* TargetName = strtok((char*)args, " "); // get entered name - if (!TargetName) // if no name entered use target - { - player = handler->getSelectedPlayer(); - if (player) //prevent crash with creature as target - { - name = player->GetName(); - normalizePlayerName(name); - } - } - else // if name entered - { - name = TargetName; - normalizePlayerName(name); - player = sObjectAccessor->FindPlayerByName(name.c_str()); - } - - if (!player) - { - handler->SendSysMessage(LANG_COMMAND_FREEZE_WRONG); - return true; - } - - if (player == handler->GetSession()->GetPlayer()) - { - handler->SendSysMessage(LANG_COMMAND_FREEZE_ERROR); - return true; - } - - // effect - if (player && (player != handler->GetSession()->GetPlayer())) - { - handler->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); - } - } - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(9454)) - Aura::TryRefreshStackOrCreate(spellInfo, MAX_EFFECT_MASK, player, player); - - // save player - player->SaveToDB(); - } - - return true; - } - - static bool HandleUnFreezeCommand(ChatHandler* handler, char const*args) - { - std::string name; - Player* player; - char* targetName = strtok((char*)args, " "); // Get entered name - - if (targetName) - { - name = targetName; - normalizePlayerName(name); - player = sObjectAccessor->FindPlayerByName(name.c_str()); - } - else // If no name was entered - use target - { - player = handler->getSelectedPlayer(); - if (player) - name = player->GetName(); - } - - if (player) - { - handler->PSendSysMessage(LANG_COMMAND_UNFREEZE, name.c_str()); - - // Reset player faction + allow combat + allow duels - player->setFactionForRace(player->getRace()); - player->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - - // Remove Freeze spell (allowing movement and spells) - player->RemoveAurasDueToSpell(9454); - - // Save player - player->SaveToDB(); - } - else - { - 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) - { - handler->SendSysMessage(LANG_COMMAND_FREEZE_WRONG); - return true; - } - - // If player found: delete his freeze aura - Field* fields = result->Fetch(); - uint32 lowGuid = fields[0].GetUInt32(); - - stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_AURA_FROZEN); - stmt->setUInt32(0, lowGuid); - CharacterDatabase.Execute(stmt); - - handler->PSendSysMessage(LANG_COMMAND_UNFREEZE, name.c_str()); - return true; - } - else - { - handler->SendSysMessage(LANG_COMMAND_FREEZE_WRONG); - return true; - } - } - - return true; - } - - static bool HandleListFreezeCommand(ChatHandler* handler, char const* /*args*/) - { - // Get names from DB - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_AURA_FROZEN); - PreparedQueryResult result = CharacterDatabase.Query(stmt); - if (!result) - { - handler->SendSysMessage(LANG_COMMAND_NO_FROZEN_PLAYERS); - return true; - } - - // Header of the names - handler->PSendSysMessage(LANG_COMMAND_LIST_FREEZE); - - // Output of the results - do - { - Field* fields = result->Fetch(); - std::string player = fields[0].GetString(); - handler->PSendSysMessage(LANG_COMMAND_FROZEN_PLAYERS, player.c_str()); - } - while (result->NextRow()); - - return true; - } - - static bool HandleGroupLeaderCommand(ChatHandler* handler, char const* args) - { - Player* player = NULL; - Group* group = NULL; - uint64 guid = 0; - char* nameStr = strtok((char*)args, " "); - - if (handler->GetPlayerGroupAndGUIDByName(nameStr, player, group, guid)) - if (group && group->GetLeaderGUID() != guid) - { - group->ChangeLeader(guid); - group->SendUpdate(); - } - - return true; - } - - static bool HandleGroupDisbandCommand(ChatHandler* handler, char const* args) - { - Player* player = NULL; - Group* group = NULL; - uint64 guid = 0; - char* nameStr = strtok((char*)args, " "); - - if (handler->GetPlayerGroupAndGUIDByName(nameStr, player, group, guid)) - if (group) - group->Disband(); - - return true; - } - - static bool HandleGroupRemoveCommand(ChatHandler* handler, char const* args) - { - Player* player = NULL; - Group* group = NULL; - uint64 guid = 0; - char* nameStr = strtok((char*)args, " "); - - if (handler->GetPlayerGroupAndGUIDByName(nameStr, player, group, guid, true)) - if (group) - group->RemoveMember(guid); - - return true; - } - - static bool HandlePlayAllCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - uint32 soundId = atoi((char*)args); - - if (!sSoundEntriesStore.LookupEntry(soundId)) - { - handler->PSendSysMessage(LANG_SOUND_NOT_EXIST, soundId); - handler->SetSentErrorMessage(true); - return false; - } - - WorldPacket data(SMSG_PLAY_SOUND, 4); - data << uint32(soundId) << handler->GetSession()->GetPlayer()->GetGUID(); - sWorld->SendGlobalMessage(&data); - - handler->PSendSysMessage(LANG_COMMAND_PLAYED_TO_ALL, soundId); - return true; - } - - static bool HandlePossessCommand(ChatHandler* handler, char const* /*args*/) - { - Unit* unit = handler->getSelectedUnit(); - if (!unit) - return false; - - handler->GetSession()->GetPlayer()->CastSpell(unit, 530, true); - return true; - } - - static bool HandleUnPossessCommand(ChatHandler* handler, char const* /*args*/) - { - Unit* unit = handler->getSelectedUnit(); - if (!unit) - unit = handler->GetSession()->GetPlayer(); - - unit->RemoveCharmAuras(); - - return true; - } - - static bool HandleBindSightCommand(ChatHandler* handler, char const* /*args*/) - { - Unit* unit = handler->getSelectedUnit(); - if (!unit) - return false; - - handler->GetSession()->GetPlayer()->CastSpell(unit, 6277, true); - return true; - } - - static bool HandleUnbindSightCommand(ChatHandler* handler, char const* /*args*/) - { - Player* player = handler->GetSession()->GetPlayer(); - - if (player->isPossessing()) - return false; - - player->StopCastingBindSight(); - return true; - } -}; - -void AddSC_misc_commandscript() -{ - new misc_commandscript(); -} +/* + * Copyright (C) 2008-2012 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "Chat.h" +#include "ScriptMgr.h" +#include "AccountMgr.h" +#include "ArenaTeamMgr.h" +#include "CellImpl.h" +#include "GridNotifiers.h" +#include "Group.h" +#include "InstanceSaveMgr.h" +#include "MovementGenerator.h" +#include "ObjectAccessor.h" +#include "SpellAuras.h" +#include "TargetedMovementGenerator.h" +#include "WeatherMgr.h" +#include "ace/INET_Addr.h" + +class misc_commandscript : public CommandScript +{ +public: + misc_commandscript() : CommandScript("misc_commandscript") { } + + ChatCommand* GetCommands() const + { + static ChatCommand groupCommandTable[] = + { + { "leader", SEC_ADMINISTRATOR, false, &HandleGroupLeaderCommand, "", NULL }, + { "disband", SEC_ADMINISTRATOR, false, &HandleGroupDisbandCommand, "", NULL }, + { "remove", SEC_ADMINISTRATOR, false, &HandleGroupRemoveCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand petCommandTable[] = + { + { "create", SEC_GAMEMASTER, false, &HandleCreatePetCommand, "", NULL }, + { "learn", SEC_GAMEMASTER, false, &HandlePetLearnCommand, "", NULL }, + { "unlearn", SEC_GAMEMASTER, false, &HandlePetUnlearnCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand sendCommandTable[] = + { + { "items", SEC_ADMINISTRATOR, true, &HandleSendItemsCommand, "", NULL }, + { "mail", SEC_MODERATOR, true, &HandleSendMailCommand, "", NULL }, + { "message", SEC_ADMINISTRATOR, true, &HandleSendMessageCommand, "", NULL }, + { "money", SEC_ADMINISTRATOR, true, &HandleSendMoneyCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand commandTable[] = + { + { "dev", SEC_ADMINISTRATOR, false, &HandleDevCommand, "", NULL }, + { "gps", SEC_ADMINISTRATOR, false, &HandleGPSCommand, "", NULL }, + { "aura", SEC_ADMINISTRATOR, false, &HandleAuraCommand, "", NULL }, + { "unaura", SEC_ADMINISTRATOR, false, &HandleUnAuraCommand, "", NULL }, + { "appear", SEC_MODERATOR, false, &HandleAppearCommand, "", NULL }, + { "summon", SEC_MODERATOR, false, &HandleSummonCommand, "", NULL }, + { "groupsummon", SEC_MODERATOR, false, &HandleGroupSummonCommand, "", NULL }, + { "commands", SEC_PLAYER, true, &HandleCommandsCommand, "", NULL }, + { "die", SEC_ADMINISTRATOR, false, &HandleDieCommand, "", NULL }, + { "revive", SEC_ADMINISTRATOR, true, &HandleReviveCommand, "", NULL }, + { "dismount", SEC_PLAYER, false, &HandleDismountCommand, "", NULL }, + { "guid", SEC_GAMEMASTER, false, &HandleGUIDCommand, "", NULL }, + { "help", SEC_PLAYER, true, &HandleHelpCommand, "", NULL }, + { "itemmove", SEC_GAMEMASTER, false, &HandleItemMoveCommand, "", NULL }, + { "cooldown", SEC_ADMINISTRATOR, false, &HandleCooldownCommand, "", NULL }, + { "distance", SEC_ADMINISTRATOR, false, &HandleGetDistanceCommand, "", NULL }, + { "recall", SEC_MODERATOR, false, &HandleRecallCommand, "", NULL }, + { "save", SEC_PLAYER, false, &HandleSaveCommand, "", NULL }, + { "saveall", SEC_MODERATOR, true, &HandleSaveAllCommand, "", NULL }, + { "kick", SEC_GAMEMASTER, true, &HandleKickPlayerCommand, "", NULL }, + { "start", SEC_PLAYER, false, &HandleStartCommand, "", NULL }, + { "taxicheat", SEC_MODERATOR, false, &HandleTaxiCheatCommand, "", NULL }, + { "linkgrave", SEC_ADMINISTRATOR, false, &HandleLinkGraveCommand, "", NULL }, + { "neargrave", SEC_ADMINISTRATOR, false, &HandleNearGraveCommand, "", NULL }, + { "explorecheat", SEC_ADMINISTRATOR, false, &HandleExploreCheatCommand, "", NULL }, + { "showarea", SEC_ADMINISTRATOR, false, &HandleShowAreaCommand, "", NULL }, + { "hidearea", SEC_ADMINISTRATOR, false, &HandleHideAreaCommand, "", NULL }, + { "additem", SEC_ADMINISTRATOR, false, &HandleAddItemCommand, "", NULL }, + { "additemset", SEC_ADMINISTRATOR, false, &HandleAddItemSetCommand, "", NULL }, + { "bank", SEC_ADMINISTRATOR, false, &HandleBankCommand, "", NULL }, + { "wchange", SEC_ADMINISTRATOR, false, &HandleChangeWeather, "", NULL }, + { "maxskill", SEC_ADMINISTRATOR, false, &HandleMaxSkillCommand, "", NULL }, + { "setskill", SEC_ADMINISTRATOR, false, &HandleSetSkillCommand, "", NULL }, + { "pinfo", SEC_GAMEMASTER, true, &HandlePInfoCommand, "", NULL }, + { "respawn", SEC_ADMINISTRATOR, false, &HandleRespawnCommand, "", NULL }, + { "send", SEC_MODERATOR, true, NULL, "", sendCommandTable }, + { "pet", SEC_GAMEMASTER, false, NULL, "", petCommandTable }, + { "mute", SEC_MODERATOR, true, &HandleMuteCommand, "", NULL }, + { "unmute", SEC_MODERATOR, true, &HandleUnmuteCommand, "", NULL }, + { "movegens", SEC_ADMINISTRATOR, false, &HandleMovegensCommand, "", NULL }, + { "cometome", SEC_ADMINISTRATOR, false, &HandleComeToMeCommand, "", NULL }, + { "damage", SEC_ADMINISTRATOR, false, &HandleDamageCommand, "", NULL }, + { "combatstop", SEC_GAMEMASTER, true, &HandleCombatStopCommand, "", NULL }, + { "flusharenapoints", SEC_ADMINISTRATOR, false, &HandleFlushArenaPointsCommand, "", NULL }, + { "repairitems", SEC_GAMEMASTER, true, &HandleRepairitemsCommand, "", NULL }, + { "waterwalk", SEC_GAMEMASTER, false, &HandleWaterwalkCommand, "", NULL }, + { "freeze", SEC_MODERATOR, false, &HandleFreezeCommand, "", NULL }, + { "unfreeze", SEC_MODERATOR, false, &HandleUnFreezeCommand, "", NULL }, + { "listfreeze", SEC_MODERATOR, false, &HandleListFreezeCommand, "", NULL }, + { "group", SEC_ADMINISTRATOR, false, NULL, "", groupCommandTable }, + { "possess", SEC_ADMINISTRATOR, false, HandlePossessCommand, "", NULL }, + { "unpossess", SEC_ADMINISTRATOR, false, HandleUnPossessCommand, "", NULL }, + { "bindsight", SEC_ADMINISTRATOR, false, HandleBindSightCommand, "", NULL }, + { "unbindsight", SEC_ADMINISTRATOR, false, HandleUnbindSightCommand, "", NULL }, + { "playall", SEC_GAMEMASTER, false, HandlePlayAllCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + return commandTable; + } + + static bool HandleDevCommand(ChatHandler* handler, char const* args) + { + if (!*args) + { + if (handler->GetSession()->GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_DEVELOPER)) + handler->GetSession()->SendNotification(LANG_DEV_ON); + else + handler->GetSession()->SendNotification(LANG_DEV_OFF); + return true; + } + + std::string argstr = (char*)args; + + if (argstr == "on") + { + handler->GetSession()->GetPlayer()->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_DEVELOPER); + handler->GetSession()->SendNotification(LANG_DEV_ON); + return true; + } + + if (argstr == "off") + { + handler->GetSession()->GetPlayer()->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_DEVELOPER); + handler->GetSession()->SendNotification(LANG_DEV_OFF); + return true; + } + + handler->SendSysMessage(LANG_USE_BOL); + handler->SetSentErrorMessage(true); + return false; + } + + static bool HandleGPSCommand(ChatHandler* handler, char const* args) + { + WorldObject* object = NULL; + if (*args) + { + uint64 guid = handler->extractGuidFromLink((char*)args); + if (guid) + object = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*handler->GetSession()->GetPlayer(), guid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT); + + if (!object) + { + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + } + else + { + object = handler->getSelectedUnit(); + + if (!object) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + } + + CellCoord cellCoord = Trinity::ComputeCellCoord(object->GetPositionX(), object->GetPositionY()); + Cell cell(cellCoord); + + uint32 zoneId, areaId; + object->GetZoneAndAreaId(zoneId, areaId); + + MapEntry const* mapEntry = sMapStore.LookupEntry(object->GetMapId()); + AreaTableEntry const* zoneEntry = GetAreaEntryByAreaID(zoneId); + AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(areaId); + + float zoneX = object->GetPositionX(); + float zoneY = object->GetPositionY(); + + Map2ZoneCoordinates(zoneX, zoneY, zoneId); + + Map const* map = object->GetMap(); + float groundZ = map->GetHeight(object->GetPhaseMask(), object->GetPositionX(), object->GetPositionY(), MAX_HEIGHT); + float floorZ = map->GetHeight(object->GetPhaseMask(), object->GetPositionX(), object->GetPositionY(), object->GetPositionZ()); + + GridCoord gridCoord = Trinity::ComputeGridCoord(object->GetPositionX(), object->GetPositionY()); + + // 63? WHY? + int gridX = 63 - gridCoord.x_coord; + int gridY = 63 - gridCoord.y_coord; + + uint32 haveMap = Map::ExistMap(object->GetMapId(), gridX, gridY) ? 1 : 0; + uint32 haveVMap = Map::ExistVMap(object->GetMapId(), gridX, gridY) ? 1 : 0; + + if (haveVMap) + { + if (map->IsOutdoors(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ())) + handler->PSendSysMessage("You are outdoors"); + else + handler->PSendSysMessage("You are indoors"); + } + else + handler->PSendSysMessage("no VMAP available for area info"); + + handler->PSendSysMessage(LANG_MAP_POSITION, + object->GetMapId(), (mapEntry ? mapEntry->name[handler->GetSessionDbcLocale()] : ""), + zoneId, (zoneEntry ? zoneEntry->area_name[handler->GetSessionDbcLocale()] : ""), + areaId, (areaEntry ? areaEntry->area_name[handler->GetSessionDbcLocale()] : ""), + object->GetPhaseMask(), + object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), object->GetOrientation(), + cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), object->GetInstanceId(), + zoneX, zoneY, groundZ, floorZ, haveMap, haveVMap); + + LiquidData liquidStatus; + ZLiquidStatus status = map->getLiquidStatus(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), MAP_ALL_LIQUIDS, &liquidStatus); + + if (status) + handler->PSendSysMessage(LANG_LIQUID_STATUS, liquidStatus.level, liquidStatus.depth_level, liquidStatus.entry, liquidStatus.type_flags, status); + + return true; + } + + static bool HandleAuraCommand(ChatHandler* handler, char const* args) + { + Unit* target = handler->getSelectedUnit(); + if (!target) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spellId = handler->extractSpellIdFromLink((char*)args); + + if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId)) + Aura::TryRefreshStackOrCreate(spellInfo, MAX_EFFECT_MASK, target, target); + + return true; + } + + static bool HandleUnAuraCommand(ChatHandler* handler, char const* args) + { + Unit* target = handler->getSelectedUnit(); + if (!target) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + std::string argstr = args; + if (argstr == "all") + { + target->RemoveAllAuras(); + return true; + } + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spellId = handler->extractSpellIdFromLink((char*)args); + if (!spellId) + return false; + + target->RemoveAurasDueToSpell(spellId); + + return true; + } + // Teleport to Player + static bool HandleAppearCommand(ChatHandler* handler, char const* args) + { + Player* target; + uint64 targetGuid; + std::string targetName; + if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) + return false; + + Player* _player = handler->GetSession()->GetPlayer(); + if (target == _player || targetGuid == _player->GetGUID()) + { + handler->SendSysMessage(LANG_CANT_TELEPORT_SELF); + handler->SetSentErrorMessage(true); + return false; + } + + if (target) + { + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + std::string chrNameLink = handler->playerLink(targetName); + + Map* map = target->GetMap(); + if (map->IsBattlegroundOrArena()) + { + // only allow if gm mode is on + if (!_player->isGameMaster()) + { + handler->PSendSysMessage(LANG_CANNOT_GO_TO_BG_GM, chrNameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + // if both players are in different bgs + else if (_player->GetBattlegroundId() && _player->GetBattlegroundId() != target->GetBattlegroundId()) + _player->LeaveBattleground(false); // Note: should be changed so _player gets no Deserter debuff + + // all's well, set bg id + // when porting out from the bg, it will be reset to 0 + _player->SetBattlegroundId(target->GetBattlegroundId(), target->GetBattlegroundTypeId()); + // remember current position as entry point for return at bg end teleportation + if (!_player->GetMap()->IsBattlegroundOrArena()) + _player->SetBattlegroundEntryPoint(); + } + else if (map->IsDungeon()) + { + // we have to go to instance, and can go to player only if: + // 1) we are in his group (either as leader or as member) + // 2) we are not bound to any group and have GM mode on + if (_player->GetGroup()) + { + // we are in group, we can go only if we are in the player group + if (_player->GetGroup() != target->GetGroup()) + { + handler->PSendSysMessage(LANG_CANNOT_GO_TO_INST_PARTY, chrNameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + } + else + { + // we are not in group, let's verify our GM mode + if (!_player->isGameMaster()) + { + handler->PSendSysMessage(LANG_CANNOT_GO_TO_INST_GM, chrNameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + } + + // if the player or the player's group is bound to another instance + // the player will not be bound to another one + InstancePlayerBind* bind = _player->GetBoundInstance(target->GetMapId(), target->GetDifficulty(map->IsRaid())); + if (!bind) + { + Group* group = _player->GetGroup(); + // if no bind exists, create a solo bind + InstanceGroupBind* gBind = group ? group->GetBoundInstance(target) : NULL; // if no bind exists, create a solo bind + if (!gBind) + if (InstanceSave* save = sInstanceSaveMgr->GetInstanceSave(target->GetInstanceId())) + _player->BindToInstance(save, !save->CanReset()); + } + + if (map->IsRaid()) + _player->SetRaidDifficulty(target->GetRaidDifficulty()); + else + _player->SetDungeonDifficulty(target->GetDungeonDifficulty()); + } + + handler->PSendSysMessage(LANG_APPEARING_AT, chrNameLink.c_str()); + + // stop flight if need + if (_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->CleanupAfterTaxiFlight(); + } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + // to point to see at target with same orientation + float x, y, z; + target->GetContactPoint(_player, x, y, z); + + _player->TeleportTo(target->GetMapId(), x, y, z, _player->GetAngle(target), TELE_TO_GM_MODE); + _player->SetPhaseMask(target->GetPhaseMask(), true); + } + else + { + // check offline security + if (handler->HasLowerSecurity(NULL, targetGuid)) + return false; + + std::string nameLink = handler->playerLink(targetName); + + handler->PSendSysMessage(LANG_APPEARING_AT, nameLink.c_str()); + + // to point where player stay (if loaded) + float x, y, z, o; + uint32 map; + bool in_flight; + if (!Player::LoadPositionFromDB(map, x, y, z, o, in_flight, targetGuid)) + return false; + + // stop flight if need + if (_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->CleanupAfterTaxiFlight(); + } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + _player->TeleportTo(map, x, y, z, _player->GetOrientation()); + } + + return true; + } + // Summon Player + static bool HandleSummonCommand(ChatHandler* handler, char const* args) + { + Player* target; + uint64 targetGuid; + std::string targetName; + if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) + return false; + + Player* _player = handler->GetSession()->GetPlayer(); + if (target == _player || targetGuid == _player->GetGUID()) + { + handler->PSendSysMessage(LANG_CANT_TELEPORT_SELF); + handler->SetSentErrorMessage(true); + return false; + } + + if (target) + { + std::string nameLink = handler->playerLink(targetName); + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + if (target->IsBeingTeleported()) + { + handler->PSendSysMessage(LANG_IS_TELEPORTED, nameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + Map* map = handler->GetSession()->GetPlayer()->GetMap(); + + if (map->IsBattlegroundOrArena()) + { + // only allow if gm mode is on + if (!_player->isGameMaster()) + { + handler->PSendSysMessage(LANG_CANNOT_GO_TO_BG_GM, nameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + // if both players are in different bgs + else if (target->GetBattlegroundId() && handler->GetSession()->GetPlayer()->GetBattlegroundId() != target->GetBattlegroundId()) + target->LeaveBattleground(false); // Note: should be changed so target gets no Deserter debuff + + // all's well, set bg id + // when porting out from the bg, it will be reset to 0 + target->SetBattlegroundId(handler->GetSession()->GetPlayer()->GetBattlegroundId(), handler->GetSession()->GetPlayer()->GetBattlegroundTypeId()); + // remember current position as entry point for return at bg end teleportation + if (!target->GetMap()->IsBattlegroundOrArena()) + target->SetBattlegroundEntryPoint(); + } + else if (map->IsDungeon()) + { + Map* map = target->GetMap(); + + if (map->Instanceable() && map->GetInstanceId() != map->GetInstanceId()) + target->UnbindInstance(map->GetInstanceId(), target->GetDungeonDifficulty(), true); + + // we are in instance, and can summon only player in our group with us as lead + if (!handler->GetSession()->GetPlayer()->GetGroup() || !target->GetGroup() || + (target->GetGroup()->GetLeaderGUID() != handler->GetSession()->GetPlayer()->GetGUID()) || + (handler->GetSession()->GetPlayer()->GetGroup()->GetLeaderGUID() != handler->GetSession()->GetPlayer()->GetGUID())) + // the last check is a bit excessive, but let it be, just in case + { + handler->PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST, nameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + } + + handler->PSendSysMessage(LANG_SUMMONING, nameLink.c_str(), ""); + if (handler->needReportToTarget(target)) + ChatHandler(target).PSendSysMessage(LANG_SUMMONED_BY, handler->playerLink(_player->GetName()).c_str()); + + // stop flight if need + if (target->isInFlight()) + { + target->GetMotionMaster()->MovementExpired(); + target->CleanupAfterTaxiFlight(); + } + // save only in non-flight case + else + target->SaveRecallPosition(); + + // before GM + float x, y, z; + handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, target->GetObjectSize()); + target->TeleportTo(handler->GetSession()->GetPlayer()->GetMapId(), x, y, z, target->GetOrientation()); + target->SetPhaseMask(handler->GetSession()->GetPlayer()->GetPhaseMask(), true); + } + else + { + // check offline security + if (handler->HasLowerSecurity(NULL, targetGuid)) + return false; + + std::string nameLink = handler->playerLink(targetName); + + handler->PSendSysMessage(LANG_SUMMONING, nameLink.c_str(), handler->GetTrinityString(LANG_OFFLINE)); + + // in point where GM stay + Player::SavePositionInDB(handler->GetSession()->GetPlayer()->GetMapId(), + handler->GetSession()->GetPlayer()->GetPositionX(), + handler->GetSession()->GetPlayer()->GetPositionY(), + handler->GetSession()->GetPlayer()->GetPositionZ(), + handler->GetSession()->GetPlayer()->GetOrientation(), + handler->GetSession()->GetPlayer()->GetZoneId(), + targetGuid); + } + + return true; + } + // Summon group of player + static bool HandleGroupSummonCommand(ChatHandler* handler, char const* args) + { + Player* target; + if (!handler->extractPlayerTarget((char*)args, &target)) + return false; + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + Group* group = target->GetGroup(); + + std::string nameLink = handler->GetNameLink(target); + + if (!group) + { + handler->PSendSysMessage(LANG_NOT_IN_GROUP, nameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + Map* gmMap = handler->GetSession()->GetPlayer()->GetMap(); + bool toInstance = gmMap->Instanceable(); + + // we are in instance, and can summon only player in our group with us as lead + if (toInstance && ( + !handler->GetSession()->GetPlayer()->GetGroup() || (group->GetLeaderGUID() != handler->GetSession()->GetPlayer()->GetGUID()) || + (handler->GetSession()->GetPlayer()->GetGroup()->GetLeaderGUID() != handler->GetSession()->GetPlayer()->GetGUID()))) + // the last check is a bit excessive, but let it be, just in case + { + handler->SendSysMessage(LANG_CANNOT_SUMMON_TO_INST); + handler->SetSentErrorMessage(true); + return false; + } + + for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player* player = itr->getSource(); + + if (!player || player == handler->GetSession()->GetPlayer() || !player->GetSession()) + continue; + + // check online security + if (handler->HasLowerSecurity(player, 0)) + return false; + + std::string plNameLink = handler->GetNameLink(player); + + if (player->IsBeingTeleported() == true) + { + handler->PSendSysMessage(LANG_IS_TELEPORTED, plNameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + if (toInstance) + { + Map* playerMap = player->GetMap(); + + if (playerMap->Instanceable() && playerMap->GetInstanceId() != gmMap->GetInstanceId()) + { + // cannot summon from instance to instance + handler->PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST, plNameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + } + + handler->PSendSysMessage(LANG_SUMMONING, plNameLink.c_str(), ""); + if (handler->needReportToTarget(player)) + ChatHandler(player).PSendSysMessage(LANG_SUMMONED_BY, handler->GetNameLink().c_str()); + + // stop flight if need + if (player->isInFlight()) + { + player->GetMotionMaster()->MovementExpired(); + player->CleanupAfterTaxiFlight(); + } + // save only in non-flight case + else + player->SaveRecallPosition(); + + // before GM + float x, y, z; + handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, player->GetObjectSize()); + player->TeleportTo(handler->GetSession()->GetPlayer()->GetMapId(), x, y, z, player->GetOrientation()); + } + + return true; + } + + static bool HandleCommandsCommand(ChatHandler* handler, char const* /*args*/) + { + handler->ShowHelpForCommand(handler->getCommandTable(), ""); + return true; + } + + static bool HandleDieCommand(ChatHandler* handler, char const* /*args*/) + { + Unit* target = handler->getSelectedUnit(); + + if (!target || !handler->GetSession()->GetPlayer()->GetSelection()) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + if (target->GetTypeId() == TYPEID_PLAYER) + { + if (handler->HasLowerSecurity((Player*)target, 0, false)) + return false; + } + + if (target->isAlive()) + { + if (sWorld->getBoolConfig(CONFIG_DIE_COMMAND_MODE)) + handler->GetSession()->GetPlayer()->Kill(target); + else + handler->GetSession()->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + + return true; + } + + static bool HandleReviveCommand(ChatHandler* handler, char const* args) + { + Player* target; + uint64 targetGuid; + if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid)) + return false; + + if (target) + { + target->ResurrectPlayer(!AccountMgr::IsPlayerAccount(target->GetSession()->GetSecurity()) ? 1.0f : 0.5f); + target->SpawnCorpseBones(); + target->SaveToDB(); + } + else + // will resurrected at login without corpse + sObjectAccessor->ConvertCorpseForPlayer(targetGuid); + + return true; + } + + static bool HandleDismountCommand(ChatHandler* handler, char const* /*args*/) + { + Player* player = handler->GetSession()->GetPlayer(); + + // If player is not mounted, so go out :) + if (!player->IsMounted()) + { + handler->SendSysMessage(LANG_CHAR_NON_MOUNTED); + handler->SetSentErrorMessage(true); + return false; + } + + if (player->isInFlight()) + { + handler->SendSysMessage(LANG_YOU_IN_FLIGHT); + handler->SetSentErrorMessage(true); + return false; + } + + player->Dismount(); + player->RemoveAurasByType(SPELL_AURA_MOUNTED); + return true; + } + + static bool HandleGUIDCommand(ChatHandler* handler, char const* /*args*/) + { + uint64 guid = handler->GetSession()->GetPlayer()->GetSelection(); + + if (guid == 0) + { + handler->SendSysMessage(LANG_NO_SELECTION); + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage(LANG_OBJECT_GUID, GUID_LOPART(guid), GUID_HIPART(guid)); + return true; + } + + static bool HandleHelpCommand(ChatHandler* handler, char const* args) + { + char const* cmd = strtok((char*)args, " "); + if (!cmd) + { + handler->ShowHelpForCommand(handler->getCommandTable(), "help"); + handler->ShowHelpForCommand(handler->getCommandTable(), ""); + } + else + { + if (!handler->ShowHelpForCommand(handler->getCommandTable(), cmd)) + handler->SendSysMessage(LANG_NO_HELP_CMD); + } + + return true; + } + // move item to other slot + static bool HandleItemMoveCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + char const* param1 = strtok((char*)args, " "); + if (!param1) + return false; + + char const* param2 = strtok(NULL, " "); + if (!param2) + return false; + + uint8 srcSlot = uint8(atoi(param1)); + uint8 dstSlot = uint8(atoi(param2)); + + if (srcSlot == dstSlot) + return true; + + if (!handler->GetSession()->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0, srcSlot, true)) + return false; + + if (!handler->GetSession()->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0, dstSlot, false)) + return false; + + uint16 src = ((INVENTORY_SLOT_BAG_0 << 8) | srcSlot); + uint16 dst = ((INVENTORY_SLOT_BAG_0 << 8) | dstSlot); + + handler->GetSession()->GetPlayer()->SwapItem(src, dst); + + return true; + } + + static bool HandleCooldownCommand(ChatHandler* handler, char const* args) + { + Player* target = handler->getSelectedPlayer(); + if (!target) + { + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + + std::string nameLink = handler->GetNameLink(target); + + if (!*args) + { + target->RemoveAllSpellCooldown(); + handler->PSendSysMessage(LANG_REMOVEALL_COOLDOWN, nameLink.c_str()); + } + else + { + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spellIid = handler->extractSpellIdFromLink((char*)args); + if (!spellIid) + return false; + + if (!sSpellMgr->GetSpellInfo(spellIid)) + { + handler->PSendSysMessage(LANG_UNKNOWN_SPELL, target == handler->GetSession()->GetPlayer() ? handler->GetTrinityString(LANG_YOU) : nameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + target->RemoveSpellCooldown(spellIid, true); + handler->PSendSysMessage(LANG_REMOVE_COOLDOWN, spellIid, target == handler->GetSession()->GetPlayer() ? handler->GetTrinityString(LANG_YOU) : nameLink.c_str()); + } + return true; + } + + static bool HandleGetDistanceCommand(ChatHandler* handler, char const* args) + { + WorldObject* obj = NULL; + + if (*args) + { + uint64 guid = handler->extractGuidFromLink((char*)args); + if (guid) + obj = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*handler->GetSession()->GetPlayer(), guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); + + if (!obj) + { + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + } + else + { + obj = handler->getSelectedUnit(); + + if (!obj) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + } + + handler->PSendSysMessage(LANG_DISTANCE, handler->GetSession()->GetPlayer()->GetDistance(obj), handler->GetSession()->GetPlayer()->GetDistance2d(obj), handler->GetSession()->GetPlayer()->GetExactDist(obj), handler->GetSession()->GetPlayer()->GetExactDist2d(obj)); + return true; + } + // Teleport player to last position + static bool HandleRecallCommand(ChatHandler* handler, char const* args) + { + Player* target; + if (!handler->extractPlayerTarget((char*)args, &target)) + return false; + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + if (target->IsBeingTeleported()) + { + handler->PSendSysMessage(LANG_IS_TELEPORTED, handler->GetNameLink(target).c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + // stop flight if need + if (target->isInFlight()) + { + target->GetMotionMaster()->MovementExpired(); + target->CleanupAfterTaxiFlight(); + } + + target->TeleportTo(target->m_recallMap, target->m_recallX, target->m_recallY, target->m_recallZ, target->m_recallO); + return true; + } + + static bool HandleSaveCommand(ChatHandler* handler, char const* /*args*/) + { + Player* player = handler->GetSession()->GetPlayer(); + + // save GM account without delay and output message + if (!AccountMgr::IsPlayerAccount(handler->GetSession()->GetSecurity())) + { + if (Player* target = handler->getSelectedPlayer()) + target->SaveToDB(); + else + player->SaveToDB(); + handler->SendSysMessage(LANG_PLAYER_SAVED); + return true; + } + + // save if the player has last been saved over 20 seconds ago + uint32 saveInterval = sWorld->getIntConfig(CONFIG_INTERVAL_SAVE); + if (saveInterval == 0 || (saveInterval > 20 * IN_MILLISECONDS && player->GetSaveTimer() <= saveInterval - 20 * IN_MILLISECONDS)) + player->SaveToDB(); + + return true; + } + + // Save all players in the world + static bool HandleSaveAllCommand(ChatHandler* handler, char const* /*args*/) + { + sObjectAccessor->SaveAllPlayers(); + handler->SendSysMessage(LANG_PLAYERS_SAVED); + return true; + } + + // kick player + static bool HandleKickPlayerCommand(ChatHandler* handler, char const* args) + { + Player* target = NULL; + std::string playerName; + if (!handler->extractPlayerTarget((char*)args, &target, NULL, &playerName)) + return false; + + if (handler->GetSession() && target == handler->GetSession()->GetPlayer()) + { + handler->SendSysMessage(LANG_COMMAND_KICKSELF); + handler->SetSentErrorMessage(true); + return false; + } + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + if (sWorld->getBoolConfig(CONFIG_SHOW_KICK_IN_WORLD)) + sWorld->SendWorldText(LANG_COMMAND_KICKMESSAGE, playerName.c_str()); + else + handler->PSendSysMessage(LANG_COMMAND_KICKMESSAGE, playerName.c_str()); + + target->GetSession()->KickPlayer(); + + return true; + } + + static bool HandleStartCommand(ChatHandler* handler, char const* /*args*/) + { + Player* player = handler->GetSession()->GetPlayer(); + + if (player->isInFlight()) + { + handler->SendSysMessage(LANG_YOU_IN_FLIGHT); + handler->SetSentErrorMessage(true); + return false; + } + + if (player->isInCombat()) + { + handler->SendSysMessage(LANG_YOU_IN_COMBAT); + handler->SetSentErrorMessage(true); + return false; + } + + if (player->isDead() || player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) + { + // if player is dead and stuck, send ghost to graveyard + player->RepopAtGraveyard(); + return true; + } + + // cast spell Stuck + player->CastSpell(player, 7355, false); + return true; + } + // Enable on\off all taxi paths + static bool HandleTaxiCheatCommand(ChatHandler* handler, char const* args) + { + if (!*args) + { + handler->SendSysMessage(LANG_USE_BOL); + handler->SetSentErrorMessage(true); + return false; + } + + std::string argStr = (char*)args; + + Player* chr = handler->getSelectedPlayer(); + + if (!chr) + chr = handler->GetSession()->GetPlayer(); + else if (handler->HasLowerSecurity(chr, 0)) // check online security + return false; + + if (argStr == "on") + { + chr->SetTaxiCheater(true); + handler->PSendSysMessage(LANG_YOU_GIVE_TAXIS, handler->GetNameLink(chr).c_str()); + if (handler->needReportToTarget(chr)) + ChatHandler(chr).PSendSysMessage(LANG_YOURS_TAXIS_ADDED, handler->GetNameLink().c_str()); + return true; + } + + if (argStr == "off") + { + chr->SetTaxiCheater(false); + handler->PSendSysMessage(LANG_YOU_REMOVE_TAXIS, handler->GetNameLink(chr).c_str()); + if (handler->needReportToTarget(chr)) + ChatHandler(chr).PSendSysMessage(LANG_YOURS_TAXIS_REMOVED, handler->GetNameLink().c_str()); + + return true; + } + + handler->SendSysMessage(LANG_USE_BOL); + handler->SetSentErrorMessage(true); + + return false; + } + + static bool HandleLinkGraveCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + char* px = strtok((char*)args, " "); + if (!px) + return false; + + uint32 graveyardId = uint32(atoi(px)); + + uint32 team; + + char* px2 = strtok(NULL, " "); + + if (!px2) + team = 0; + else if (strncmp(px2, "horde", 6) == 0) + team = HORDE; + else if (strncmp(px2, "alliance", 9) == 0) + team = ALLIANCE; + else + return false; + + WorldSafeLocsEntry const* graveyard = sWorldSafeLocsStore.LookupEntry(graveyardId); + + if (!graveyard) + { + handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST, graveyardId); + handler->SetSentErrorMessage(true); + return false; + } + + Player* player = handler->GetSession()->GetPlayer(); + + uint32 zoneId = player->GetZoneId(); + + AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(zoneId); + if (!areaEntry || areaEntry->zone !=0) + { + handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, graveyardId, zoneId); + handler->SetSentErrorMessage(true); + return false; + } + + if (sObjectMgr->AddGraveYardLink(graveyardId, zoneId, team)) + handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, graveyardId, zoneId); + else + handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, graveyardId, zoneId); + + return true; + } + + static bool HandleNearGraveCommand(ChatHandler* handler, char const* args) + { + uint32 team; + + size_t argStr = strlen(args); + + if (!*args) + team = 0; + else if (strncmp((char*)args, "horde", argStr) == 0) + team = HORDE; + else if (strncmp((char*)args, "alliance", argStr) == 0) + team = ALLIANCE; + else + return false; + + Player* player = handler->GetSession()->GetPlayer(); + uint32 zone_id = player->GetZoneId(); + + WorldSafeLocsEntry const* graveyard = sObjectMgr->GetClosestGraveYard( + player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), team); + + if (graveyard) + { + uint32 graveyardId = graveyard->ID; + + GraveYardData const* data = sObjectMgr->FindGraveYardData(graveyardId, zone_id); + if (!data) + { + handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR, graveyardId); + handler->SetSentErrorMessage(true); + return false; + } + + team = data->team; + + std::string team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_NOTEAM); + + if (team == 0) + team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_ANY); + else if (team == HORDE) + team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_HORDE); + else if (team == ALLIANCE) + team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_ALLIANCE); + + handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, graveyardId, team_name.c_str(), zone_id); + } + else + { + std::string team_name; + + if (team == 0) + team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_ANY); + else if (team == HORDE) + team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_HORDE); + else if (team == ALLIANCE) + team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_ALLIANCE); + + if (team == ~uint32(0)) + handler->PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, zone_id); + else + handler->PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, zone_id, team_name.c_str()); + } + + return true; + } + + static bool HandleExploreCheatCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + int32 flag = int32(atoi((char*)args)); + + Player* playerTarget = handler->getSelectedPlayer(); + if (!playerTarget) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + if (flag != 0) + { + handler->PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, handler->GetNameLink(playerTarget).c_str()); + if (handler->needReportToTarget(playerTarget)) + ChatHandler(playerTarget).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL, handler->GetNameLink().c_str()); + } + else + { + handler->PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, handler->GetNameLink(playerTarget).c_str()); + if (handler->needReportToTarget(playerTarget)) + ChatHandler(playerTarget).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING, handler->GetNameLink().c_str()); + } + + for (uint8 i = 0; i < PLAYER_EXPLORED_ZONES_SIZE; ++i) + { + if (flag != 0) + handler->GetSession()->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i, 0xFFFFFFFF); + else + handler->GetSession()->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i, 0); + } + + return true; + } + + static bool HandleShowAreaCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + Player* playerTarget = handler->getSelectedPlayer(); + if (!playerTarget) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + int32 area = GetAreaFlagByAreaID(atoi((char*)args)); + int32 offset = area / 32; + uint32 val = uint32((1 << (area % 32))); + + if (area<0 || offset >= PLAYER_EXPLORED_ZONES_SIZE) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 currFields = playerTarget->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset); + playerTarget->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, uint32((currFields | val))); + + handler->SendSysMessage(LANG_EXPLORE_AREA); + return true; + } + + static bool HandleHideAreaCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + Player* playerTarget = handler->getSelectedPlayer(); + if (!playerTarget) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + int32 area = GetAreaFlagByAreaID(atoi((char*)args)); + int32 offset = area / 32; + uint32 val = uint32((1 << (area % 32))); + + if (area < 0 || offset >= PLAYER_EXPLORED_ZONES_SIZE) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 currFields = playerTarget->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset); + playerTarget->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, uint32((currFields ^ val))); + + handler->SendSysMessage(LANG_UNEXPLORE_AREA); + return true; + } + + static bool HandleAddItemCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + uint32 itemId = 0; + + if (args[0] == '[') // [name] manual form + { + char const* itemNameStr = strtok((char*)args, "]"); + + if (itemNameStr && itemNameStr[0]) + { + std::string itemName = itemNameStr+1; + WorldDatabase.EscapeString(itemName); + + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_ITEM_TEMPLATE_BY_NAME); + stmt->setString(0, itemName); + PreparedQueryResult result = WorldDatabase.Query(stmt); + + if (!result) + { + handler->PSendSysMessage(LANG_COMMAND_COULDNOTFIND, itemNameStr+1); + handler->SetSentErrorMessage(true); + return false; + } + itemId = result->Fetch()->GetUInt32(); + } + else + return false; + } + else // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r + { + char const* id = handler->extractKeyFromLink((char*)args, "Hitem"); + if (!id) + return false; + itemId = uint32(atol(id)); + } + + char const* ccount = strtok(NULL, " "); + + int32 count = 1; + + if (ccount) + count = strtol(ccount, NULL, 10); + + if (count == 0) + count = 1; + + Player* player = handler->GetSession()->GetPlayer(); + Player* playerTarget = handler->getSelectedPlayer(); + if (!playerTarget) + playerTarget = player; + + sLog->outDebug(LOG_FILTER_GENERAL, handler->GetTrinityString(LANG_ADDITEM), itemId, count); + + ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemId); + if (!itemTemplate) + { + handler->PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId); + handler->SetSentErrorMessage(true); + return false; + } + + // Subtract + if (count < 0) + { + playerTarget->DestroyItemCount(itemId, -count, true, false); + handler->PSendSysMessage(LANG_REMOVEITEM, itemId, -count, handler->GetNameLink(playerTarget).c_str()); + return true; + } + + // Adding items + uint32 noSpaceForCount = 0; + + // check space and find places + ItemPosCountVec dest; + InventoryResult msg = playerTarget->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount); + if (msg != EQUIP_ERR_OK) // convert to possible store amount + count -= noSpaceForCount; + + if (count == 0 || dest.empty()) // can't add any + { + handler->PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount); + handler->SetSentErrorMessage(true); + return false; + } + + Item* item = playerTarget->StoreNewItem(dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId)); + + // remove binding (let GM give it to another player later) + if (player == playerTarget) + for (ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr) + if (Item* item1 = player->GetItemByPos(itr->pos)) + item1->SetBinding(false); + + if (count > 0 && item) + { + player->SendNewItem(item, count, false, true); + if (player != playerTarget) + playerTarget->SendNewItem(item, count, true, false); + } + + if (noSpaceForCount > 0) + handler->PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount); + + return true; + } + + static bool HandleAddItemSetCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + char const* id = handler->extractKeyFromLink((char*)args, "Hitemset"); // number or [name] Shift-click form |color|Hitemset:itemset_id|h[name]|h|r + if (!id) + return false; + + uint32 itemSetId = atol(id); + + // prevent generation all items with itemset field value '0' + if (itemSetId == 0) + { + handler->PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND, itemSetId); + handler->SetSentErrorMessage(true); + return false; + } + + Player* player = handler->GetSession()->GetPlayer(); + Player* playerTarget = handler->getSelectedPlayer(); + if (!playerTarget) + playerTarget = player; + + sLog->outDebug(LOG_FILTER_GENERAL, handler->GetTrinityString(LANG_ADDITEMSET), itemSetId); + + bool found = false; + ItemTemplateContainer const* its = sObjectMgr->GetItemTemplateStore(); + for (ItemTemplateContainer::const_iterator itr = its->begin(); itr != its->end(); ++itr) + { + if (itr->second.ItemSet == itemSetId) + { + found = true; + ItemPosCountVec dest; + InventoryResult msg = playerTarget->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itr->second.ItemId, 1); + if (msg == EQUIP_ERR_OK) + { + Item* item = playerTarget->StoreNewItem(dest, itr->second.ItemId, true); + + // remove binding (let GM give it to another player later) + if (player == playerTarget) + item->SetBinding(false); + + player->SendNewItem(item, 1, false, true); + if (player != playerTarget) + playerTarget->SendNewItem(item, 1, true, false); + } + else + { + player->SendEquipError(msg, NULL, NULL, itr->second.ItemId); + handler->PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itr->second.ItemId, 1); + } + } + } + + if (!found) + { + handler->PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND, itemSetId); + handler->SetSentErrorMessage(true); + return false; + } + + return true; + } + + static bool HandleBankCommand(ChatHandler* handler, char const* /*args*/) + { + handler->GetSession()->SendShowBank(handler->GetSession()->GetPlayer()->GetGUID()); + return true; + } + + static bool HandleChangeWeather(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + // Weather is OFF + if (!sWorld->getBoolConfig(CONFIG_WEATHER)) + { + handler->SendSysMessage(LANG_WEATHER_DISABLED); + handler->SetSentErrorMessage(true); + return false; + } + + // *Change the weather of a cell + char const* px = strtok((char*)args, " "); + char const* py = strtok(NULL, " "); + + if (!px || !py) + return false; + + uint32 type = uint32(atoi(px)); //0 to 3, 0: fine, 1: rain, 2: snow, 3: sand + float grade = float(atof(py)); //0 to 1, sending -1 is instand good weather + + Player* player = handler->GetSession()->GetPlayer(); + uint32 zoneid = player->GetZoneId(); + + Weather* weather = WeatherMgr::FindWeather(zoneid); + + if (!weather) + weather = WeatherMgr::AddWeather(zoneid); + if (!weather) + { + handler->SendSysMessage(LANG_NO_WEATHER); + handler->SetSentErrorMessage(true); + return false; + } + + weather->SetWeather(WeatherType(type), grade); + + return true; + } + + + static bool HandleMaxSkillCommand(ChatHandler* handler, char const* /*args*/) + { + Player* SelectedPlayer = handler->getSelectedPlayer(); + if (!SelectedPlayer) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + // each skills that have max skill value dependent from level seted to current level max skill value + SelectedPlayer->UpdateSkillsToMaxSkillsForLevel(); + return true; + } + + static bool HandleSetSkillCommand(ChatHandler* handler, char const* args) + { + // number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r + char const* skillStr = handler->extractKeyFromLink((char*)args, "Hskill"); + if (!skillStr) + return false; + + char const* levelStr = strtok(NULL, " "); + if (!levelStr) + return false; + + char const* maxPureSkill = strtok(NULL, " "); + + int32 skill = atoi(skillStr); + if (skill <= 0) + { + handler->PSendSysMessage(LANG_INVALID_SKILL_ID, skill); + handler->SetSentErrorMessage(true); + return false; + } + + int32 level = uint32(atol(levelStr)); + + Player* target = handler->getSelectedPlayer(); + if (!target) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + SkillLineEntry const* skillLine = sSkillLineStore.LookupEntry(skill); + if (!skillLine) + { + handler->PSendSysMessage(LANG_INVALID_SKILL_ID, skill); + handler->SetSentErrorMessage(true); + return false; + } + + std::string tNameLink = handler->GetNameLink(target); + + if (!target->GetSkillValue(skill)) + { + handler->PSendSysMessage(LANG_SET_SKILL_ERROR, tNameLink.c_str(), skill, skillLine->name[handler->GetSessionDbcLocale()]); + handler->SetSentErrorMessage(true); + return false; + } + + uint16 max = maxPureSkill ? atol (maxPureSkill) : target->GetPureMaxSkillValue(skill); + + if (level <= 0 || level > max || max <= 0) + return false; + + target->SetSkill(skill, target->GetSkillStep(skill), level, max); + handler->PSendSysMessage(LANG_SET_SKILL, skill, skillLine->name[handler->GetSessionDbcLocale()], tNameLink.c_str(), level, max); + + return true; + } + // show info of player + static bool HandlePInfoCommand(ChatHandler* handler, char const* args) + { + Player* target; + uint64 targetGuid; + std::string targetName; + + uint32 parseGUID = MAKE_NEW_GUID(atol((char*)args), 0, HIGHGUID_PLAYER); + + if (sObjectMgr->GetPlayerNameByGUID(parseGUID, targetName)) + { + target = sObjectMgr->GetPlayerByLowGUID(parseGUID); + targetGuid = parseGUID; + } + else if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) + return false; + + uint32 accId = 0; + uint32 money = 0; + uint32 totalPlayerTime = 0; + uint8 level = 0; + uint32 latency = 0; + uint8 race; + uint8 Class; + int64 muteTime = 0; + int64 banTime = -1; + uint32 mapId; + uint32 areaId; + uint32 phase = 0; + + // get additional information from Player object + if (target) + { + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + accId = target->GetSession()->GetAccountId(); + money = target->GetMoney(); + totalPlayerTime = target->GetTotalPlayedTime(); + level = target->getLevel(); + latency = target->GetSession()->GetLatency(); + race = target->getRace(); + Class = target->getClass(); + muteTime = target->GetSession()->m_muteTime; + mapId = target->GetMapId(); + areaId = target->GetAreaId(); + phase = target->GetPhaseMask(); + } + // get additional information from DB + else + { + // check offline security + if (handler->HasLowerSecurity(NULL, targetGuid)) + return false; + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PINFO); + stmt->setUInt32(0, GUID_LOPART(targetGuid)); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + + if (!result) + return false; + + Field* fields = result->Fetch(); + totalPlayerTime = fields[0].GetUInt32(); + level = fields[1].GetUInt8(); + money = fields[2].GetUInt32(); + accId = fields[3].GetUInt32(); + race = fields[4].GetUInt8(); + Class = fields[5].GetUInt8(); + mapId = fields[6].GetUInt16(); + areaId = fields[7].GetUInt16(); + } + + std::string userName = handler->GetTrinityString(LANG_ERROR); + std::string eMail = handler->GetTrinityString(LANG_ERROR); + std::string lastIp = handler->GetTrinityString(LANG_ERROR); + uint32 security = 0; + std::string lastLogin = handler->GetTrinityString(LANG_ERROR); + + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO); + stmt->setInt32(0, int32(realmID)); + stmt->setUInt32(1, accId); + PreparedQueryResult result = LoginDatabase.Query(stmt); + + if (result) + { + Field* fields = result->Fetch(); + userName = fields[0].GetString(); + security = fields[1].GetUInt8(); + eMail = fields[2].GetString(); + muteTime = fields[5].GetUInt64(); + + if (eMail.empty()) + eMail = "-"; + + if (!handler->GetSession() || handler->GetSession()->GetSecurity() >= AccountTypes(security)) + { + lastIp = fields[3].GetString(); + lastLogin = fields[4].GetString(); + + uint32 ip = inet_addr(lastIp.c_str()); +#if TRINITY_ENDIAN == BIGENDIAN + EndianConvertReverse(ip); +#endif + + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_IP2NATION_COUNTRY); + + stmt->setUInt32(0, ip); + + PreparedQueryResult result2 = WorldDatabase.Query(stmt); + + if (result2) + { + Field* fields2 = result2->Fetch(); + lastIp.append(" ("); + lastIp.append(fields2[0].GetString()); + lastIp.append(")"); + } + } + else + { + lastIp = "-"; + lastLogin = "-"; + } + } + + std::string nameLink = handler->playerLink(targetName); + + handler->PSendSysMessage(LANG_PINFO_ACCOUNT, (target ? "" : handler->GetTrinityString(LANG_OFFLINE)), nameLink.c_str(), GUID_LOPART(targetGuid), userName.c_str(), accId, eMail.c_str(), security, lastIp.c_str(), lastLogin.c_str(), latency); + + std::string bannedby = "unknown"; + std::string banreason = ""; + + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO_BANS); + stmt->setUInt32(0, accId); + PreparedQueryResult result2 = LoginDatabase.Query(stmt); + if (!result2) + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PINFO_BANS); + stmt->setUInt32(0, GUID_LOPART(targetGuid)); + result2 = CharacterDatabase.Query(stmt); + } + + if (result2) + { + Field* fields = result2->Fetch(); + banTime = int64(fields[1].GetBool() ? 0 : fields[0].GetUInt32()); + bannedby = fields[2].GetString(); + banreason = fields[3].GetString(); + } + + if (muteTime > 0) + handler->PSendSysMessage(LANG_PINFO_MUTE, secsToTimeString(muteTime - time(NULL), true).c_str()); + + if (banTime >= 0) + handler->PSendSysMessage(LANG_PINFO_BAN, banTime > 0 ? secsToTimeString(banTime - time(NULL), true).c_str() : "permanently", bannedby.c_str(), banreason.c_str()); + + std::string raceStr, ClassStr; + switch (race) + { + case RACE_HUMAN: + raceStr = "Human"; + break; + case RACE_ORC: + raceStr = "Orc"; + break; + case RACE_DWARF: + raceStr = "Dwarf"; + break; + case RACE_NIGHTELF: + raceStr = "Night Elf"; + break; + case RACE_UNDEAD_PLAYER: + raceStr = "Undead"; + break; + case RACE_TAUREN: + raceStr = "Tauren"; + break; + case RACE_GNOME: + raceStr = "Gnome"; + break; + case RACE_TROLL: + raceStr = "Troll"; + break; + case RACE_BLOODELF: + raceStr = "Blood Elf"; + break; + case RACE_DRAENEI: + raceStr = "Draenei"; + break; + } + + switch (Class) + { + case CLASS_WARRIOR: + ClassStr = "Warrior"; + break; + case CLASS_PALADIN: + ClassStr = "Paladin"; + break; + case CLASS_HUNTER: + ClassStr = "Hunter"; + break; + case CLASS_ROGUE: + ClassStr = "Rogue"; + break; + case CLASS_PRIEST: + ClassStr = "Priest"; + break; + case CLASS_DEATH_KNIGHT: + ClassStr = "Death Knight"; + break; + case CLASS_SHAMAN: + ClassStr = "Shaman"; + break; + case CLASS_MAGE: + ClassStr = "Mage"; + break; + case CLASS_WARLOCK: + ClassStr = "Warlock"; + break; + case CLASS_DRUID: + ClassStr = "Druid"; + break; + } + + std::string timeStr = secsToTimeString(totalPlayerTime, true, true); + uint32 gold = money /GOLD; + uint32 silv = (money % GOLD) / SILVER; + uint32 copp = (money % GOLD) % SILVER; + handler->PSendSysMessage(LANG_PINFO_LEVEL, raceStr.c_str(), ClassStr.c_str(), timeStr.c_str(), level, gold, silv, copp); + + // Add map, zone, subzone and phase to output + int locale = handler->GetSessionDbcLocale(); + std::string areaName = ""; + std::string zoneName = ""; + + MapEntry const* map = sMapStore.LookupEntry(mapId); + + AreaTableEntry const* area = GetAreaEntryByAreaID(areaId); + if (area) + { + areaName = area->area_name[locale]; + + AreaTableEntry const* zone = GetAreaEntryByAreaID(area->zone); + if (zone) + zoneName = zone->area_name[locale]; + } + + if (target) + { + if (!zoneName.empty()) + handler->PSendSysMessage(LANG_PINFO_MAP_ONLINE, map->name[locale], zoneName.c_str(), areaName.c_str(), phase); + else + handler->PSendSysMessage(LANG_PINFO_MAP_ONLINE, map->name[locale], areaName.c_str(), "", phase); + } + else + handler->PSendSysMessage(LANG_PINFO_MAP_OFFLINE, map->name[locale], areaName.c_str()); + + return true; + } + + static bool HandleRespawnCommand(ChatHandler* handler, char const* /*args*/) + { + Player* player = handler->GetSession()->GetPlayer(); + + // accept only explicitly selected target (not implicitly self targeting case) + Unit* target = handler->getSelectedUnit(); + if (player->GetSelection() && target) + { + if (target->GetTypeId() != TYPEID_UNIT || target->isPet()) + { + handler->SendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + if (target->isDead()) + target->ToCreature()->Respawn(); + return true; + } + + CellCoord p(Trinity::ComputeCellCoord(player->GetPositionX(), player->GetPositionY())); + Cell cell(p); + cell.SetNoCreate(); + + Trinity::RespawnDo u_do; + Trinity::WorldObjectWorker worker(player, u_do); + + TypeContainerVisitor, GridTypeMapContainer > obj_worker(worker); + cell.Visit(p, obj_worker, *player->GetMap(), *player, player->GetGridActivationRange()); + + return true; + } + // mute player for some times + static bool HandleMuteCommand(ChatHandler* handler, char const* args) + { + char* nameStr; + char* delayStr; + handler->extractOptFirstArg((char*)args, &nameStr, &delayStr); + if (!delayStr) + return false; + + char const* muteReason = strtok(NULL, "\r"); + std::string muteReasonStr = "No reason"; + if (muteReason != NULL) + muteReasonStr = muteReason; + + Player* target; + uint64 targetGuid; + std::string targetName; + if (!handler->extractPlayerTarget(nameStr, &target, &targetGuid, &targetName)) + return false; + + uint32 accountId = target ? target->GetSession()->GetAccountId() : sObjectMgr->GetPlayerAccountIdByGUID(targetGuid); + + // find only player from same account if any + if (!target) + if (WorldSession* session = sWorld->FindSession(accountId)) + target = session->GetPlayer(); + + uint32 notSpeakTime = uint32(atoi(delayStr)); + + // must have strong lesser security level + if (handler->HasLowerSecurity (target, targetGuid, true)) + return false; + + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME); + + if (target) + { + // Target is online, mute will be in effect right away. + int64 muteTime = time(NULL) + notSpeakTime * MINUTE; + target->GetSession()->m_muteTime = muteTime; + stmt->setInt64(0, muteTime); + ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notSpeakTime, muteReasonStr.c_str()); + } + else + { + // Target is offline, mute will be in effect starting from the next login. + int32 muteTime = -int32(notSpeakTime * MINUTE); + stmt->setInt64(0, muteTime); + } + + stmt->setUInt32(1, accountId); + LoginDatabase.Execute(stmt); + std::string nameLink = handler->playerLink(targetName); + + handler->PSendSysMessage(target ? LANG_YOU_DISABLE_CHAT : LANG_COMMAND_DISABLE_CHAT_DELAYED, nameLink.c_str(), notSpeakTime, muteReasonStr.c_str()); + + return true; + } + + // unmute player + static bool HandleUnmuteCommand(ChatHandler* handler, char const* args) + { + Player* target; + uint64 targetGuid; + std::string targetName; + if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) + return false; + + uint32 accountId = target ? target->GetSession()->GetAccountId() : sObjectMgr->GetPlayerAccountIdByGUID(targetGuid); + + // find only player from same account if any + if (!target) + if (WorldSession* session = sWorld->FindSession(accountId)) + target = session->GetPlayer(); + + // must have strong lesser security level + if (handler->HasLowerSecurity (target, targetGuid, true)) + return false; + + if (target) + { + if (target->CanSpeak()) + { + handler->SendSysMessage(LANG_CHAT_ALREADY_ENABLED); + handler->SetSentErrorMessage(true); + return false; + } + + target->GetSession()->m_muteTime = 0; + } + + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME); + stmt->setInt64(0, 0); + stmt->setUInt32(1, accountId); + LoginDatabase.Execute(stmt); + + if (target) + ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_ENABLED); + + std::string nameLink = handler->playerLink(targetName); + + handler->PSendSysMessage(LANG_YOU_ENABLE_CHAT, nameLink.c_str()); + + return true; + } + + + static bool HandleMovegensCommand(ChatHandler* handler, char const* /*args*/) + { + Unit* unit = handler->getSelectedUnit(); + if (!unit) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage(LANG_MOVEGENS_LIST, (unit->GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature"), unit->GetGUIDLow()); + + MotionMaster* motionMaster = unit->GetMotionMaster(); + float x, y, z; + motionMaster->GetDestination(x, y, z); + + for (uint8 i = 0; i < MAX_MOTION_SLOT; ++i) + { + MovementGenerator* movementGenerator = motionMaster->GetMotionSlot(i); + if (!movementGenerator) + { + handler->SendSysMessage("Empty"); + continue; + } + + switch (movementGenerator->GetMovementGeneratorType()) + { + case IDLE_MOTION_TYPE: + handler->SendSysMessage(LANG_MOVEGENS_IDLE); + break; + case RANDOM_MOTION_TYPE: + handler->SendSysMessage(LANG_MOVEGENS_RANDOM); + break; + case WAYPOINT_MOTION_TYPE: + handler->SendSysMessage(LANG_MOVEGENS_WAYPOINT); + break; + case ANIMAL_RANDOM_MOTION_TYPE: + handler->SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM); + break; + case CONFUSED_MOTION_TYPE: + handler->SendSysMessage(LANG_MOVEGENS_CONFUSED); + break; + case CHASE_MOTION_TYPE: + { + Unit* target = NULL; + if (unit->GetTypeId() == TYPEID_PLAYER) + target = static_cast const*>(movementGenerator)->GetTarget(); + else + target = static_cast const*>(movementGenerator)->GetTarget(); + + if (!target) + handler->SendSysMessage(LANG_MOVEGENS_CHASE_NULL); + else if (target->GetTypeId() == TYPEID_PLAYER) + handler->PSendSysMessage(LANG_MOVEGENS_CHASE_PLAYER, target->GetName(), target->GetGUIDLow()); + else + handler->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 const*>(movementGenerator)->GetTarget(); + else + target = static_cast const*>(movementGenerator)->GetTarget(); + + if (!target) + handler->SendSysMessage(LANG_MOVEGENS_FOLLOW_NULL); + else if (target->GetTypeId() == TYPEID_PLAYER) + handler->PSendSysMessage(LANG_MOVEGENS_FOLLOW_PLAYER, target->GetName(), target->GetGUIDLow()); + else + handler->PSendSysMessage(LANG_MOVEGENS_FOLLOW_CREATURE, target->GetName(), target->GetGUIDLow()); + break; + } + case HOME_MOTION_TYPE: + { + if (unit->GetTypeId() == TYPEID_UNIT) + handler->PSendSysMessage(LANG_MOVEGENS_HOME_CREATURE, x, y, z); + else + handler->SendSysMessage(LANG_MOVEGENS_HOME_PLAYER); + break; + } + case FLIGHT_MOTION_TYPE: + handler->SendSysMessage(LANG_MOVEGENS_FLIGHT); + break; + case POINT_MOTION_TYPE: + { + handler->PSendSysMessage(LANG_MOVEGENS_POINT, x, y, z); + break; + } + case FLEEING_MOTION_TYPE: + handler->SendSysMessage(LANG_MOVEGENS_FEAR); + break; + case DISTRACT_MOTION_TYPE: + handler->SendSysMessage(LANG_MOVEGENS_DISTRACT); + break; + case EFFECT_MOTION_TYPE: + handler->SendSysMessage(LANG_MOVEGENS_EFFECT); + break; + default: + handler->PSendSysMessage(LANG_MOVEGENS_UNKNOWN, movementGenerator->GetMovementGeneratorType()); + break; + } + } + return true; + } + /* + ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator + Without this function 3rd party scripting library will get linking errors (unresolved external) + when attempting to use the PointMovementGenerator + */ + static bool HandleComeToMeCommand(ChatHandler* handler, char const* args) + { + char const* newFlagStr = strtok((char*)args, " "); + if (!newFlagStr) + return false; + + Creature* caster = handler->getSelectedCreature(); + if (!caster) + { + handler->SendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + Player* player = handler->GetSession()->GetPlayer(); + + caster->GetMotionMaster()->MovePoint(0, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()); + + return true; + } + + static bool HandleDamageCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + Unit* target = handler->getSelectedUnit(); + if (!target || !handler->GetSession()->GetPlayer()->GetSelection()) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + if (target->GetTypeId() == TYPEID_PLAYER) + { + if (handler->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) + { + handler->GetSession()->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + if (target != handler->GetSession()->GetPlayer()) + handler->GetSession()->GetPlayer()->SendAttackStateUpdate (HITINFO_AFFECTS_VICTIM, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_HIT, 0); + return true; + } + + 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 = handler->GetSession()->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; + + handler->GetSession()->GetPlayer()->CalcAbsorbResist(target, schoolmask, SPELL_DIRECT_DAMAGE, damage, &absorb, &resist); + + if (damage <= absorb + resist) + return true; + + damage -= absorb + resist; + + handler->GetSession()->GetPlayer()->DealDamageMods(target, damage, &absorb); + handler->GetSession()->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false); + handler->GetSession()->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 = handler->extractSpellIdFromLink((char*)args); + if (!spellid || !sSpellMgr->GetSpellInfo(spellid)) + return false; + + handler->GetSession()->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage); + return true; + } + + static bool HandleCombatStopCommand(ChatHandler* handler, char const* args) + { + Player* target = NULL; + + if (args && strlen(args) > 0) + { + target = sObjectAccessor->FindPlayerByName(args); + if (!target) + { + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + } + + if (!target) + { + if (!handler->extractPlayerTarget((char*)args, &target)) + return false; + } + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + target->CombatStop(); + target->getHostileRefManager().deleteReferences(); + return true; + } + + static bool HandleFlushArenaPointsCommand(ChatHandler* /*handler*/, char const* /*args*/) + { + sArenaTeamMgr->DistributeArenaPoints(); + return true; + } + + static bool HandleRepairitemsCommand(ChatHandler* handler, char const* args) + { + Player* target; + if (!handler->extractPlayerTarget((char*)args, &target)) + return false; + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + // Repair items + target->DurabilityRepairAll(false, 0, false); + + handler->PSendSysMessage(LANG_YOU_REPAIR_ITEMS, handler->GetNameLink(target).c_str()); + if (handler->needReportToTarget(target)) + ChatHandler(target).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED, handler->GetNameLink().c_str()); + + return true; + } + + static bool HandleWaterwalkCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + Player* player = handler->getSelectedPlayer(); + if (!player) + { + handler->PSendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + // check online security + if (handler->HasLowerSecurity(player, 0)) + return false; + + if (strncmp(args, "on", 3) == 0) + player->SetMovement(MOVE_WATER_WALK); // ON + else if (strncmp(args, "off", 4) == 0) + player->SetMovement(MOVE_LAND_WALK); // OFF + else + { + handler->SendSysMessage(LANG_USE_BOL); + return false; + } + + handler->PSendSysMessage(LANG_YOU_SET_WATERWALK, args, handler->GetNameLink(player).c_str()); + if (handler->needReportToTarget(player)) + ChatHandler(player).PSendSysMessage(LANG_YOUR_WATERWALK_SET, args, handler->GetNameLink().c_str()); + return true; + } + + // Send mail by command + static bool HandleSendMailCommand(ChatHandler* handler, char const* args) + { + // format: name "subject text" "mail text" + Player* target; + uint64 targetGuid; + std::string targetName; + if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) + return false; + + char* tail1 = strtok(NULL, ""); + if (!tail1) + return false; + + char const* msgSubject = handler->extractQuotedArg(tail1); + if (!msgSubject) + return false; + + char* tail2 = strtok(NULL, ""); + if (!tail2) + return false; + + char const* msgText = handler->extractQuotedArg(tail2); + if (!msgText) + return false; + + // msgSubject, msgText isn't NUL after prev. check + std::string subject = msgSubject; + std::string text = msgText; + + // from console show not existed sender + MailSender sender(MAIL_NORMAL, handler->GetSession() ? handler->GetSession()->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM); + + //- TODO: Fix poor design + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + MailDraft(subject, text) + .SendMailTo(trans, MailReceiver(target, GUID_LOPART(targetGuid)), sender); + + CharacterDatabase.CommitTransaction(trans); + + std::string nameLink = handler->playerLink(targetName); + handler->PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); + return true; + } + // Send items by mail + static bool HandleSendItemsCommand(ChatHandler* handler, char const* args) + { + // format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12] + Player* receiver; + uint64 receiverGuid; + std::string receiverName; + if (!handler->extractPlayerTarget((char*)args, &receiver, &receiverGuid, &receiverName)) + return false; + + char* tail1 = strtok(NULL, ""); + if (!tail1) + return false; + + char const* msgSubject = handler->extractQuotedArg(tail1); + if (!msgSubject) + return false; + + char* tail2 = strtok(NULL, ""); + if (!tail2) + return false; + + char const* msgText = handler->extractQuotedArg(tail2); + if (!msgText) + return false; + + // msgSubject, msgText isn't NUL after prev. check + std::string subject = msgSubject; + std::string text = msgText; + + // extract items + typedef std::pair ItemPair; + typedef std::list< ItemPair > ItemPairs; + ItemPairs items; + + // get all tail string + char* tail = strtok(NULL, ""); + + // get from tail next item str + while (char* itemStr = strtok(tail, " ")) + { + // and get new tail + tail = strtok(NULL, ""); + + // parse item str + char const* itemIdStr = strtok(itemStr, ":"); + char const* itemCountStr = strtok(NULL, " "); + + uint32 itemId = atoi(itemIdStr); + if (!itemId) + return false; + + ItemTemplate const* item_proto = sObjectMgr->GetItemTemplate(itemId); + if (!item_proto) + { + handler->PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 itemCount = itemCountStr ? atoi(itemCountStr) : 1; + if (itemCount < 1 || (item_proto->MaxCount > 0 && itemCount > uint32(item_proto->MaxCount))) + { + handler->PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, itemCount, itemId); + handler->SetSentErrorMessage(true); + return false; + } + + while (itemCount > item_proto->GetMaxStackSize()) + { + items.push_back(ItemPair(itemId, item_proto->GetMaxStackSize())); + itemCount -= item_proto->GetMaxStackSize(); + } + + items.push_back(ItemPair(itemId, itemCount)); + + if (items.size() > MAX_MAIL_ITEMS) + { + handler->PSendSysMessage(LANG_COMMAND_MAIL_ITEMS_LIMIT, MAX_MAIL_ITEMS); + handler->SetSentErrorMessage(true); + return false; + } + } + + // from console show not existed sender + MailSender sender(MAIL_NORMAL, handler->GetSession() ? handler->GetSession()->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM); + + // fill mail + MailDraft draft(subject, text); + + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + + for (ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr) + { + if (Item* item = Item::CreateItem(itr->first, itr->second, handler->GetSession() ? handler->GetSession()->GetPlayer() : 0)) + { + item->SaveToDB(trans); // save for prevent lost at next mail load, if send fail then item will deleted + draft.AddItem(item); + } + } + + draft.SendMailTo(trans, MailReceiver(receiver, GUID_LOPART(receiverGuid)), sender); + CharacterDatabase.CommitTransaction(trans); + + std::string nameLink = handler->playerLink(receiverName); + handler->PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); + return true; + } + /// Send money by mail + static bool HandleSendMoneyCommand(ChatHandler* handler, char const* args) + { + /// format: name "subject text" "mail text" money + + Player* receiver; + uint64 receiverGuid; + std::string receiverName; + if (!handler->extractPlayerTarget((char*)args, &receiver, &receiverGuid, &receiverName)) + return false; + + char* tail1 = strtok(NULL, ""); + if (!tail1) + return false; + + char* msgSubject = handler->extractQuotedArg(tail1); + if (!msgSubject) + return false; + + char* tail2 = strtok(NULL, ""); + if (!tail2) + return false; + + char* msgText = handler->extractQuotedArg(tail2); + if (!msgText) + return false; + + char* moneyStr = strtok(NULL, ""); + int32 money = moneyStr ? atoi(moneyStr) : 0; + if (money <= 0) + return false; + + // msgSubject, msgText isn't NUL after prev. check + std::string subject = msgSubject; + std::string text = msgText; + + // from console show not existed sender + MailSender sender(MAIL_NORMAL, handler->GetSession() ? handler->GetSession()->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM); + + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + + MailDraft(subject, text) + .AddMoney(money) + .SendMailTo(trans, MailReceiver(receiver, GUID_LOPART(receiverGuid)), sender); + + CharacterDatabase.CommitTransaction(trans); + + std::string nameLink = handler->playerLink(receiverName); + handler->PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); + return true; + } + /// Send a message to a player in game + static bool HandleSendMessageCommand(ChatHandler* handler, char const* args) + { + /// - Find the player + Player* player; + if (!handler->extractPlayerTarget((char*)args, &player)) + return false; + + char* msgStr = strtok(NULL, ""); + if (!msgStr) + return false; + + ///- Check that he is not logging out. + if (player->GetSession()->isLogingOut()) + { + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + + /// - Send the message + // Use SendAreaTriggerMessage for fastest delivery. + player->GetSession()->SendAreaTriggerMessage("%s", msgStr); + player->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r"); + + // Confirmation message + std::string nameLink = handler->GetNameLink(player); + handler->PSendSysMessage(LANG_SENDMESSAGE, nameLink.c_str(), msgStr); + + return true; + } + + static bool HandleCreatePetCommand(ChatHandler* handler, char const* /*args*/) + { + Player* player = handler->GetSession()->GetPlayer(); + Creature* creatureTarget = handler->getSelectedCreature(); + + if (!creatureTarget || creatureTarget->isPet() || creatureTarget->GetTypeId() == TYPEID_PLAYER) + { + handler->PSendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + CreatureTemplate const* creatrueTemplate = sObjectMgr->GetCreatureTemplate(creatureTarget->GetEntry()); + // Creatures with family 0 crashes the server + if (!creatrueTemplate->family) + { + handler->PSendSysMessage("This creature cannot be tamed. (family id: 0)."); + handler->SetSentErrorMessage(true); + return false; + } + + if (player->GetPetGUID()) + { + handler->PSendSysMessage("You already have a pet"); + handler->SetSentErrorMessage(true); + return false; + } + + // Everything looks OK, create new pet + Pet* pet = new Pet(player, HUNTER_PET); + if (!pet->CreateBaseAtCreature(creatureTarget)) + { + delete pet; + handler->PSendSysMessage("Error 1"); + return false; + } + + creatureTarget->setDeathState(JUST_DIED); + creatureTarget->RemoveCorpse(); + creatureTarget->SetHealth(0); // just for nice GM-mode view + + pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, player->GetGUID()); + pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, player->getFaction()); + + if (!pet->InitStatsForLevel(creatureTarget->getLevel())) + { + sLog->outError(LOG_FILTER_GENERAL, "InitStatsForLevel() in EffectTameCreature failed! Pet deleted."); + handler->PSendSysMessage("Error 2"); + delete pet; + return false; + } + + // prepare visual effect for levelup + pet->SetUInt32Value(UNIT_FIELD_LEVEL, creatureTarget->getLevel()-1); + + pet->GetCharmInfo()->SetPetNumber(sObjectMgr->GeneratePetNumber(), true); + // this enables pet details window (Shift+P) + pet->InitPetCreateSpells(); + pet->SetFullHealth(); + + pet->GetMap()->AddToMap(pet->ToCreature()); + + // visual effect for levelup + pet->SetUInt32Value(UNIT_FIELD_LEVEL, creatureTarget->getLevel()); + + player->SetMinion(pet, true); + pet->SavePetToDB(PET_SAVE_AS_CURRENT); + player->PetSpellInitialize(); + + return true; + } + + static bool HandlePetLearnCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + Player* player = handler->GetSession()->GetPlayer(); + Pet* pet = player->GetPet(); + + if (!pet) + { + handler->PSendSysMessage("You have no pet"); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 spellId = handler->extractSpellIdFromLink((char*)args); + + if (!spellId || !sSpellMgr->GetSpellInfo(spellId)) + return false; + + // Check if pet already has it + if (pet->HasSpell(spellId)) + { + handler->PSendSysMessage("Pet already has spell: %u", spellId); + handler->SetSentErrorMessage(true); + return false; + } + + // Check if spell is valid + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); + if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo)) + { + handler->PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spellId); + handler->SetSentErrorMessage(true); + return false; + } + + pet->learnSpell(spellId); + + handler->PSendSysMessage("Pet has learned spell %u", spellId); + return true; + } + + static bool HandlePetUnlearnCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + Player* player = handler->GetSession()->GetPlayer(); + Pet* pet = player->GetPet(); + if (!pet) + { + handler->PSendSysMessage("You have no pet"); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 spellId = handler->extractSpellIdFromLink((char*)args); + + if (pet->HasSpell(spellId)) + pet->removeSpell(spellId, false); + else + handler->PSendSysMessage("Pet doesn't have that spell"); + + return true; + } + + static bool HandleFreezeCommand(ChatHandler* handler, char const* args) + { + std::string name; + Player* player; + char const* TargetName = strtok((char*)args, " "); // get entered name + if (!TargetName) // if no name entered use target + { + player = handler->getSelectedPlayer(); + if (player) //prevent crash with creature as target + { + name = player->GetName(); + normalizePlayerName(name); + } + } + else // if name entered + { + name = TargetName; + normalizePlayerName(name); + player = sObjectAccessor->FindPlayerByName(name.c_str()); + } + + if (!player) + { + handler->SendSysMessage(LANG_COMMAND_FREEZE_WRONG); + return true; + } + + if (player == handler->GetSession()->GetPlayer()) + { + handler->SendSysMessage(LANG_COMMAND_FREEZE_ERROR); + return true; + } + + // effect + if (player && (player != handler->GetSession()->GetPlayer())) + { + handler->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); + } + } + + if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(9454)) + Aura::TryRefreshStackOrCreate(spellInfo, MAX_EFFECT_MASK, player, player); + + // save player + player->SaveToDB(); + } + + return true; + } + + static bool HandleUnFreezeCommand(ChatHandler* handler, char const*args) + { + std::string name; + Player* player; + char* targetName = strtok((char*)args, " "); // Get entered name + + if (targetName) + { + name = targetName; + normalizePlayerName(name); + player = sObjectAccessor->FindPlayerByName(name.c_str()); + } + else // If no name was entered - use target + { + player = handler->getSelectedPlayer(); + if (player) + name = player->GetName(); + } + + if (player) + { + handler->PSendSysMessage(LANG_COMMAND_UNFREEZE, name.c_str()); + + // Reset player faction + allow combat + allow duels + player->setFactionForRace(player->getRace()); + player->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + + // Remove Freeze spell (allowing movement and spells) + player->RemoveAurasDueToSpell(9454); + + // Save player + player->SaveToDB(); + } + else + { + 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) + { + handler->SendSysMessage(LANG_COMMAND_FREEZE_WRONG); + return true; + } + + // If player found: delete his freeze aura + Field* fields = result->Fetch(); + uint32 lowGuid = fields[0].GetUInt32(); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_AURA_FROZEN); + stmt->setUInt32(0, lowGuid); + CharacterDatabase.Execute(stmt); + + handler->PSendSysMessage(LANG_COMMAND_UNFREEZE, name.c_str()); + return true; + } + else + { + handler->SendSysMessage(LANG_COMMAND_FREEZE_WRONG); + return true; + } + } + + return true; + } + + static bool HandleListFreezeCommand(ChatHandler* handler, char const* /*args*/) + { + // Get names from DB + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_AURA_FROZEN); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (!result) + { + handler->SendSysMessage(LANG_COMMAND_NO_FROZEN_PLAYERS); + return true; + } + + // Header of the names + handler->PSendSysMessage(LANG_COMMAND_LIST_FREEZE); + + // Output of the results + do + { + Field* fields = result->Fetch(); + std::string player = fields[0].GetString(); + handler->PSendSysMessage(LANG_COMMAND_FROZEN_PLAYERS, player.c_str()); + } + while (result->NextRow()); + + return true; + } + + static bool HandleGroupLeaderCommand(ChatHandler* handler, char const* args) + { + Player* player = NULL; + Group* group = NULL; + uint64 guid = 0; + char* nameStr = strtok((char*)args, " "); + + if (handler->GetPlayerGroupAndGUIDByName(nameStr, player, group, guid)) + if (group && group->GetLeaderGUID() != guid) + { + group->ChangeLeader(guid); + group->SendUpdate(); + } + + return true; + } + + static bool HandleGroupDisbandCommand(ChatHandler* handler, char const* args) + { + Player* player = NULL; + Group* group = NULL; + uint64 guid = 0; + char* nameStr = strtok((char*)args, " "); + + if (handler->GetPlayerGroupAndGUIDByName(nameStr, player, group, guid)) + if (group) + group->Disband(); + + return true; + } + + static bool HandleGroupRemoveCommand(ChatHandler* handler, char const* args) + { + Player* player = NULL; + Group* group = NULL; + uint64 guid = 0; + char* nameStr = strtok((char*)args, " "); + + if (handler->GetPlayerGroupAndGUIDByName(nameStr, player, group, guid, true)) + if (group) + group->RemoveMember(guid); + + return true; + } + + static bool HandlePlayAllCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + uint32 soundId = atoi((char*)args); + + if (!sSoundEntriesStore.LookupEntry(soundId)) + { + handler->PSendSysMessage(LANG_SOUND_NOT_EXIST, soundId); + handler->SetSentErrorMessage(true); + return false; + } + + WorldPacket data(SMSG_PLAY_SOUND, 4); + data << uint32(soundId) << handler->GetSession()->GetPlayer()->GetGUID(); + sWorld->SendGlobalMessage(&data); + + handler->PSendSysMessage(LANG_COMMAND_PLAYED_TO_ALL, soundId); + return true; + } + + static bool HandlePossessCommand(ChatHandler* handler, char const* /*args*/) + { + Unit* unit = handler->getSelectedUnit(); + if (!unit) + return false; + + handler->GetSession()->GetPlayer()->CastSpell(unit, 530, true); + return true; + } + + static bool HandleUnPossessCommand(ChatHandler* handler, char const* /*args*/) + { + Unit* unit = handler->getSelectedUnit(); + if (!unit) + unit = handler->GetSession()->GetPlayer(); + + unit->RemoveCharmAuras(); + + return true; + } + + static bool HandleBindSightCommand(ChatHandler* handler, char const* /*args*/) + { + Unit* unit = handler->getSelectedUnit(); + if (!unit) + return false; + + handler->GetSession()->GetPlayer()->CastSpell(unit, 6277, true); + return true; + } + + static bool HandleUnbindSightCommand(ChatHandler* handler, char const* /*args*/) + { + Player* player = handler->GetSession()->GetPlayer(); + + if (player->isPossessing()) + return false; + + player->StopCastingBindSight(); + return true; + } +}; + +void AddSC_misc_commandscript() +{ + new misc_commandscript(); +} diff --git a/src/server/shared/Logging/AppenderDB.cpp b/src/server/shared/Logging/AppenderDB.cpp index 76abfca2d85..d85a4db9f7a 100644 --- a/src/server/shared/Logging/AppenderDB.cpp +++ b/src/server/shared/Logging/AppenderDB.cpp @@ -37,7 +37,7 @@ void AppenderDB::_write(LogMessage& message) case LOG_FILTER_SQL_DRIVER: case LOG_FILTER_SQL_DEV: break; // Avoid infinite loop, PExecute triggers Logging with LOG_FILTER_SQL type - default: + default: PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_LOG); stmt->setUInt64(0, message.mtime); stmt->setUInt32(1, realm); diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp index 64f7e697f1f..8e740ba83b8 100755 --- a/src/server/shared/Logging/Log.cpp +++ b/src/server/shared/Logging/Log.cpp @@ -109,7 +109,7 @@ void Log::CreateAppenderFromConfig(const char* name) if (++iter != tokens.end()) flags = AppenderFlags(atoi(*iter)); - + switch (type) { case APPENDER_CONSOLE: -- cgit v1.2.3