From 26dc8c07ab93e8c9759cb18dfc4e79f31be5cd1d Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Tue, 21 Oct 2008 08:05:21 +0400 Subject: [PATCH] * [2008_10_21_01_mangos_mangos_string.sql,2008_10_21_02_mangos_command.sql] Merge CLI command proccessing to chat command proccessing. Now console/RA uas same commads as used in chat if selected command marked as safe for console. Some commands accessable only at console and have security level 4. See sql update for new command names. Not all commands that safe (or can be modified to safe) for console allowed currently for use in console input, this will be fixed later. --- sql/mangos.sql | 54 +- .../2008_10_21_01_mangos_mangos_string.sql | 35 + sql/updates/2008_10_21_02_mangos_command.sql | 23 + sql/updates/Makefile.am | 4 + src/game/Chat.cpp | 770 ++++++----- src/game/Chat.h | 53 +- src/game/Language.h | 42 +- src/game/Level0.cpp | 36 +- src/game/Level1.cpp | 9 +- src/game/Level2.cpp | 10 +- src/game/Level3.cpp | 432 +++++- src/game/World.cpp | 19 +- src/game/World.h | 47 +- src/game/WorldSession.cpp | 2 +- src/game/WorldSession.h | 6 +- src/mangosd/CliRunnable.cpp | 1187 ++--------------- src/mangosd/RASocket.cpp | 31 +- src/mangosd/RASocket.h | 2 +- src/shared/Common.h | 3 +- 19 files changed, 1216 insertions(+), 1549 deletions(-) create mode 100644 sql/updates/2008_10_21_01_mangos_mangos_string.sql create mode 100644 sql/updates/2008_10_21_02_mangos_command.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index 0d93ab7db..f2fc49f27 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -173,7 +173,13 @@ CREATE TABLE `command` ( LOCK TABLES `command` WRITE; /*!40000 ALTER TABLE `command` DISABLE KEYS */; INSERT INTO `command` VALUES -('acct',0,'Syntax: .acct\r\n\r\nDisplay the access level of your account.'), +('account',0,'Syntax: .account\r\n\r\nDisplay the access level of your account.'), +('account create',4,'Syntax: .account create $account $password\r\n\r\nCreate account and set password to it.'), +('account delete',4,'Syntax: .account delete $account\r\n\r\nDelete account with all characters.'), +('account onlinelist',4,'Syntax: .account onlinelist\r\n\r\nShow list of online accounts.'), +('account set addon',3,'Syntax: .account set addon [$account] #addon\r\n\r\nSet user (posible targeted) expansion addon level allowed. Addon values: 0 - normal, 1 - tbc, 2 - wotlk.'), +('account set gmlevel',4,'Syntax: .account set gmlevel [$account] #level\r\n\r\nSet the security level for targeted player (can''t be used at self) or for account $name to a level of #level.\r\n\r\n#level may range from 0 to 3.'), +('account set password',4,'Syntax: .account set password $account $password $password\r\n\r\nSet password for account.'), ('additem',3,'Syntax: .additem #itemid/[#itemname]/#shift-click-item-link #itemcount\r\n\r\nAdds the specified number of items of id #itemid (or exact (!) name $itemname in brackets, or link created by shift-click at item in inventory or recipe) to your or selected character inventory. If #itemcount is omitted, only one item will be added.\r\n.'), ('additemset',3,'Syntax: .additemset #itemsetid\r\n\r\nAdd items from itemset of id #itemsetid to your or selected character inventory. Will add by one example each item from itemset.'), ('addmove',2,'Syntax: .addmove #creature_guid [#waittime]\r\n\r\nAdd your current location as a waypoint for creature with guid #creature_guid. And optional add wait time.'), @@ -188,6 +194,7 @@ INSERT INTO `command` VALUES ('cast dist',3,'Syntax: .cast dist #spellid [#dist [triggered]]\r\n You will cast spell to pint at distance #dist. If \'trigered\' or part provided then spell casted with triggered flag. Not all spells can be casted as area spells.'), ('cast self',3,'Syntax: .cast self #spellid [triggered]\r\nCast #spellid by target at target itself. If \'trigered\' or part provided then spell casted with triggered flag.'), ('cast target',3,'Syntax: .cast target #spellid [triggered]\r\n Selected target will cast #spellid to his victim. If \'trigered\' or part provided then spell casted with triggered flag.'), +('chardelete',4,'Syntax: .chardelete $charactername\r\n\r\nDelete character.'), ('combatstop',2,'Syntax: .combatstop [$playername]\r\nStop combat for selected character. If selected non-player then command applied to self. If $playername provided then attempt applied to online player $playername.'), ('commands',0,'Syntax: .commands\r\n\r\nDisplay a list of available commands for your account level.'), ('cooldown',3,'Syntax: .cooldown [#spell_id]\r\n\r\nRemove all (if spell_id not provided) or #spel_id spell cooldown from selected character or you (if no selection).'), @@ -211,7 +218,9 @@ INSERT INTO `command` VALUES ('gm',1,'Syntax: .gm [on/off]\r\n\r\nEnable or Disable in game GM MODE or show current state of on/off not provided.'), ('gm chat',1,'Syntax: .gm chat [on/off]\r\n\r\nEnable or disable chat GM MODE (show gm badge in messages) or show current state of on/off not provided.'), ('gm fly',3,'Syntax: .gm fly on/off\r\nEnable/disable gm fly mode.'), -('gm list',0,'Syntax: .gm list\r\n\r\nDisplay a list of available Game Masters.'), + +('gm list',3,'Syntax: .gm list\r\n\r\nDisplay a list of all Game Masters accounts and security levels.'), +('gm online',0,'Syntax: .gm online\r\n\r\nDisplay a list of available Game Masters.'), ('gm visible',1,'Syntax: .gm visible on/off\r\n\r\nOutput current visibility state or make GM visible(on) and invisible(off) for other players.'), ('go creature',2,'Syntax: .go creature #creature_guid\r\nTeleport your character to creature with guid #creature_guid.\r\n.gocreature #creature_name\r\nTeleport your character to creature with this name.\r\n.gocreature id #creature_id\r\nTeleport your character to a creature that was spawned from the template with this entry.\r\n*If* more than one creature is found, then you are teleported to the first that is found inside the database.'), ('go graveyard',2,'Syntax: .go graveyard #graveyardId\r\n Teleport to graveyard with the graveyardId specified.'), @@ -351,12 +360,17 @@ INSERT INTO `command` VALUES ('revive',3,'Syntax: .revive\r\n\r\nRevive the selected player. If no player is selected, it will revive you.'), ('save',0,'Syntax: .save\r\n\r\nSaves your character.'), ('saveall',1,'Syntax: .saveall\r\n\r\nSave all characters in game.'), -('security',3,'Syntax: .security $name #level\r\n\r\nSet the security level of player $name to a level of #level.\r\n\r\n#level may range from 0 to 5.'), ('sendmail',1,'Syntax: .sendmail #playername "#subject" "#text" itemid1[:count1] itemid2[:count2] ... itemidN[:countN]\r\n\r\nSend a mail to a player. Subject and mail text must be in "". If for itemid not provided related count values then expected 1, if count > max items in stack then items will be send in required amount stacks. All stacks amount in mail limited to 12.'), +('sendmessage',3,'Syntax: .sendmessage $playername $message\r\n\r\nSend screen message to player from ADMINISTRATOR.'), +('server corpses',2,'Syntax: .server corpses\r\n\r\nTriggering corpses expire check in world.'), +('server exit',4,'Syntax: .server exit\r\n\r\nTerminate mangosd NOW.'), ('server info',0,'Syntax: .server info\r\n\r\nDisplay server version and the number of connected players.'), ('server idleshutdown',3,'Syntax: .server idleshutdown #delay|cancel\r\n\r\nShut the server down after #delay seconds if no active connections are present (no players) or cancel the restart/shutdown if cancel value is used.'), ('server idlerestart',3,'Syntax: .server idlerestart #delay|cancel\r\n\r\nRestart the server after #delay seconds if no active connections are present (no players) or cancel the restart/shutdown if cancel value is used.'), +('server motd',0,'Syntax: .server motd\r\n\r\nShow server Message of the day.'), ('server restart',3,'Syntax: .server restart seconds\r\n\r\nRestart the server after given seconds and show "Restart server in X" or cancel the restart/shutdown if cancel value is used.'), +('server set loglevel',4,'Syntax: .server set loglevel #level\r\n\r\nSet server log level (0 - errors only, 1 - basic, 2 - detail, 3 - debug).'), +('server set motd',3,'Syntax: .server set motd $MOTD\r\n\r\nSet server Message of the day.'), ('server shutdown',3,'Syntax: .server shutdown seconds\r\n\r\nShut the server down after given seconds and show "Off server in X" or cancel the restart/shutdown if cancel value is used.'), ('setskill',3,'Syntax: .setskill #skill #level [#max]\r\n\r\nSet a skill of id #skill with a current skill value of #level and a maximum value of #max (or equal current maximum if not provide) for the selected character. If no character is selected, you learn the skill.'), ('showarea',3,'Syntax: .showarea #areaid\r\n\r\nReveal the area of #areaid to the selected character. If no character is selected, reveal this area to you.'), @@ -2103,7 +2117,7 @@ INSERT INTO `mangos_string` VALUES (22,'You are not mounted so you can\'t dismount.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (23,'Cannot do that while fighting.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (24,'You used it recently.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), -(25,'Your password can\'t be longer than 16 characters (client limit), password not changed!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(25,'Password not changed (unknown error)!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (26,'The password was changed',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (27,'The new passwords do not match or the old password is wrong',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (28,'Your account is now locked.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), @@ -2132,6 +2146,9 @@ INSERT INTO `mangos_string` VALUES (51,'Hello! Ready for some training?',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (52,'Invaid item count (%u) for item %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (53,'Mail can\'t have more %u item stacks',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(54,'The new passwords do not match',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(55,'Your password can\'t be longer than 16 characters (client limit), password not changed!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(56,'Current Message of the day: \r\n%s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (100,'Global notify: ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (101,'Map: %u (%s) Zone: %u (%s) Area: %u (%s)\nX: %f Y: %f Z: %f Orientation: %f\ngrid[%u,%u]cell[%u,%u] InstanceID: %u\n ZoneX: %f ZoneY: %f\nGroundZ: %f FloorZ: %f Have height data (Map: %u VMap: %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (102,'%s is already being teleported.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), @@ -2202,6 +2219,7 @@ INSERT INTO `mangos_string` VALUES (168,'Locations found are:\n %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (169,'Mail sent to %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (170,'You try to hear sound %u but it doesn\'t exist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(171,'You are being teleported by server console command.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (200,'No selection.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (201,'Object GUID is: lowpart %u highpart %X',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (202,'The name was too long by %i characters.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), @@ -2339,7 +2357,7 @@ INSERT INTO `mangos_string` VALUES (334,'GM Chat Badge is ON',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (335,'GM Chat Badge is OFF',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (400,'|cffff0000[System Message]:|rScripts reloaded',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), -(401,'You change security level of %s to %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(401,'You change security level of account %s to %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (402,'%s changed your security level to %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (403,'You have low security level for this.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (404,'Creature movement disabled.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), @@ -2351,7 +2369,7 @@ INSERT INTO `mangos_string` VALUES (410,'%s %s not found',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (411,'%s unbanned.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (412,'There was an error removing the ban on %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), -(413,'There is no such account.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(413,'Account not exist: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (414,'There is no such character.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (415,'There is no such IP in banlist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (416,'Account %s has never been banned',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), @@ -2530,6 +2548,13 @@ INSERT INTO `mangos_string` VALUES (590,' Fear movement',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (591,' Distract movement',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (592,'You have learned all spells in craft: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(593,'Currently Banned Accounts:',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(594,'| Account | BanDate | UnbanDate | Banned By | Ban Reason |',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(595,'Currently Banned IPs:',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(596,'| IP | BanDate | UnbanDate | Banned By | Ban Reason |',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(597,'Current gamemasters:',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(598,'| Account | GM |',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(599,'No gamemasters.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (600,'The Alliance wins!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (601,'The Horde wins!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (602,'The battle for Warsong Gulch begins in 1 minute.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), @@ -2589,7 +2614,22 @@ INSERT INTO `mangos_string` VALUES (806,'You don\'t know that language',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (807,'Please provide character name',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (808,'Player %s not found or offline',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), -(809,'Account for character %s not found',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); +(809,'Account for character %s not found',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1000,'Exiting daemon...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1001,'Account deleted: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1002,'Account %s NOT deleted (probably sql file format was updated)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1003,'Account %s NOT deleted (unknown error)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1004,'Account created: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1005,'Account name can\'t be longer than 16 characters (client limit), account not created!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1006,'Account with this name already exist!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1007,'Account %s NOT created (probably sql file format was updated)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1008,'Account %s NOT created (unknown error)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1009,'Player %s (Guid: %u) Account %s (Id: %u) deleted.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1010,'| Account | Character | IP | GM | TBC |',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1011,'| | %20s | |||',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1100,'Account %s (Id: %u) have up to %u expansion allowed now.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1101,'Message of the day changed to:\r\n%s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1102,'Message sent to %s: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); /*!40000 ALTER TABLE `mangos_string` ENABLE KEYS */; UNLOCK TABLES; diff --git a/sql/updates/2008_10_21_01_mangos_mangos_string.sql b/sql/updates/2008_10_21_01_mangos_mangos_string.sql new file mode 100644 index 000000000..fa7dee886 --- /dev/null +++ b/sql/updates/2008_10_21_01_mangos_mangos_string.sql @@ -0,0 +1,35 @@ +DELETE FROM mangos_string WHERE entry IN ( + 25,54,55,56,171,401,413,593,594,595,596,597,598,599, + 1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1100,1101,1102 +); + +INSERT INTO mangos_string VALUES +(25,'Password not changed (unknown error)!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(54,'The new passwords do not match',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(55,'Your password can\'t be longer than 16 characters (client limit), password not changed!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(56,'Current Message of the day: \r\n%s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(171,'You are being teleported by server console command.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(401,'You change security level of account %s to %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(413,'Account not exist: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(593,'Currently Banned Accounts:',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(594,'| Account | BanDate | UnbanDate | Banned By | Ban Reason |',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(595,'Currently Banned IPs:',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(596,'| IP | BanDate | UnbanDate | Banned By | Ban Reason |',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(597,'Current gamemasters:',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(598,'| Account | GM |',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(599,'No gamemasters.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1000,'Exiting daemon...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1001,'Account deleted: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1002,'Account %s NOT deleted (probably sql file format was updated)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1003,'Account %s NOT deleted (unknown error)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1004,'Account created: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1005,'Account name can\'t be longer than 16 characters (client limit), account not created!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1006,'Account with this name already exist!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1007,'Account %s NOT created (probably sql file format was updated)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1008,'Account %s NOT created (unknown error)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1009,'Player %s (Guid: %u) Account %s (Id: %u) deleted.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1010,'| Account | Character | IP | GM | TBC |',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1011,'| | %20s | |||',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1100,'Account %s (Id: %u) have up to %u expansion allowed now.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1101,'Message of the day changed to:\r\n%s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1102,'Message sent to %s: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/2008_10_21_02_mangos_command.sql b/sql/updates/2008_10_21_02_mangos_command.sql new file mode 100644 index 000000000..9586cf236 --- /dev/null +++ b/sql/updates/2008_10_21_02_mangos_command.sql @@ -0,0 +1,23 @@ +DELETE FROM command WHERE name IN ( + 'acct','account','account create','account delete','account onlinelist', + 'account set addon','account set gmlevel','account set password', + 'chardelete','gm list','gm online','sendmessage','server corpses','server exit','server motd', + 'server set loglevel','server set motd','security' +); +INSERT INTO `command` VALUES +('account',0,'Syntax: .account\r\n\r\nDisplay the access level of your account.'), +('account create',4,'Syntax: .account create $account $password\r\n\r\nCreate account and set password to it.'), +('account delete',4,'Syntax: .account delete $account\r\n\r\nDelete account with all characters.'), +('account onlinelist',4,'Syntax: .account onlinelist\r\n\r\nShow list of online accounts.'), +('account set addon',3,'Syntax: .account set addon [$account] #addon\r\n\r\nSet user (posible targeted) expansion addon level allowed. Addon values: 0 - normal, 1 - tbc, 2 - wotlk.'), +('account set gmlevel',4,'Syntax: .account set gmlevel [$account] #level\r\n\r\nSet the security level for targeted player (can''t be used at self) or for account $name to a level of #level.\r\n\r\n#level may range from 0 to 3.'), +('account set password',4,'Syntax: .account set password $account $password $password\r\n\r\nSet password for account.'), +('chardelete',4,'Syntax: .chardelete $charactername\r\n\r\nDelete character.'), +('gm list',3,'Syntax: .gm list\r\n\r\nDisplay a list of all Game Masters accounts and security levels.'), +('gm online',0,'Syntax: .gm online\r\n\r\nDisplay a list of available Game Masters.'), +('sendmessage',3,'Syntax: .sendmessage $playername $message\r\n\r\nSend screen message to player from ADMINISTRATOR.'), +('server corpses',2,'Syntax: .server corpses\r\n\r\nTriggering corpses expire check in world.'), +('server exit',4,'Syntax: .server exit\r\n\r\nTerminate mangosd NOW.'), +('server motd',0,'Syntax: .server motd\r\n\r\nShow server Message of the day.'), +('server set loglevel',4,'Syntax: .server set loglevel #level\r\n\r\nSet server log level (0 - errors only, 1 - basic, 2 - detail, 3 - debug).'), +('server set motd',3,'Syntax: .server set motd $MOTD\r\n\r\nSet server Message of the day.'); diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 6236fb7d3..99f31fd14 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -96,6 +96,8 @@ pkgdata_DATA = \ 2008_10_18_02_mangos_spell_proc_event.sql \ 2008_10_19_01_mangos_spell_affect.sql \ 2008_10_19_02_mangos_spell_proc_event.sql \ + 2008_10_21_01_mangos_mangos_string.sql \ + 2008_10_21_02_mangos_command.sql \ README ## Additional files to include when running 'make dist' @@ -173,4 +175,6 @@ EXTRA_DIST = \ 2008_10_18_02_mangos_spell_proc_event.sql \ 2008_10_19_01_mangos_spell_affect.sql \ 2008_10_19_02_mangos_spell_proc_event.sql \ + 2008_10_21_01_mangos_mangos_string.sql \ + 2008_10_21_02_mangos_command.sql \ README diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index c79eb653c..2fdfc42dc 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -36,436 +36,467 @@ bool ChatHandler::load_command_table = true; ChatCommand * ChatHandler::getCommandTable() { + static ChatCommand accountSetCommandTable[] = + { + { "addon", SEC_ADMINISTRATOR, true, &ChatHandler::HandleAccountSetAddonCommand, "", NULL }, + { "gmlevel", SEC_CONSOLE, true, &ChatHandler::HandleAccountSetGmLevelCommand, "", NULL }, + { "password", SEC_CONSOLE, true, &ChatHandler::HandleAccountSetPasswordCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + + static ChatCommand accountCommandTable[] = + { + { "create", SEC_CONSOLE, true, &ChatHandler::HandleAccountCreateCommand, "", NULL }, + { "delete", SEC_CONSOLE, true, &ChatHandler::HandleAccountDeleteCommand, "", NULL }, + { "onlinelist", SEC_CONSOLE, true, &ChatHandler::HandleAccountOnlineListCommand, "", NULL }, + { "set", SEC_ADMINISTRATOR, true, NULL, "", accountSetCommandTable }, + { "", SEC_PLAYER, true, &ChatHandler::HandleAccountCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + + static ChatCommand serverSetCommandTable[] = + { + { "loglevel", SEC_CONSOLE, true, &ChatHandler::HandleServerSetLogLevelCommand, "", NULL }, + { "motd", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerSetMotdCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand serverCommandTable[] = { - { "idlerestart", SEC_ADMINISTRATOR, &ChatHandler::HandleIdleRestartCommand, "", NULL }, - { "idleshutdown", SEC_ADMINISTRATOR, &ChatHandler::HandleIdleShutDownCommand, "", NULL }, - { "info", SEC_PLAYER, &ChatHandler::HandleInfoCommand, "", NULL }, - { "restart", SEC_ADMINISTRATOR, &ChatHandler::HandleRestartCommand, "", NULL }, - { "shutdown", SEC_ADMINISTRATOR, &ChatHandler::HandleShutDownCommand, "", NULL }, - { NULL, 0, NULL, "", NULL } + { "corpses", SEC_GAMEMASTER, true, &ChatHandler::HandleServerCorpsesCommand, "", NULL }, + { "exit", SEC_CONSOLE, true, &ChatHandler::HandleServerExitCommand, "", NULL }, + { "idlerestart", SEC_ADMINISTRATOR, true, &ChatHandler::HandleIdleRestartCommand, "", NULL }, + { "idleshutdown", SEC_ADMINISTRATOR, true, &ChatHandler::HandleIdleShutDownCommand, "", NULL }, + { "info", SEC_PLAYER, true, &ChatHandler::HandleInfoCommand, "", NULL }, + { "motd", SEC_PLAYER, true, &ChatHandler::HandleServerMotdCommand, "", NULL }, + { "restart", SEC_ADMINISTRATOR, true, &ChatHandler::HandleRestartCommand, "", NULL }, + { "shutdown", SEC_ADMINISTRATOR, true, &ChatHandler::HandleShutDownCommand, "", NULL }, + { "set", SEC_ADMINISTRATOR, true, NULL, "", serverSetCommandTable }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand modifyCommandTable[] = { - { "hp", SEC_MODERATOR, &ChatHandler::HandleModifyHPCommand, "", NULL }, - { "mana", SEC_MODERATOR, &ChatHandler::HandleModifyManaCommand, "", NULL }, - { "rage", SEC_MODERATOR, &ChatHandler::HandleModifyRageCommand, "", NULL }, - { "energy", SEC_MODERATOR, &ChatHandler::HandleModifyEnergyCommand, "", NULL }, - { "money", SEC_MODERATOR, &ChatHandler::HandleModifyMoneyCommand, "", NULL }, - { "speed", SEC_MODERATOR, &ChatHandler::HandleModifySpeedCommand, "", NULL }, - { "swim", SEC_MODERATOR, &ChatHandler::HandleModifySwimCommand, "", NULL }, - { "scale", SEC_MODERATOR, &ChatHandler::HandleModifyScaleCommand, "", NULL }, - { "bit", SEC_MODERATOR, &ChatHandler::HandleModifyBitCommand, "", NULL }, - { "bwalk", SEC_MODERATOR, &ChatHandler::HandleModifyBWalkCommand, "", NULL }, - { "fly", SEC_MODERATOR, &ChatHandler::HandleModifyFlyCommand, "", NULL }, - { "aspeed", SEC_MODERATOR, &ChatHandler::HandleModifyASpeedCommand, "", NULL }, - { "faction", SEC_MODERATOR, &ChatHandler::HandleModifyFactionCommand, "", NULL }, - { "spell", SEC_MODERATOR, &ChatHandler::HandleModifySpellCommand, "", NULL }, - { "tp", SEC_MODERATOR, &ChatHandler::HandleModifyTalentCommand, "", NULL }, - { "titles", SEC_MODERATOR, &ChatHandler::HandleModifyKnownTitlesCommand, "", NULL }, - { "mount", SEC_MODERATOR, &ChatHandler::HandleModifyMountCommand, "", NULL }, - { "honor", SEC_MODERATOR, &ChatHandler::HandleModifyHonorCommand, "", NULL }, - { "rep", SEC_MODERATOR, &ChatHandler::HandleModifyRepCommand, "", NULL }, - { "arena", SEC_MODERATOR, &ChatHandler::HandleModifyArenaCommand, "", NULL }, - { "drunk", SEC_MODERATOR, &ChatHandler::HandleDrunkCommand, "", NULL }, - { "standstate", SEC_GAMEMASTER, &ChatHandler::HandleStandStateCommand, "", NULL }, - { "morph", SEC_GAMEMASTER, &ChatHandler::HandleMorphCommand, "", NULL }, - { NULL, 0, NULL, "", NULL } + { "hp", SEC_MODERATOR, false, &ChatHandler::HandleModifyHPCommand, "", NULL }, + { "mana", SEC_MODERATOR, false, &ChatHandler::HandleModifyManaCommand, "", NULL }, + { "rage", SEC_MODERATOR, false, &ChatHandler::HandleModifyRageCommand, "", NULL }, + { "energy", SEC_MODERATOR, false, &ChatHandler::HandleModifyEnergyCommand, "", NULL }, + { "money", SEC_MODERATOR, false, &ChatHandler::HandleModifyMoneyCommand, "", NULL }, + { "speed", SEC_MODERATOR, false, &ChatHandler::HandleModifySpeedCommand, "", NULL }, + { "swim", SEC_MODERATOR, false, &ChatHandler::HandleModifySwimCommand, "", NULL }, + { "scale", SEC_MODERATOR, false, &ChatHandler::HandleModifyScaleCommand, "", NULL }, + { "bit", SEC_MODERATOR, false, &ChatHandler::HandleModifyBitCommand, "", NULL }, + { "bwalk", SEC_MODERATOR, false, &ChatHandler::HandleModifyBWalkCommand, "", NULL }, + { "fly", SEC_MODERATOR, false, &ChatHandler::HandleModifyFlyCommand, "", NULL }, + { "aspeed", SEC_MODERATOR, false, &ChatHandler::HandleModifyASpeedCommand, "", NULL }, + { "faction", SEC_MODERATOR, false, &ChatHandler::HandleModifyFactionCommand, "", NULL }, + { "spell", SEC_MODERATOR, false, &ChatHandler::HandleModifySpellCommand, "", NULL }, + { "tp", SEC_MODERATOR, false, &ChatHandler::HandleModifyTalentCommand, "", NULL }, + { "titles", SEC_MODERATOR, false, &ChatHandler::HandleModifyKnownTitlesCommand, "", NULL }, + { "mount", SEC_MODERATOR, false, &ChatHandler::HandleModifyMountCommand, "", NULL }, + { "honor", SEC_MODERATOR, false, &ChatHandler::HandleModifyHonorCommand, "", NULL }, + { "rep", SEC_MODERATOR, false, &ChatHandler::HandleModifyRepCommand, "", NULL }, + { "arena", SEC_MODERATOR, false, &ChatHandler::HandleModifyArenaCommand, "", NULL }, + { "drunk", SEC_MODERATOR, false, &ChatHandler::HandleDrunkCommand, "", NULL }, + { "standstate", SEC_GAMEMASTER, false, &ChatHandler::HandleStandStateCommand, "", NULL }, + { "morph", SEC_GAMEMASTER, false, &ChatHandler::HandleMorphCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand wpCommandTable[] = { - { "show", SEC_GAMEMASTER, &ChatHandler::HandleWpShowCommand, "", NULL }, - { "add", SEC_GAMEMASTER, &ChatHandler::HandleWpAddCommand, "", NULL }, - { "modify", SEC_GAMEMASTER, &ChatHandler::HandleWpModifyCommand, "", NULL }, - { "export", SEC_ADMINISTRATOR, &ChatHandler::HandleWpExportCommand, "", NULL }, - { "import", SEC_ADMINISTRATOR, &ChatHandler::HandleWpImportCommand, "", NULL }, - { NULL, 0, NULL, "", NULL } + { "show", SEC_GAMEMASTER, false, &ChatHandler::HandleWpShowCommand, "", NULL }, + { "add", SEC_GAMEMASTER, false, &ChatHandler::HandleWpAddCommand, "", NULL }, + { "modify", SEC_GAMEMASTER, false, &ChatHandler::HandleWpModifyCommand, "", NULL }, + { "export", SEC_ADMINISTRATOR, false, &ChatHandler::HandleWpExportCommand, "", NULL }, + { "import", SEC_ADMINISTRATOR, false, &ChatHandler::HandleWpImportCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand debugCommandTable[] = { - { "inarc", SEC_ADMINISTRATOR, &ChatHandler::HandleDebugInArcCommand, "", NULL }, - { "spellfail", SEC_ADMINISTRATOR, &ChatHandler::HandleDebugSpellFailCommand, "", NULL }, - { "setpoi", SEC_ADMINISTRATOR, &ChatHandler::HandleSetPoiCommand, "", NULL }, - { "qpartymsg", SEC_ADMINISTRATOR, &ChatHandler::HandleSendQuestPartyMsgCommand, "", NULL }, - { "qinvalidmsg", SEC_ADMINISTRATOR, &ChatHandler::HandleSendQuestInvalidMsgCommand, "", NULL }, - { "equiperr", SEC_ADMINISTRATOR, &ChatHandler::HandleEquipErrorCommand, "", NULL }, - { "sellerr", SEC_ADMINISTRATOR, &ChatHandler::HandleSellErrorCommand, "", NULL }, - { "buyerr", SEC_ADMINISTRATOR, &ChatHandler::HandleBuyErrorCommand, "", NULL }, - { "sendopcode", SEC_ADMINISTRATOR, &ChatHandler::HandleSendOpcodeCommand, "", NULL }, - { "uws", SEC_ADMINISTRATOR, &ChatHandler::HandleUpdateWorldStateCommand, "", NULL }, - { "ps", SEC_ADMINISTRATOR, &ChatHandler::HandlePlaySound2Command, "", NULL }, - { "scn", SEC_ADMINISTRATOR, &ChatHandler::HandleSendChannelNotifyCommand, "", NULL }, - { "scm", SEC_ADMINISTRATOR, &ChatHandler::HandleSendChatMsgCommand, "", NULL }, - { "getitemstate", SEC_ADMINISTRATOR, &ChatHandler::HandleGetItemState, "", NULL }, - { "playsound", SEC_MODERATOR, &ChatHandler::HandlePlaySoundCommand, "", NULL }, - { "update", SEC_ADMINISTRATOR, &ChatHandler::HandleUpdate, "", NULL }, - { "setvalue", SEC_ADMINISTRATOR, &ChatHandler::HandleSetValue, "", NULL }, - { "getvalue", SEC_ADMINISTRATOR, &ChatHandler::HandleGetValue, "", NULL }, - { "Mod32Value", SEC_ADMINISTRATOR, &ChatHandler::HandleMod32Value, "", NULL }, - { "anim", SEC_GAMEMASTER, &ChatHandler::HandleAnimCommand, "", NULL }, - { "lootrecipient", SEC_GAMEMASTER, &ChatHandler::HandleGetLootRecipient, "", NULL }, - { NULL, 0, NULL, "", NULL } + { "inarc", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugInArcCommand, "", NULL }, + { "spellfail", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSpellFailCommand, "", NULL }, + { "setpoi", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSetPoiCommand, "", NULL }, + { "qpartymsg", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSendQuestPartyMsgCommand, "", NULL }, + { "qinvalidmsg", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSendQuestInvalidMsgCommand, "", NULL }, + { "equiperr", SEC_ADMINISTRATOR, false, &ChatHandler::HandleEquipErrorCommand, "", NULL }, + { "sellerr", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSellErrorCommand, "", NULL }, + { "buyerr", SEC_ADMINISTRATOR, false, &ChatHandler::HandleBuyErrorCommand, "", NULL }, + { "sendopcode", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSendOpcodeCommand, "", NULL }, + { "uws", SEC_ADMINISTRATOR, false, &ChatHandler::HandleUpdateWorldStateCommand, "", NULL }, + { "ps", SEC_ADMINISTRATOR, false, &ChatHandler::HandlePlaySound2Command, "", NULL }, + { "scn", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSendChannelNotifyCommand, "", NULL }, + { "scm", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSendChatMsgCommand, "", NULL }, + { "getitemstate", SEC_ADMINISTRATOR, false, &ChatHandler::HandleGetItemState, "", NULL }, + { "playsound", SEC_MODERATOR, false, &ChatHandler::HandlePlaySoundCommand, "", NULL }, + { "update", SEC_ADMINISTRATOR, false, &ChatHandler::HandleUpdate, "", NULL }, + { "setvalue", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSetValue, "", NULL }, + { "getvalue", SEC_ADMINISTRATOR, false, &ChatHandler::HandleGetValue, "", NULL }, + { "Mod32Value", SEC_ADMINISTRATOR, false, &ChatHandler::HandleMod32Value, "", NULL }, + { "anim", SEC_GAMEMASTER, false, &ChatHandler::HandleAnimCommand, "", NULL }, + { "lootrecipient", SEC_GAMEMASTER, false, &ChatHandler::HandleGetLootRecipient, "", NULL }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand eventCommandTable[] = { - { "activelist", SEC_GAMEMASTER, &ChatHandler::HandleEventActiveListCommand, "", NULL }, - { "start", SEC_GAMEMASTER, &ChatHandler::HandleEventStartCommand, "", NULL }, - { "stop", SEC_GAMEMASTER, &ChatHandler::HandleEventStopCommand, "", NULL }, - { "", SEC_GAMEMASTER, &ChatHandler::HandleEventInfoCommand, "", NULL }, - { NULL, 0, NULL, "", NULL } + { "activelist", SEC_GAMEMASTER, false, &ChatHandler::HandleEventActiveListCommand, "", NULL }, + { "start", SEC_GAMEMASTER, false, &ChatHandler::HandleEventStartCommand, "", NULL }, + { "stop", SEC_GAMEMASTER, false, &ChatHandler::HandleEventStopCommand, "", NULL }, + { "", SEC_GAMEMASTER, false, &ChatHandler::HandleEventInfoCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand learnCommandTable[] = { - { "all", SEC_ADMINISTRATOR, &ChatHandler::HandleLearnAllCommand, "", NULL }, - { "all_gm", SEC_GAMEMASTER, &ChatHandler::HandleLearnAllGMCommand, "", NULL }, - { "all_crafts", SEC_GAMEMASTER, &ChatHandler::HandleLearnAllCraftsCommand, "", NULL }, - { "all_default", SEC_MODERATOR, &ChatHandler::HandleLearnAllDefaultCommand, "", NULL }, - { "all_lang", SEC_MODERATOR, &ChatHandler::HandleLearnAllLangCommand, "", NULL }, - { "all_myclass", SEC_ADMINISTRATOR, &ChatHandler::HandleLearnAllMyClassCommand, "", NULL }, - { "all_myspells", SEC_ADMINISTRATOR, &ChatHandler::HandleLearnAllMySpellsCommand, "", NULL }, - { "all_mytalents", SEC_ADMINISTRATOR, &ChatHandler::HandleLearnAllMyTalentsCommand, "", NULL }, - { "all_recipes", SEC_GAMEMASTER, &ChatHandler::HandleLearnAllRecipesCommand, "", NULL }, - { "", SEC_ADMINISTRATOR, &ChatHandler::HandleLearnCommand, "", NULL }, - { NULL, 0, NULL, "", NULL } + { "all", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLearnAllCommand, "", NULL }, + { "all_gm", SEC_GAMEMASTER, false, &ChatHandler::HandleLearnAllGMCommand, "", NULL }, + { "all_crafts", SEC_GAMEMASTER, false, &ChatHandler::HandleLearnAllCraftsCommand, "", NULL }, + { "all_default", SEC_MODERATOR, false, &ChatHandler::HandleLearnAllDefaultCommand, "", NULL }, + { "all_lang", SEC_MODERATOR, false, &ChatHandler::HandleLearnAllLangCommand, "", NULL }, + { "all_myclass", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLearnAllMyClassCommand, "", NULL }, + { "all_myspells", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLearnAllMySpellsCommand, "", NULL }, + { "all_mytalents", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLearnAllMyTalentsCommand, "", NULL }, + { "all_recipes", SEC_GAMEMASTER, false, &ChatHandler::HandleLearnAllRecipesCommand, "", NULL }, + { "", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLearnCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand reloadCommandTable[] = { - { "all", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadAllCommand, "", NULL }, - { "all_loot", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadAllLootCommand, "", NULL }, - { "all_npc", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadAllNpcCommand, "", NULL }, - { "all_quest", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadAllQuestCommand, "", NULL }, - { "all_scripts", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadAllScriptsCommand, "", NULL }, - { "all_spell", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadAllSpellCommand, "", NULL }, - { "all_item", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadAllItemCommand, "", NULL }, - { "all_locales", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadAllLocalesCommand, "", NULL }, + { "all", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadAllCommand, "", NULL }, + { "all_loot", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadAllLootCommand, "", NULL }, + { "all_npc", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadAllNpcCommand, "", NULL }, + { "all_quest", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadAllQuestCommand, "", NULL }, + { "all_scripts", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadAllScriptsCommand, "", NULL }, + { "all_spell", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadAllSpellCommand, "", NULL }, + { "all_item", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadAllItemCommand, "", NULL }, + { "all_locales", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadAllLocalesCommand, "", NULL }, - { "config", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadConfigCommand, "", NULL }, + { "config", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadConfigCommand, "", NULL }, - { "areatrigger_tavern", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadAreaTriggerTavernCommand, "", NULL }, - { "areatrigger_teleport", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadAreaTriggerTeleportCommand, "", NULL }, - { "areatrigger_involvedrelation",SEC_ADMINISTRATOR, &ChatHandler::HandleReloadQuestAreaTriggersCommand, "", NULL }, - { "event_scripts", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadEventScriptsCommand, "", NULL }, - { "command", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadCommandCommand, "", NULL }, - { "creature_involvedrelation", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadCreatureQuestInvRelationsCommand,"",NULL }, - { "creature_loot_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesCreatureCommand, "", NULL }, - { "creature_questrelation", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadCreatureQuestRelationsCommand, "", NULL }, - { "disenchant_loot_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesDisenchantCommand, "", NULL }, - { "fishing_loot_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesFishingCommand, "", NULL }, - { "game_graveyard_zone", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadGameGraveyardZoneCommand, "", NULL }, - { "game_tele", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadGameTeleCommand, "", NULL }, - { "gameobject_involvedrelation", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadGOQuestInvRelationsCommand, "", NULL }, - { "gameobject_loot_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesGameobjectCommand, "", NULL }, - { "gameobject_questrelation", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadGOQuestRelationsCommand, "", NULL }, - { "gameobject_scripts", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadGameObjectScriptsCommand, "", NULL }, - { "item_enchantment_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadItemEnchantementsCommand, "", NULL }, - { "item_loot_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesItemCommand, "", NULL }, - { "mangos_string", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadMangosStringCommand, "", NULL }, - { "npc_gossip", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadNpcGossipCommand, "", NULL }, - { "npc_trainer", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadNpcTrainerCommand, "", NULL }, - { "npc_vendor", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadNpcVendorCommand, "", NULL }, - { "page_text", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadPageTextsCommand, "", NULL }, - { "pickpocketing_loot_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesPickpocketingCommand,"",NULL}, - { "prospecting_loot_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesProspectingCommand,"", NULL }, - { "quest_mail_loot_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesQuestMailCommand, "", NULL }, - { "quest_end_scripts", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadQuestEndScriptsCommand, "", NULL }, - { "quest_start_scripts", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadQuestStartScriptsCommand, "", NULL }, - { "quest_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadQuestTemplateCommand, "", NULL }, - { "reference_loot_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesReferenceCommand, "", NULL }, - { "reserved_name", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadReservedNameCommand, "", NULL }, - { "skill_discovery_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSkillDiscoveryTemplateCommand, "", NULL }, - { "skill_extra_item_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSkillExtraItemTemplateCommand, "", NULL }, - { "skill_fishing_base_level", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSkillFishingBaseLevelCommand, "", NULL }, - { "skinning_loot_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesSkinningCommand, "", NULL }, - { "spell_affect", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellAffectCommand, "", NULL }, - { "spell_chain", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellChainCommand, "", NULL }, - { "spell_elixir", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellElixirCommand, "", NULL }, - { "spell_learn_spell", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellLearnSpellCommand, "", NULL }, - { "spell_pet_auras", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellPetAurasCommand, "", NULL }, - { "spell_proc_event", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellProcEventCommand, "", NULL }, - { "spell_script_target", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellScriptTargetCommand, "", NULL }, - { "spell_scripts", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellScriptsCommand, "", NULL }, - { "spell_target_position", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellTargetPositionCommand, "", NULL }, - { "spell_threats", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellThreatsCommand, "", NULL }, - { "locales_creature", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLocalesCreatureCommand, "", NULL }, - { "locales_gameobject", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLocalesGameobjectCommand, "", NULL }, - { "locales_item", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLocalesItemCommand, "", NULL }, - { "locales_npc_text", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLocalesNpcTextCommand, "", NULL }, - { "locales_page_text", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLocalesPageTextCommand, "", NULL }, - { "locales_quest", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLocalesQuestCommand, "", NULL }, + { "areatrigger_tavern", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadAreaTriggerTavernCommand, "", NULL }, + { "areatrigger_teleport", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadAreaTriggerTeleportCommand, "", NULL }, + { "areatrigger_involvedrelation",SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadQuestAreaTriggersCommand, "", NULL }, + { "event_scripts", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadEventScriptsCommand, "", NULL }, + { "command", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadCommandCommand, "", NULL }, + { "creature_involvedrelation", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadCreatureQuestInvRelationsCommand,"",NULL }, + { "creature_loot_template", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadLootTemplatesCreatureCommand, "", NULL }, + { "creature_questrelation", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadCreatureQuestRelationsCommand, "", NULL }, + { "disenchant_loot_template", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadLootTemplatesDisenchantCommand, "", NULL }, + { "fishing_loot_template", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadLootTemplatesFishingCommand, "", NULL }, + { "game_graveyard_zone", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadGameGraveyardZoneCommand, "", NULL }, + { "game_tele", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadGameTeleCommand, "", NULL }, + { "gameobject_involvedrelation", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadGOQuestInvRelationsCommand, "", NULL }, + { "gameobject_loot_template", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadLootTemplatesGameobjectCommand, "", NULL }, + { "gameobject_questrelation", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadGOQuestRelationsCommand, "", NULL }, + { "gameobject_scripts", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadGameObjectScriptsCommand, "", NULL }, + { "item_enchantment_template", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadItemEnchantementsCommand, "", NULL }, + { "item_loot_template", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadLootTemplatesItemCommand, "", NULL }, + { "mangos_string", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadMangosStringCommand, "", NULL }, + { "npc_gossip", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadNpcGossipCommand, "", NULL }, + { "npc_trainer", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadNpcTrainerCommand, "", NULL }, + { "npc_vendor", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadNpcVendorCommand, "", NULL }, + { "page_text", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadPageTextsCommand, "", NULL }, + { "pickpocketing_loot_template", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadLootTemplatesPickpocketingCommand,"",NULL}, + { "prospecting_loot_template", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadLootTemplatesProspectingCommand,"", NULL }, + { "quest_mail_loot_template", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadLootTemplatesQuestMailCommand, "", NULL }, + { "quest_end_scripts", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadQuestEndScriptsCommand, "", NULL }, + { "quest_start_scripts", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadQuestStartScriptsCommand, "", NULL }, + { "quest_template", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadQuestTemplateCommand, "", NULL }, + { "reference_loot_template", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadLootTemplatesReferenceCommand, "", NULL }, + { "reserved_name", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadReservedNameCommand, "", NULL }, + { "skill_discovery_template", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadSkillDiscoveryTemplateCommand, "", NULL }, + { "skill_extra_item_template", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadSkillExtraItemTemplateCommand, "", NULL }, + { "skill_fishing_base_level", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadSkillFishingBaseLevelCommand, "", NULL }, + { "skinning_loot_template", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadLootTemplatesSkinningCommand, "", NULL }, + { "spell_affect", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadSpellAffectCommand, "", NULL }, + { "spell_chain", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadSpellChainCommand, "", NULL }, + { "spell_elixir", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadSpellElixirCommand, "", NULL }, + { "spell_learn_spell", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadSpellLearnSpellCommand, "", NULL }, + { "spell_pet_auras", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadSpellPetAurasCommand, "", NULL }, + { "spell_proc_event", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadSpellProcEventCommand, "", NULL }, + { "spell_script_target", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadSpellScriptTargetCommand, "", NULL }, + { "spell_scripts", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadSpellScriptsCommand, "", NULL }, + { "spell_target_position", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadSpellTargetPositionCommand, "", NULL }, + { "spell_threats", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadSpellThreatsCommand, "", NULL }, + { "locales_creature", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadLocalesCreatureCommand, "", NULL }, + { "locales_gameobject", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadLocalesGameobjectCommand, "", NULL }, + { "locales_item", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadLocalesItemCommand, "", NULL }, + { "locales_npc_text", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadLocalesNpcTextCommand, "", NULL }, + { "locales_page_text", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadLocalesPageTextCommand, "", NULL }, + { "locales_quest", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadLocalesQuestCommand, "", NULL }, - { "", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadCommand, "", NULL }, - { NULL, 0, NULL, "", NULL } + { "", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand honorCommandTable[] = { - { "add", SEC_GAMEMASTER, &ChatHandler::HandleAddHonorCommand, "", NULL }, - { "addkill", SEC_GAMEMASTER, &ChatHandler::HandleHonorAddKillCommand, "", NULL }, - { "update", SEC_GAMEMASTER, &ChatHandler::HandleUpdateHonorFieldsCommand, "", NULL }, - { NULL, 0, NULL, "", NULL } + { "add", SEC_GAMEMASTER, false, &ChatHandler::HandleAddHonorCommand, "", NULL }, + { "addkill", SEC_GAMEMASTER, false, &ChatHandler::HandleHonorAddKillCommand, "", NULL }, + { "update", SEC_GAMEMASTER, false, &ChatHandler::HandleUpdateHonorFieldsCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand guildCommandTable[] = { - { "create", SEC_GAMEMASTER, &ChatHandler::HandleGuildCreateCommand, "", NULL }, - { "delete", SEC_GAMEMASTER, &ChatHandler::HandleGuildDeleteCommand, "", NULL }, - { "invite", SEC_GAMEMASTER, &ChatHandler::HandleGuildInviteCommand, "", NULL }, - { "uninvite", SEC_GAMEMASTER, &ChatHandler::HandleGuildUninviteCommand, "", NULL }, - { "rank", SEC_GAMEMASTER, &ChatHandler::HandleGuildRankCommand, "", NULL }, - { NULL, 0, NULL, "", NULL } + { "create", SEC_GAMEMASTER, false, &ChatHandler::HandleGuildCreateCommand, "", NULL }, + { "delete", SEC_GAMEMASTER, false, &ChatHandler::HandleGuildDeleteCommand, "", NULL }, + { "invite", SEC_GAMEMASTER, false, &ChatHandler::HandleGuildInviteCommand, "", NULL }, + { "uninvite", SEC_GAMEMASTER, false, &ChatHandler::HandleGuildUninviteCommand, "", NULL }, + { "rank", SEC_GAMEMASTER, false, &ChatHandler::HandleGuildRankCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand lookupPlayerCommandTable[] = { - { "ip", SEC_GAMEMASTER, &ChatHandler::HandleLookupPlayerIpCommand, "", NULL }, - { "account", SEC_GAMEMASTER, &ChatHandler::HandleLookupPlayerAccountCommand, "", NULL }, - { "email", SEC_GAMEMASTER, &ChatHandler::HandleLookupPlayerEmailCommand, "", NULL }, - { NULL, 0, NULL, "", NULL } + { "ip", SEC_GAMEMASTER, false, &ChatHandler::HandleLookupPlayerIpCommand, "", NULL }, + { "account", SEC_GAMEMASTER, false, &ChatHandler::HandleLookupPlayerAccountCommand, "", NULL }, + { "email", SEC_GAMEMASTER, false, &ChatHandler::HandleLookupPlayerEmailCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand lookupCommandTable[] = { - { "area", SEC_MODERATOR, &ChatHandler::HandleLookupAreaCommand, "", NULL }, - { "creature", SEC_ADMINISTRATOR, &ChatHandler::HandleLookupCreatureCommand, "", NULL }, - { "event", SEC_GAMEMASTER, &ChatHandler::HandleLookupEventCommand, "", NULL }, - { "faction", SEC_ADMINISTRATOR, &ChatHandler::HandleLookupFactionCommand, "", NULL }, - { "item", SEC_ADMINISTRATOR, &ChatHandler::HandleLookupItemCommand, "", NULL }, - { "itemset", SEC_ADMINISTRATOR, &ChatHandler::HandleLookupItemSetCommand, "", NULL }, - { "object", SEC_ADMINISTRATOR, &ChatHandler::HandleLookupObjectCommand, "", NULL }, - { "quest", SEC_ADMINISTRATOR, &ChatHandler::HandleLookupQuestCommand, "", NULL }, - { "player", SEC_GAMEMASTER, NULL, "", lookupPlayerCommandTable }, - { "skill", SEC_ADMINISTRATOR, &ChatHandler::HandleLookupSkillCommand, "", NULL }, - { "spell", SEC_ADMINISTRATOR, &ChatHandler::HandleLookupSpellCommand, "", NULL }, - { "tele", SEC_MODERATOR, &ChatHandler::HandleLookupTeleCommand, "", NULL }, - { NULL, 0, NULL, "", NULL } + { "area", SEC_MODERATOR, false, &ChatHandler::HandleLookupAreaCommand, "", NULL }, + { "creature", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLookupCreatureCommand, "", NULL }, + { "event", SEC_GAMEMASTER, false, &ChatHandler::HandleLookupEventCommand, "", NULL }, + { "faction", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLookupFactionCommand, "", NULL }, + { "item", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLookupItemCommand, "", NULL }, + { "itemset", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLookupItemSetCommand, "", NULL }, + { "object", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLookupObjectCommand, "", NULL }, + { "quest", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLookupQuestCommand, "", NULL }, + { "player", SEC_GAMEMASTER, false, NULL, "", lookupPlayerCommandTable }, + { "skill", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLookupSkillCommand, "", NULL }, + { "spell", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLookupSpellCommand, "", NULL }, + { "tele", SEC_MODERATOR, false, &ChatHandler::HandleLookupTeleCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand resetCommandTable[] = { - { "honor", SEC_ADMINISTRATOR, &ChatHandler::HandleResetHonorCommand, "", NULL }, - { "level", SEC_ADMINISTRATOR, &ChatHandler::HandleResetLevelCommand, "", NULL }, - { "spells", SEC_ADMINISTRATOR, &ChatHandler::HandleResetSpellsCommand, "", NULL }, - { "stats", SEC_ADMINISTRATOR, &ChatHandler::HandleResetStatsCommand, "", NULL }, - { "talents", SEC_ADMINISTRATOR, &ChatHandler::HandleResetTalentsCommand, "", NULL }, - { "all", SEC_ADMINISTRATOR, &ChatHandler::HandleResetAllCommand, "", NULL }, - { NULL, 0, NULL, "", NULL } + { "honor", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetHonorCommand, "", NULL }, + { "level", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetLevelCommand, "", NULL }, + { "spells", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetSpellsCommand, "", NULL }, + { "stats", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetStatsCommand, "", NULL }, + { "talents", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetTalentsCommand, "", NULL }, + { "all", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetAllCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand castCommandTable[] = { - { "back", SEC_ADMINISTRATOR, &ChatHandler::HandleCastBackCommand, "", NULL }, - { "dist", SEC_ADMINISTRATOR, &ChatHandler::HandleCastDistCommand, "", NULL }, - { "self", SEC_ADMINISTRATOR, &ChatHandler::HandleCastSelfCommand, "", NULL }, - { "target", SEC_ADMINISTRATOR, &ChatHandler::HandleCastTargetCommand, "", NULL }, - { "", SEC_ADMINISTRATOR, &ChatHandler::HandleCastCommand, "", NULL }, - { NULL, 0, NULL, "", NULL } + { "back", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCastBackCommand, "", NULL }, + { "dist", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCastDistCommand, "", NULL }, + { "self", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCastSelfCommand, "", NULL }, + { "target", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCastTargetCommand, "", NULL }, + { "", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCastCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand pdumpCommandTable[] = { - { "load", SEC_ADMINISTRATOR, &ChatHandler::HandleLoadPDumpCommand, "", NULL }, - { "write", SEC_ADMINISTRATOR, &ChatHandler::HandleWritePDumpCommand, "", NULL }, - { NULL, 0, NULL, "", NULL } + { "load", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLoadPDumpCommand, "", NULL }, + { "write", SEC_ADMINISTRATOR, true, &ChatHandler::HandleWritePDumpCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand listCommandTable[] = { - { "creature", SEC_ADMINISTRATOR, &ChatHandler::HandleListCreatureCommand, "", NULL }, - { "item", SEC_ADMINISTRATOR, &ChatHandler::HandleListItemCommand, "", NULL }, - { "object", SEC_ADMINISTRATOR, &ChatHandler::HandleListObjectCommand, "", NULL }, - { "auras", SEC_ADMINISTRATOR, &ChatHandler::HandleListAurasCommand, "", NULL }, - { NULL, 0, NULL, "", NULL } + { "creature", SEC_ADMINISTRATOR, false, &ChatHandler::HandleListCreatureCommand, "", NULL }, + { "item", SEC_ADMINISTRATOR, false, &ChatHandler::HandleListItemCommand, "", NULL }, + { "object", SEC_ADMINISTRATOR, false, &ChatHandler::HandleListObjectCommand, "", NULL }, + { "auras", SEC_ADMINISTRATOR, false, &ChatHandler::HandleListAurasCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand teleCommandTable[] = { - { "add", SEC_ADMINISTRATOR, &ChatHandler::HandleAddTeleCommand, "", NULL }, - { "del", SEC_ADMINISTRATOR, &ChatHandler::HandleDelTeleCommand, "", NULL }, - { "name", SEC_MODERATOR, &ChatHandler::HandleNameTeleCommand, "", NULL }, - { "group", SEC_MODERATOR, &ChatHandler::HandleGroupTeleCommand, "", NULL }, - { "", SEC_MODERATOR, &ChatHandler::HandleTeleCommand, "", NULL }, - { NULL, 0, NULL, "", NULL } + { "add", SEC_ADMINISTRATOR, false, &ChatHandler::HandleAddTeleCommand, "", NULL }, + { "del", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDelTeleCommand, "", NULL }, + { "name", SEC_MODERATOR, true, &ChatHandler::HandleNameTeleCommand, "", NULL }, + { "group", SEC_MODERATOR, false, &ChatHandler::HandleGroupTeleCommand, "", NULL }, + { "", SEC_MODERATOR, false, &ChatHandler::HandleTeleCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand npcCommandTable[] = { - { "say", SEC_MODERATOR, &ChatHandler::HandleSayCommand, "", NULL }, - { "whisper", SEC_MODERATOR, &ChatHandler::HandleNpcWhisperCommand, "", NULL }, - { "yell", SEC_MODERATOR, &ChatHandler::HandleYellCommand, "", NULL }, - { "textemote", SEC_MODERATOR, &ChatHandler::HandleTextEmoteCommand, "", NULL }, - { "add", SEC_GAMEMASTER, &ChatHandler::HandleAddSpwCommand, "", NULL }, - { "delete", SEC_GAMEMASTER, &ChatHandler::HandleDelCreatureCommand, "", NULL }, - { "spawndist", SEC_GAMEMASTER, &ChatHandler::HandleSpawnDistCommand, "", NULL }, - { "spawntime", SEC_GAMEMASTER, &ChatHandler::HandleSpawnTimeCommand, "", NULL }, - { "factionid", SEC_GAMEMASTER, &ChatHandler::HandleFactionIdCommand, "", NULL }, - { "addmove", SEC_GAMEMASTER, &ChatHandler::HandleAddMoveCommand, "", NULL }, - { "setmovetype", SEC_GAMEMASTER, &ChatHandler::HandleSetMoveTypeCommand, "", NULL }, - { "move", SEC_GAMEMASTER, &ChatHandler::HandleMoveCreatureCommand, "", NULL }, - { "changelevel", SEC_GAMEMASTER, &ChatHandler::HandleChangeLevelCommand, "", NULL }, - { "setmodel", SEC_GAMEMASTER, &ChatHandler::HandleSetModelCommand, "", NULL }, - { "additem", SEC_GAMEMASTER, &ChatHandler::HandleAddVendorItemCommand, "", NULL }, - { "delitem", SEC_GAMEMASTER, &ChatHandler::HandleDelVendorItemCommand, "", NULL }, - { "flag", SEC_GAMEMASTER, &ChatHandler::HandleNPCFlagCommand, "", NULL }, - { "changeentry", SEC_ADMINISTRATOR, &ChatHandler::HandleChangeEntryCommand, "", NULL }, - { "info", SEC_ADMINISTRATOR, &ChatHandler::HandleNpcInfoCommand, "", NULL }, - { "playemote", SEC_ADMINISTRATOR, &ChatHandler::HandlePlayEmoteCommand, "", NULL }, + { "say", SEC_MODERATOR, false, &ChatHandler::HandleSayCommand, "", NULL }, + { "whisper", SEC_MODERATOR, false, &ChatHandler::HandleNpcWhisperCommand, "", NULL }, + { "yell", SEC_MODERATOR, false, &ChatHandler::HandleYellCommand, "", NULL }, + { "textemote", SEC_MODERATOR, false, &ChatHandler::HandleTextEmoteCommand, "", NULL }, + { "add", SEC_GAMEMASTER, false, &ChatHandler::HandleAddSpwCommand, "", NULL }, + { "delete", SEC_GAMEMASTER, false, &ChatHandler::HandleDelCreatureCommand, "", NULL }, + { "spawndist", SEC_GAMEMASTER, false, &ChatHandler::HandleSpawnDistCommand, "", NULL }, + { "spawntime", SEC_GAMEMASTER, false, &ChatHandler::HandleSpawnTimeCommand, "", NULL }, + { "factionid", SEC_GAMEMASTER, false, &ChatHandler::HandleFactionIdCommand, "", NULL }, + { "addmove", SEC_GAMEMASTER, false, &ChatHandler::HandleAddMoveCommand, "", NULL }, + { "setmovetype", SEC_GAMEMASTER, false, &ChatHandler::HandleSetMoveTypeCommand, "", NULL }, + { "move", SEC_GAMEMASTER, false, &ChatHandler::HandleMoveCreatureCommand, "", NULL }, + { "changelevel", SEC_GAMEMASTER, false, &ChatHandler::HandleChangeLevelCommand, "", NULL }, + { "setmodel", SEC_GAMEMASTER, false, &ChatHandler::HandleSetModelCommand, "", NULL }, + { "additem", SEC_GAMEMASTER, false, &ChatHandler::HandleAddVendorItemCommand, "", NULL }, + { "delitem", SEC_GAMEMASTER, false, &ChatHandler::HandleDelVendorItemCommand, "", NULL }, + { "flag", SEC_GAMEMASTER, false, &ChatHandler::HandleNPCFlagCommand, "", NULL }, + { "changeentry", SEC_ADMINISTRATOR, false, &ChatHandler::HandleChangeEntryCommand, "", NULL }, + { "info", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcInfoCommand, "", NULL }, + { "playemote", SEC_ADMINISTRATOR, false, &ChatHandler::HandlePlayEmoteCommand, "", NULL }, //{ TODO: fix or remove this commands - { "name", SEC_GAMEMASTER, &ChatHandler::HandleNameCommand, "", NULL }, - { "subname", SEC_GAMEMASTER, &ChatHandler::HandleSubNameCommand, "", NULL }, - { "addweapon", SEC_ADMINISTRATOR, &ChatHandler::HandleAddWeaponCommand, "", NULL }, + { "name", SEC_GAMEMASTER, false, &ChatHandler::HandleNameCommand, "", NULL }, + { "subname", SEC_GAMEMASTER, false, &ChatHandler::HandleSubNameCommand, "", NULL }, + { "addweapon", SEC_ADMINISTRATOR, false, &ChatHandler::HandleAddWeaponCommand, "", NULL }, //} - { NULL, 0, NULL, "", NULL } + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand goCommandTable[] = { - { "grid", SEC_MODERATOR, &ChatHandler::HandleGoGridCommand, "", NULL }, - { "creature", SEC_GAMEMASTER, &ChatHandler::HandleGoCreatureCommand, "", NULL }, - { "object", SEC_GAMEMASTER, &ChatHandler::HandleGoObjectCommand, "", NULL }, - { "trigger", SEC_GAMEMASTER, &ChatHandler::HandleGoTriggerCommand, "", NULL }, - { "graveyard", SEC_GAMEMASTER, &ChatHandler::HandleGoGraveyardCommand, "", NULL }, - { "zonexy", SEC_MODERATOR, &ChatHandler::HandleGoZoneXYCommand, "", NULL }, - { "xy", SEC_MODERATOR, &ChatHandler::HandleGoXYCommand, "", NULL }, - { "xyz", SEC_MODERATOR, &ChatHandler::HandleGoXYZCommand, "", NULL }, - { "", SEC_MODERATOR, &ChatHandler::HandleGoXYZCommand, "", NULL }, - { NULL, 0, NULL, "", NULL } + { "grid", SEC_MODERATOR, false, &ChatHandler::HandleGoGridCommand, "", NULL }, + { "creature", SEC_GAMEMASTER, false, &ChatHandler::HandleGoCreatureCommand, "", NULL }, + { "object", SEC_GAMEMASTER, false, &ChatHandler::HandleGoObjectCommand, "", NULL }, + { "trigger", SEC_GAMEMASTER, false, &ChatHandler::HandleGoTriggerCommand, "", NULL }, + { "graveyard", SEC_GAMEMASTER, false, &ChatHandler::HandleGoGraveyardCommand, "", NULL }, + { "zonexy", SEC_MODERATOR, false, &ChatHandler::HandleGoZoneXYCommand, "", NULL }, + { "xy", SEC_MODERATOR, false, &ChatHandler::HandleGoXYCommand, "", NULL }, + { "xyz", SEC_MODERATOR, false, &ChatHandler::HandleGoXYZCommand, "", NULL }, + { "", SEC_MODERATOR, false, &ChatHandler::HandleGoXYZCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand gobjectCommandTable[] = { - { "add", SEC_GAMEMASTER, &ChatHandler::HandleGameObjectCommand, "", NULL }, - { "delete", SEC_GAMEMASTER, &ChatHandler::HandleDelObjectCommand, "", NULL }, - { "target", SEC_GAMEMASTER, &ChatHandler::HandleTargetObjectCommand, "", NULL }, - { "turn", SEC_GAMEMASTER, &ChatHandler::HandleTurnObjectCommand, "", NULL }, - { "move", SEC_GAMEMASTER, &ChatHandler::HandleMoveObjectCommand, "", NULL }, - { "near", SEC_ADMINISTRATOR, &ChatHandler::HandleNearObjectCommand, "", NULL }, - { NULL, 0, NULL, "", NULL } + { "add", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectCommand, "", NULL }, + { "delete", SEC_GAMEMASTER, false, &ChatHandler::HandleDelObjectCommand, "", NULL }, + { "target", SEC_GAMEMASTER, false, &ChatHandler::HandleTargetObjectCommand, "", NULL }, + { "turn", SEC_GAMEMASTER, false, &ChatHandler::HandleTurnObjectCommand, "", NULL }, + { "move", SEC_GAMEMASTER, false, &ChatHandler::HandleMoveObjectCommand, "", NULL }, + { "near", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNearObjectCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand questCommandTable[] = { - { "add", SEC_ADMINISTRATOR, &ChatHandler::HandleAddQuest, "", NULL }, - { "complete", SEC_ADMINISTRATOR, &ChatHandler::HandleCompleteQuest, "", NULL }, - { "remove", SEC_ADMINISTRATOR, &ChatHandler::HandleRemoveQuest, "", NULL }, - { NULL, 0, NULL, "", NULL } + { "add", SEC_ADMINISTRATOR, false, &ChatHandler::HandleAddQuest, "", NULL }, + { "complete", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCompleteQuest, "", NULL }, + { "remove", SEC_ADMINISTRATOR, false, &ChatHandler::HandleRemoveQuest, "", NULL }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand gmCommandTable[] = { - { "chat", SEC_MODERATOR, &ChatHandler::HandleGMChatCommand, "", NULL }, - { "list", SEC_PLAYER, &ChatHandler::HandleGMListCommand, "", NULL }, - { "visible", SEC_MODERATOR, &ChatHandler::HandleVisibleCommand, "", NULL }, - { "fly", SEC_ADMINISTRATOR, &ChatHandler::HandleFlyModeCommand, "", NULL }, - { "", SEC_MODERATOR, &ChatHandler::HandleGMmodeCommand, "", NULL }, - { NULL, 0, NULL, "", NULL } + { "chat", SEC_MODERATOR, false, &ChatHandler::HandleGMChatCommand, "", NULL }, + { "online", SEC_PLAYER, true, &ChatHandler::HandleGMListOnlineCommand, "", NULL }, + { "list", SEC_ADMINISTRATOR, true, &ChatHandler::HandleGMListFullCommand, "", NULL }, + { "visible", SEC_MODERATOR, false, &ChatHandler::HandleVisibleCommand, "", NULL }, + { "fly", SEC_ADMINISTRATOR, false, &ChatHandler::HandleFlyModeCommand, "", NULL }, + { "", SEC_MODERATOR, false, &ChatHandler::HandleGMmodeCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand instanceCommandTable[] = { - { "listbinds", SEC_MODERATOR, &ChatHandler::HandleInstanceListBindsCommand, "", NULL }, - { "unbind", SEC_MODERATOR, &ChatHandler::HandleInstanceUnbindCommand, "", NULL }, - { "stats", SEC_MODERATOR, &ChatHandler::HandleInstanceStatsCommand, "", NULL }, - { "savedata", SEC_MODERATOR, &ChatHandler::HandleInstanceSaveDataCommand, "", NULL }, - { NULL, 0, NULL, "", NULL } + { "listbinds", SEC_MODERATOR, false, &ChatHandler::HandleInstanceListBindsCommand, "", NULL }, + { "unbind", SEC_MODERATOR, false, &ChatHandler::HandleInstanceUnbindCommand, "", NULL }, + { "stats", SEC_MODERATOR, false, &ChatHandler::HandleInstanceStatsCommand, "", NULL }, + { "savedata", SEC_MODERATOR, false, &ChatHandler::HandleInstanceSaveDataCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand commandTable[] = { - { "gm", SEC_MODERATOR, NULL, "", gmCommandTable }, - { "npc", SEC_MODERATOR, NULL, "", npcCommandTable }, - { "go", SEC_MODERATOR, NULL, "", goCommandTable }, - { "learn", SEC_MODERATOR, NULL, "", learnCommandTable }, - { "modify", SEC_MODERATOR, NULL, "", modifyCommandTable }, - { "debug", SEC_MODERATOR, NULL, "", debugCommandTable }, - { "tele", SEC_MODERATOR, NULL, "", teleCommandTable }, - { "event", SEC_GAMEMASTER, NULL, "", eventCommandTable }, - { "gobject", SEC_GAMEMASTER, NULL, "", gobjectCommandTable }, - { "honor", SEC_GAMEMASTER, NULL, "", honorCommandTable }, - { "wp", SEC_GAMEMASTER, NULL, "", wpCommandTable }, - { "quest", SEC_ADMINISTRATOR, NULL, "", questCommandTable }, - { "reload", SEC_ADMINISTRATOR, NULL, "", reloadCommandTable }, - { "list", SEC_ADMINISTRATOR, NULL, "", listCommandTable }, - { "lookup", SEC_ADMINISTRATOR, NULL, "", lookupCommandTable }, - { "pdump", SEC_ADMINISTRATOR, NULL, "", pdumpCommandTable }, - { "guild", SEC_ADMINISTRATOR, NULL, "", guildCommandTable }, - { "cast", SEC_ADMINISTRATOR, NULL, "", castCommandTable }, - { "reset", SEC_ADMINISTRATOR, NULL, "", resetCommandTable }, - { "instance", SEC_ADMINISTRATOR, NULL, "", instanceCommandTable }, - { "server", SEC_ADMINISTRATOR, NULL, "", serverCommandTable }, + { "account", SEC_PLAYER, true, NULL, "", accountCommandTable }, + { "gm", SEC_MODERATOR, true, NULL, "", gmCommandTable }, + { "npc", SEC_MODERATOR, false, NULL, "", npcCommandTable }, + { "go", SEC_MODERATOR, false, NULL, "", goCommandTable }, + { "learn", SEC_MODERATOR, false, NULL, "", learnCommandTable }, + { "modify", SEC_MODERATOR, false, NULL, "", modifyCommandTable }, + { "debug", SEC_MODERATOR, false, NULL, "", debugCommandTable }, + { "tele", SEC_MODERATOR, true, NULL, "", teleCommandTable }, + { "event", SEC_GAMEMASTER, false, NULL, "", eventCommandTable }, + { "gobject", SEC_GAMEMASTER, false, NULL, "", gobjectCommandTable }, + { "honor", SEC_GAMEMASTER, false, NULL, "", honorCommandTable }, + { "wp", SEC_GAMEMASTER, false, NULL, "", wpCommandTable }, + { "quest", SEC_ADMINISTRATOR, false, NULL, "", questCommandTable }, + { "reload", SEC_ADMINISTRATOR, false, NULL, "", reloadCommandTable }, + { "list", SEC_ADMINISTRATOR, false, NULL, "", listCommandTable }, + { "lookup", SEC_ADMINISTRATOR, false, NULL, "", lookupCommandTable }, + { "pdump", SEC_ADMINISTRATOR, true, NULL, "", pdumpCommandTable }, + { "guild", SEC_ADMINISTRATOR, false, NULL, "", guildCommandTable }, + { "cast", SEC_ADMINISTRATOR, false, NULL, "", castCommandTable }, + { "reset", SEC_ADMINISTRATOR, false, NULL, "", resetCommandTable }, + { "instance", SEC_ADMINISTRATOR, false, NULL, "", instanceCommandTable }, + { "server", SEC_ADMINISTRATOR, true, NULL, "", serverCommandTable }, - { "aura", SEC_ADMINISTRATOR, &ChatHandler::HandleAuraCommand, "", NULL }, - { "unaura", SEC_ADMINISTRATOR, &ChatHandler::HandleUnAuraCommand, "", NULL }, - { "acct", SEC_PLAYER, &ChatHandler::HandleAcctCommand, "", NULL }, - { "announce", SEC_MODERATOR, &ChatHandler::HandleAnnounceCommand, "", NULL }, - { "notify", SEC_MODERATOR, &ChatHandler::HandleNotifyCommand, "", NULL }, - { "goname", SEC_MODERATOR, &ChatHandler::HandleGonameCommand, "", NULL }, - { "namego", SEC_MODERATOR, &ChatHandler::HandleNamegoCommand, "", NULL }, - { "groupgo", SEC_MODERATOR, &ChatHandler::HandleGroupgoCommand, "", NULL }, - { "commands", SEC_PLAYER, &ChatHandler::HandleCommandsCommand, "", NULL }, - { "demorph", SEC_GAMEMASTER, &ChatHandler::HandleDeMorphCommand, "", NULL }, - { "die", SEC_ADMINISTRATOR, &ChatHandler::HandleDieCommand, "", NULL }, - { "revive", SEC_ADMINISTRATOR, &ChatHandler::HandleReviveCommand, "", NULL }, - { "dismount", SEC_PLAYER, &ChatHandler::HandleDismountCommand, "", NULL }, - { "gps", SEC_MODERATOR, &ChatHandler::HandleGPSCommand, "", NULL }, - { "guid", SEC_GAMEMASTER, &ChatHandler::HandleGUIDCommand, "", NULL }, - { "help", SEC_PLAYER, &ChatHandler::HandleHelpCommand, "", NULL }, - { "itemmove", SEC_GAMEMASTER, &ChatHandler::HandleItemMoveCommand, "", NULL }, - { "cooldown", SEC_ADMINISTRATOR, &ChatHandler::HandleCooldownCommand, "", NULL }, - { "unlearn", SEC_ADMINISTRATOR, &ChatHandler::HandleUnLearnCommand, "", NULL }, - { "distance", SEC_ADMINISTRATOR, &ChatHandler::HandleGetDistanceCommand, "", NULL }, - { "recall", SEC_MODERATOR, &ChatHandler::HandleRecallCommand, "", NULL }, - { "save", SEC_PLAYER, &ChatHandler::HandleSaveCommand, "", NULL }, - { "saveall", SEC_MODERATOR, &ChatHandler::HandleSaveAllCommand, "", NULL }, - { "kick", SEC_GAMEMASTER, &ChatHandler::HandleKickPlayerCommand, "", NULL }, - { "security", SEC_ADMINISTRATOR, &ChatHandler::HandleSecurityCommand, "", NULL }, - { "ban", SEC_ADMINISTRATOR, &ChatHandler::HandleBanCommand, "", NULL }, - { "unban", SEC_ADMINISTRATOR, &ChatHandler::HandleUnBanCommand, "", NULL }, - { "baninfo", SEC_ADMINISTRATOR, &ChatHandler::HandleBanInfoCommand, "", NULL }, - { "banlist", SEC_ADMINISTRATOR, &ChatHandler::HandleBanListCommand, "", NULL }, - { "plimit", SEC_ADMINISTRATOR, &ChatHandler::HandlePLimitCommand, "", NULL }, - { "start", SEC_PLAYER, &ChatHandler::HandleStartCommand, "", NULL }, - { "taxicheat", SEC_MODERATOR, &ChatHandler::HandleTaxiCheatCommand, "", NULL }, - { "allowmove", SEC_ADMINISTRATOR, &ChatHandler::HandleAllowMovementCommand, "", NULL }, - { "linkgrave", SEC_ADMINISTRATOR, &ChatHandler::HandleLinkGraveCommand, "", NULL }, - { "neargrave", SEC_ADMINISTRATOR, &ChatHandler::HandleNearGraveCommand, "", NULL }, - { "transport", SEC_ADMINISTRATOR, &ChatHandler::HandleSpawnTransportCommand, "", NULL }, - { "explorecheat", SEC_ADMINISTRATOR, &ChatHandler::HandleExploreCheatCommand, "", NULL }, - { "hover", SEC_ADMINISTRATOR, &ChatHandler::HandleHoverCommand, "", NULL }, - { "levelup", SEC_ADMINISTRATOR, &ChatHandler::HandleLevelUpCommand, "", NULL }, - { "showarea", SEC_ADMINISTRATOR, &ChatHandler::HandleShowAreaCommand, "", NULL }, - { "hidearea", SEC_ADMINISTRATOR, &ChatHandler::HandleHideAreaCommand, "", NULL }, - { "additem", SEC_ADMINISTRATOR, &ChatHandler::HandleAddItemCommand, "", NULL }, - { "additemset", SEC_ADMINISTRATOR, &ChatHandler::HandleAddItemSetCommand, "", NULL }, - { "bank", SEC_ADMINISTRATOR, &ChatHandler::HandleBankCommand, "", NULL }, - { "wchange", SEC_ADMINISTRATOR, &ChatHandler::HandleChangeWeather, "", NULL }, - { "ticket", SEC_GAMEMASTER, &ChatHandler::HandleTicketCommand, "", NULL }, - { "delticket", SEC_GAMEMASTER, &ChatHandler::HandleDelTicketCommand, "", NULL }, - { "maxskill", SEC_ADMINISTRATOR, &ChatHandler::HandleMaxSkillCommand, "", NULL }, - { "setskill", SEC_ADMINISTRATOR, &ChatHandler::HandleSetSkillCommand, "", NULL }, - { "whispers", SEC_MODERATOR, &ChatHandler::HandleWhispersCommand, "", NULL }, - { "pinfo", SEC_GAMEMASTER, &ChatHandler::HandlePInfoCommand, "", NULL }, - { "password", SEC_PLAYER, &ChatHandler::HandlePasswordCommand, "", NULL }, - { "lockaccount", SEC_PLAYER, &ChatHandler::HandleLockAccountCommand, "", NULL }, - { "respawn", SEC_ADMINISTRATOR, &ChatHandler::HandleRespawnCommand, "", NULL }, - { "sendmail", SEC_MODERATOR, &ChatHandler::HandleSendMailCommand, "", NULL }, - { "rename", SEC_GAMEMASTER, &ChatHandler::HandleRenameCommand, "", NULL }, - { "loadscripts", SEC_ADMINISTRATOR, &ChatHandler::HandleLoadScriptsCommand, "", NULL }, - { "mute", SEC_GAMEMASTER, &ChatHandler::HandleMuteCommand, "", NULL }, - { "unmute", SEC_GAMEMASTER, &ChatHandler::HandleUnmuteCommand, "", NULL }, - { "movegens", SEC_ADMINISTRATOR, &ChatHandler::HandleMovegensCommand, "", NULL }, - { "cometome", SEC_ADMINISTRATOR, &ChatHandler::HandleComeToMeCommand, "", NULL }, - { "damage", SEC_ADMINISTRATOR, &ChatHandler::HandleDamageCommand, "", NULL }, - { "combatstop", SEC_GAMEMASTER, &ChatHandler::HandleCombatStopCommand, "", NULL }, + { "aura", SEC_ADMINISTRATOR, false, &ChatHandler::HandleAuraCommand, "", NULL }, + { "unaura", SEC_ADMINISTRATOR, false, &ChatHandler::HandleUnAuraCommand, "", NULL }, + { "announce", SEC_MODERATOR, true, &ChatHandler::HandleAnnounceCommand, "", NULL }, + { "notify", SEC_MODERATOR, false, &ChatHandler::HandleNotifyCommand, "", NULL }, + { "goname", SEC_MODERATOR, false, &ChatHandler::HandleGonameCommand, "", NULL }, + { "namego", SEC_MODERATOR, false, &ChatHandler::HandleNamegoCommand, "", NULL }, + { "groupgo", SEC_MODERATOR, false, &ChatHandler::HandleGroupgoCommand, "", NULL }, + { "commands", SEC_PLAYER, true, &ChatHandler::HandleCommandsCommand, "", NULL }, + { "demorph", SEC_GAMEMASTER, false, &ChatHandler::HandleDeMorphCommand, "", NULL }, + { "die", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDieCommand, "", NULL }, + { "revive", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReviveCommand, "", NULL }, + { "dismount", SEC_PLAYER, false, &ChatHandler::HandleDismountCommand, "", NULL }, + { "gps", SEC_MODERATOR, false, &ChatHandler::HandleGPSCommand, "", NULL }, + { "guid", SEC_GAMEMASTER, false, &ChatHandler::HandleGUIDCommand, "", NULL }, + { "help", SEC_PLAYER, true, &ChatHandler::HandleHelpCommand, "", NULL }, + { "itemmove", SEC_GAMEMASTER, false, &ChatHandler::HandleItemMoveCommand, "", NULL }, + { "cooldown", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCooldownCommand, "", NULL }, + { "unlearn", SEC_ADMINISTRATOR, false, &ChatHandler::HandleUnLearnCommand, "", NULL }, + { "distance", SEC_ADMINISTRATOR, false, &ChatHandler::HandleGetDistanceCommand, "", NULL }, + { "recall", SEC_MODERATOR, false, &ChatHandler::HandleRecallCommand, "", NULL }, + { "save", SEC_PLAYER, false, &ChatHandler::HandleSaveCommand, "", NULL }, + { "saveall", SEC_MODERATOR, true, &ChatHandler::HandleSaveAllCommand, "", NULL }, + { "kick", SEC_GAMEMASTER, true, &ChatHandler::HandleKickPlayerCommand, "", NULL }, + { "ban", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanCommand, "", NULL }, + { "unban", SEC_ADMINISTRATOR, true, &ChatHandler::HandleUnBanCommand, "", NULL }, + { "baninfo", SEC_ADMINISTRATOR, false, &ChatHandler::HandleBanInfoCommand, "", NULL }, + { "banlist", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanListCommand, "", NULL }, + { "plimit", SEC_ADMINISTRATOR, true, &ChatHandler::HandlePLimitCommand, "", NULL }, + { "start", SEC_PLAYER, false, &ChatHandler::HandleStartCommand, "", NULL }, + { "taxicheat", SEC_MODERATOR, false, &ChatHandler::HandleTaxiCheatCommand, "", NULL }, + { "allowmove", SEC_ADMINISTRATOR, false, &ChatHandler::HandleAllowMovementCommand, "", NULL }, + { "linkgrave", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLinkGraveCommand, "", NULL }, + { "neargrave", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNearGraveCommand, "", NULL }, + { "transport", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSpawnTransportCommand, "", NULL }, + { "explorecheat", SEC_ADMINISTRATOR, false, &ChatHandler::HandleExploreCheatCommand, "", NULL }, + { "hover", SEC_ADMINISTRATOR, false, &ChatHandler::HandleHoverCommand, "", NULL }, + { "levelup", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLevelUpCommand, "", NULL }, + { "showarea", SEC_ADMINISTRATOR, false, &ChatHandler::HandleShowAreaCommand, "", NULL }, + { "hidearea", SEC_ADMINISTRATOR, false, &ChatHandler::HandleHideAreaCommand, "", NULL }, + { "additem", SEC_ADMINISTRATOR, false, &ChatHandler::HandleAddItemCommand, "", NULL }, + { "additemset", SEC_ADMINISTRATOR, false, &ChatHandler::HandleAddItemSetCommand, "", NULL }, + { "bank", SEC_ADMINISTRATOR, false, &ChatHandler::HandleBankCommand, "", NULL }, + { "wchange", SEC_ADMINISTRATOR, false, &ChatHandler::HandleChangeWeather, "", NULL }, + { "ticket", SEC_GAMEMASTER, false, &ChatHandler::HandleTicketCommand, "", NULL }, + { "delticket", SEC_GAMEMASTER, false, &ChatHandler::HandleDelTicketCommand, "", NULL }, + { "maxskill", SEC_ADMINISTRATOR, false, &ChatHandler::HandleMaxSkillCommand, "", NULL }, + { "setskill", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSetSkillCommand, "", NULL }, + { "whispers", SEC_MODERATOR, false, &ChatHandler::HandleWhispersCommand, "", NULL }, + { "pinfo", SEC_GAMEMASTER, false, &ChatHandler::HandlePInfoCommand, "", NULL }, + { "password", SEC_PLAYER, false, &ChatHandler::HandlePasswordCommand, "", NULL }, + { "lockaccount", SEC_PLAYER, false, &ChatHandler::HandleLockAccountCommand, "", NULL }, + { "respawn", SEC_ADMINISTRATOR, false, &ChatHandler::HandleRespawnCommand, "", NULL }, + { "sendmail", SEC_MODERATOR, false, &ChatHandler::HandleSendMailCommand, "", NULL }, + { "rename", SEC_GAMEMASTER, false, &ChatHandler::HandleRenameCommand, "", NULL }, + { "loadscripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLoadScriptsCommand, "", NULL }, + { "mute", SEC_GAMEMASTER, false, &ChatHandler::HandleMuteCommand, "", NULL }, + { "unmute", SEC_GAMEMASTER, false, &ChatHandler::HandleUnmuteCommand, "", NULL }, + { "movegens", SEC_ADMINISTRATOR, false, &ChatHandler::HandleMovegensCommand, "", NULL }, + { "cometome", SEC_ADMINISTRATOR, false, &ChatHandler::HandleComeToMeCommand, "", NULL }, + { "damage", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDamageCommand, "", NULL }, + { "combatstop", SEC_GAMEMASTER, false, &ChatHandler::HandleCombatStopCommand, "", NULL }, + { "chardelete", SEC_CONSOLE, true, &ChatHandler::HandleCombatStopCommand, "", NULL }, + { "sendmessage", SEC_ADMINISTRATOR, true, &ChatHandler::HandleSendMessageCommand, "", NULL }, - { NULL, 0, NULL, "", NULL } + { NULL, 0, false, NULL, "", NULL } }; if(load_command_table) @@ -509,11 +540,17 @@ ChatCommand * ChatHandler::getCommandTable() return commandTable; } -const char *ChatHandler::GetMangosString(int32 entry) +const char *ChatHandler::GetMangosString(int32 entry) const { return m_session->GetMangosString(entry); } +bool ChatHandler::isAvailable(ChatCommand const& cmd) const +{ + // check security level only for simple command (without child commands) + return cmd.Handler && m_session->GetSecurity() >= cmd.SecurityLevel; +} + bool ChatHandler::hasStringAbbr(const char* name, const char* part) { // non "" command @@ -558,6 +595,7 @@ void ChatHandler::SendSysMessage(const char *str) void ChatHandler::SendGlobalSysMessage(const char *str) { + // Chat output WorldPacket data; // need copy to prevent corruption by strtok call in LineFromMessage original string @@ -633,8 +671,7 @@ bool ChatHandler::ExecuteCommandInTable(ChatCommand *table, const char* text, st return true; } - // check security level only for simple command (without child commands) - if(m_session->GetSecurity() < table[i].SecurityLevel) + if(!isAvailable(table[i])) continue; SetSentErrorMessage(false); @@ -643,11 +680,15 @@ bool ChatHandler::ExecuteCommandInTable(ChatCommand *table, const char* text, st { if(table[i].SecurityLevel > SEC_PLAYER) { - Player* p = m_session->GetPlayer(); - uint64 sel_guid = p->GetSelection(); - sLog.outCommand("Command: %s [Player: %s (Account: %u) X: %f Y: %f Z: %f Map: %u Selected: %s (GUID: %u)]", - fullcmd.c_str(),p->GetName(),m_session->GetAccountId(),p->GetPositionX(),p->GetPositionY(),p->GetPositionZ(),p->GetMapId(), - GetLogNameForGuid(sel_guid),GUID_LOPART(sel_guid)); + // chat case + if(m_session) + { + Player* p = m_session->GetPlayer(); + uint64 sel_guid = p->GetSelection(); + sLog.outCommand("Command: %s [Player: %s (Account: %u) X: %f Y: %f Z: %f Map: %u Selected: %s (GUID: %u)]", + fullcmd.c_str(),p->GetName(),m_session->GetAccountId(),p->GetPositionX(),p->GetPositionY(),p->GetPositionZ(),p->GetMapId(), + GetLogNameForGuid(sel_guid),GUID_LOPART(sel_guid)); + } } } // some commands have custom error messages. Don't send the default one in these cases. @@ -673,18 +714,24 @@ int ChatHandler::ParseCommands(const char* text) //if(m_session->GetSecurity() == 0) // return 0; - if(text[0] != '!' && text[0] != '.') - return 0; + /// chat case (.command or !command format) + if(m_session) + { + if(text[0] != '!' && text[0] != '.') + return 0; + } - // ignore single . and ! in line + /// ignore single . and ! in line if(strlen(text) < 2) return 0; - // ignore messages staring from many dots. + /// ignore messages staring from many dots. if(text[0] == '.' && text[1] == '.' || text[0] == '!' && text[1] == '!') return 0; - ++text; + /// skip first . or ! (in console allowed use command with . and ! and without its) + if(text[0] == '!' || text[0] == '.') + ++text; std::string fullcmd = text; // original `text` can't be used. It content destroyed in command code processing. @@ -699,7 +746,7 @@ bool ChatHandler::ShowHelpForSubCommands(ChatCommand *table, char const* cmd, ch std::string list; for(uint32 i = 0; table[i].Name != NULL; ++i) { - if(m_session->GetSecurity() < table[i].SecurityLevel) + if(!isAvailable(table[i])) continue; /// for empty subcmd show all available @@ -729,7 +776,7 @@ bool ChatHandler::ShowHelpForCommand(ChatCommand *table, const char* cmd) { for(uint32 i = 0; table[i].Name != NULL; ++i) { - if(m_session->GetSecurity() < table[i].SecurityLevel) + if(!isAvailable(table[i])) continue; if( !hasStringAbbr(table[i].Name, cmd) ) @@ -758,7 +805,7 @@ bool ChatHandler::ShowHelpForCommand(ChatCommand *table, const char* cmd) { for(uint32 i = 0; table[i].Name != NULL; ++i) { - if(m_session->GetSecurity() < table[i].SecurityLevel) + if(!isAvailable(table[i])) continue; if(strlen(table[i].Name)) @@ -859,6 +906,9 @@ void ChatHandler::FillMessageData( WorldPacket *data, WorldSession* session, uin Player * ChatHandler::getSelectedPlayer() { + if(!m_session) + return NULL; + uint64 guid = m_session->GetPlayer()->GetSelection(); if (guid == 0) @@ -869,6 +919,9 @@ Player * ChatHandler::getSelectedPlayer() Unit* ChatHandler::getSelectedUnit() { + if(!m_session) + return NULL; + uint64 guid = m_session->GetPlayer()->GetSelection(); if (guid == 0) @@ -879,6 +932,9 @@ Unit* ChatHandler::getSelectedUnit() Creature* ChatHandler::getSelectedCreature() { + if(!m_session) + return NULL; + return ObjectAccessor::GetCreatureOrPet(*m_session->GetPlayer(),m_session->GetPlayer()->GetSelection()); } @@ -1017,6 +1073,9 @@ char const *fmtstring( char const *format, ... ) GameObject* ChatHandler::GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid,uint32 entry) { + if(!m_session) + return NULL; + Player* pl = m_session->GetPlayer(); GameObject* obj = ObjectAccessor::GetGameObject(*pl, MAKE_NEW_GUID(lowguid, entry, HIGHGUID_GAMEOBJECT)); @@ -1090,3 +1149,20 @@ GameTele const* ChatHandler::extractGameTeleFromLink(char* text) return objmgr.GetGameTele(cId); } + +const char *CliHandler::GetMangosString(int32 entry) const +{ + return objmgr.GetMangosStringForDBCLocale(entry); +} + +bool CliHandler::isAvailable(ChatCommand const& cmd) const +{ + // skip non-console commands in console case + return cmd.Handler && cmd.AllowConsole; +} + +void CliHandler::SendSysMessage(const char *str) +{ + m_print(str); + m_print("\r\n"); +} diff --git a/src/game/Chat.h b/src/game/Chat.h index a6da30a3d..a3960da71 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -33,6 +33,7 @@ class ChatCommand public: const char * Name; uint32 SecurityLevel; // function pointer required correct align (use uint32) + bool AllowConsole; bool (ChatHandler::*Handler)(const char* args); std::string Help; ChatCommand * ChildCommands; @@ -59,9 +60,9 @@ class ChatHandler static char* LineFromMessage(char*& pos) { char* start = strtok(pos,"\n"); pos = NULL; return start; } - const char *GetMangosString(int32 entry); + virtual const char *GetMangosString(int32 entry) const; - void SendSysMessage( const char *str); + virtual void SendSysMessage( const char *str); void SendSysMessage( int32 entry); void PSendSysMessage( const char *format, ...) ATTR_PRINTF(2,3); void PSendSysMessage( int32 entry, ... ); @@ -69,7 +70,12 @@ class ChatHandler int ParseCommands(const char* text); protected: + explicit ChatHandler() : m_session(NULL) {} // for CLI subclass + bool hasStringAbbr(const char* name, const char* part); + + virtual bool isAvailable(ChatCommand const& cmd) const; + void SendGlobalSysMessage(const char *str); bool ExecuteCommandInTable(ChatCommand *table, const char* text, std::string fullcommand); @@ -78,14 +84,22 @@ class ChatHandler ChatCommand* getCommandTable(); + bool HandleAccountCommand(const char* args); + bool HandleAccountCreateCommand(const char* args); + bool HandleAccountDeleteCommand(const char* args); + bool HandleAccountOnlineListCommand(const char* args); + bool HandleAccountSetAddonCommand(const char* args); + bool HandleAccountSetGmLevelCommand(const char* args); + bool HandleAccountSetPasswordCommand(const char* args); + bool HandleHelpCommand(const char* args); bool HandleCommandsCommand(const char* args); - bool HandleAcctCommand(const char* args); bool HandleStartCommand(const char* args); bool HandleInfoCommand(const char* args); bool HandleDismountCommand(const char* args); bool HandleSaveCommand(const char* args); - bool HandleGMListCommand(const char* args); + bool HandleGMListOnlineCommand(const char* args); + bool HandleGMListFullCommand(const char* args); bool HandleNamegoCommand(const char* args); bool HandleGonameCommand(const char* args); @@ -204,6 +218,12 @@ class ChatHandler bool HandleInstanceStatsCommand(const char* args); bool HandleInstanceSaveDataCommand(const char * args); + bool HandleServerCorpsesCommand(const char* args); + bool HandleServerExitCommand(const char* args); + bool HandleServerMotdCommand(const char* args); + bool HandleServerSetMotdCommand(const char* args); + bool HandleServerSetLogLevelCommand(const char* args); + bool HandleAddHonorCommand(const char* args); bool HandleHonorAddKillCommand(const char* args); bool HandleUpdateHonorFieldsCommand(const char* args); @@ -249,6 +269,7 @@ class ChatHandler bool HandleUnmuteCommand(const char* args); bool HandleMovegensCommand(const char* args); + bool HandleCharacterDeleteCommand(const char* args); bool HandleBanCommand(const char* args); bool HandleUnBanCommand(const char* args); bool HandleBanInfoCommand(const char* args); @@ -257,7 +278,6 @@ class ChatHandler bool HandleIdleShutDownCommand(const char* args); bool HandleShutDownCommand(const char* args); bool HandleRestartCommand(const char* args); - bool HandleSecurityCommand(const char* args); bool HandleGoXYCommand(const char* args); bool HandleGoXYZCommand(const char* args); bool HandleGoZoneXYCommand(const char* args); @@ -375,6 +395,7 @@ class ChatHandler bool HandleCastTargetCommand(const char *args); bool HandleComeToMeCommand(const char *args); bool HandleCombatStopCommand(const char *args); + bool HandleSendMessageCommand(const char * args); //! Development Commands bool HandleSetValue(const char* args); @@ -398,8 +419,6 @@ class ChatHandler GameObject* GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid,uint32 entry); - WorldSession * m_session; - // Utility methods for commands void ShowTicket(uint64 guid, char const* text, char const* time); uint32 GetTicketIDByNum(uint32 num); @@ -407,10 +426,28 @@ class ChatHandler void SetSentErrorMessage(bool val){ sentErrorMessage = val;}; private: + WorldSession * m_session; // != NULL for chat command call and NULL for CLI command + // common global flag static bool load_command_table; bool sentErrorMessage; }; -#endif + +class CliHandler : public ChatHandler +{ + public: + typedef void Print(char const*); + explicit CliHandler(Print* zprint) : m_print(zprint) {} + + // overwrite functions + const char *GetMangosString(int32 entry) const; + bool isAvailable(ChatCommand const& cmd) const; + void SendSysMessage(const char *str); + + private: + Print* m_print; +}; char const *fmtstring( char const *format, ... ); + +#endif diff --git a/src/game/Language.h b/src/game/Language.h index 4d4c155cf..be2a7cff2 100644 --- a/src/game/Language.h +++ b/src/game/Language.h @@ -77,7 +77,10 @@ enum MangosStrings LANG_NPC_TAINER_HELLO = 51, LANG_COMMAND_INVALID_ITEM_COUNT = 52, LANG_COMMAND_MAIL_ITEMS_LIMIT = 53, - // Room for more level 0 54-99 not used + LANG_NEW_PASSWORDS_NOT_MATCH = 54, + LANG_PASSWORD_TOO_LONG = 55, + LANG_MOTD_CURRENT = 56, + // Room for more level 0 57-99 not used // level 1 chat LANG_GLOBAL_NOTIFY = 100, @@ -161,7 +164,8 @@ enum MangosStrings LANG_MAIL_SENT = 169, LANG_SOUND_NOT_EXIST = 170, - // Room for more level 1 171-199 not used + LANG_TELEPORTED_TO_BY_CONSOLE = 171, + // Room for more level 1 172-199 not used // level 2 chat LANG_NO_SELECTION = 200, @@ -329,7 +333,8 @@ enum MangosStrings LANG_UNBAN_UNBANNED = 411, LANG_UNBAN_ERROR = 412, - LANG_BANINFO_NOACCOUNT = 413, + LANG_ACCOUNT_NOT_EXIST = 413, + LANG_BANINFO_NOCHARACTER = 414, LANG_BANINFO_NOIP = 415, LANG_BANINFO_NOACCOUNTBAN = 416, @@ -536,6 +541,14 @@ enum MangosStrings LANG_MOVEGENS_DISTRACT = 591, LANG_COMMAND_LEARN_ALL_RECIPES = 592, + LANG_BANLIST_ACCOUNTS = 593, + LANG_BANLIST_ACCOUNTS_HEADER = 594, + LANG_BANLIST_IPS = 595, + LANG_BANLIST_IPS_HEADER = 596, + LANG_GMLIST = 597, + LANG_GMLIST_HEADER = 598, + LANG_GMLIST_EMPTY = 599, + // End Level 3 list, continued at 1100 // Battleground LANG_BG_A_WINS = 600, @@ -635,7 +648,28 @@ enum MangosStrings LANG_ACCOUNT_FOR_PLAYER_NOT_FOUND = 809, // Room for in-game strings 810-999 not used - // FREE IDS 1000-9999 + // Level 4 (CLI only commands) + LANG_COMMAND_EXIT = 1000, + LANG_ACCOUNT_DELETED = 1001, + LANG_ACCOUNT_NOT_DELETED_SQL_ERROR = 1002, + LANG_ACCOUNT_NOT_DELETED = 1003, + LANG_ACCOUNT_CREATED = 1004, + LANG_ACCOUNT_TOO_LONG = 1005, + LANG_ACCOUNT_ALREADY_EXIST = 1006, + LANG_ACCOUNT_NOT_CREATED_SQL_ERROR = 1007, + LANG_ACCOUNT_NOT_CREATED = 1008, + LANG_CHARACTER_DELETED = 1009, + LANG_ACCOUNT_LIST_HEADER = 1010, + LANG_ACCOUNT_LIST_ERROR = 1011, + // Room for more level 4 1012-1099 not used + + // Level 3 (continue) + LANG_MOTD_NEW = 1100, + LANG_ACCOUNT_SETADDON = 1101, + LANG_SENDMESSAGE = 1102, + // Room for more level 3 1103-1199 not used + + // FREE IDS 1200-9999 // Use for not-in-svn patches 10000-10999 // Use for custom patches 11000-11999 diff --git a/src/game/Level0.cpp b/src/game/Level0.cpp index 48f3d7639..6a1244e83 100644 --- a/src/game/Level0.cpp +++ b/src/game/Level0.cpp @@ -52,7 +52,7 @@ bool ChatHandler::HandleCommandsCommand(const char* args) return true; } -bool ChatHandler::HandleAcctCommand(const char* /*args*/) +bool ChatHandler::HandleAccountCommand(const char* /*args*/) { uint32 gmlevel = m_session->GetSecurity(); PSendSysMessage(LANG_ACCOUNT_LEVEL, gmlevel); @@ -139,7 +139,7 @@ bool ChatHandler::HandleSaveCommand(const char* /*args*/) return true; } -bool ChatHandler::HandleGMListCommand(const char* /*args*/) +bool ChatHandler::HandleGMListOnlineCommand(const char* /*args*/) { bool first = true; @@ -147,8 +147,9 @@ bool ChatHandler::HandleGMListCommand(const char* /*args*/) HashMapHolder::MapType::iterator itr = m.begin(); for(; itr != m.end(); ++itr) { - if( itr->second->GetSession()->GetSecurity() && (itr->second->isGameMaster() || sWorld.getConfig(CONFIG_GM_IN_GM_LIST) ) && - itr->second->IsVisibleGloballyFor(m_session->GetPlayer()) ) + if (itr->second->GetSession()->GetSecurity() && + (itr->second->isGameMaster() || sWorld.getConfig(CONFIG_GM_IN_GM_LIST)) && + (!m_session || itr->second->IsVisibleGloballyFor(m_session->GetPlayer())) ) { if(first) { @@ -175,17 +176,24 @@ bool ChatHandler::HandlePasswordCommand(const char* args) char *new_pass = strtok (NULL, " "); char *new_pass_c = strtok (NULL, " "); - if( !old_pass || !new_pass || !new_pass_c ) + if (!old_pass || !new_pass || !new_pass_c) return false; std::string password_old = old_pass; std::string password_new = new_pass; std::string password_new_c = new_pass_c; - if(!accmgr.CheckPassword(m_session->GetAccountId(), password_old) || password_new != password_new_c) + if (password_new != password_new_c) { - SendSysMessage(LANG_COMMAND_WRONGOLDPASSWORD); - SetSentErrorMessage(true); + SendSysMessage (LANG_NEW_PASSWORDS_NOT_MATCH); + SetSentErrorMessage (true); + return false; + } + + if (!accmgr.CheckPassword (m_session->GetAccountId(), password_old)) + { + SendSysMessage (LANG_COMMAND_WRONGOLDPASSWORD); + SetSentErrorMessage (true); return false; } @@ -196,6 +204,11 @@ bool ChatHandler::HandlePasswordCommand(const char* args) case AOR_OK: SendSysMessage(LANG_COMMAND_PASSWORD); break; + case AOR_PASS_TOO_LONG: + SendSysMessage(LANG_PASSWORD_TOO_LONG); + SetSentErrorMessage(true); + return false; + case AOR_NAME_NOT_EXIST: // not possible case, don't want get account name for output default: SendSysMessage(LANG_COMMAND_NOTCHANGEPASSWORD); SetSentErrorMessage(true); @@ -231,3 +244,10 @@ bool ChatHandler::HandleLockAccountCommand(const char* args) SendSysMessage(LANG_USE_BOL); return true; } + +/// Display the 'Message of the day' for the realm +bool ChatHandler::HandleServerMotdCommand(const char* /*args*/) +{ + PSendSysMessage(LANG_MOTD_CURRENT, sWorld.GetMotd()); + return true; +} diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp index 48be118b2..57330eeff 100644 --- a/src/game/Level1.cpp +++ b/src/game/Level1.cpp @@ -2016,8 +2016,13 @@ bool ChatHandler::HandleNameTeleCommand(const char * args) PSendSysMessage(LANG_TELEPORTING_TO, chr->GetName(),"", tele->name.c_str()); - if (m_session->GetPlayer()->IsVisibleGloballyFor(chr)) - ChatHandler(chr).PSendSysMessage(LANG_TELEPORTED_TO_BY, m_session->GetPlayer()->GetName()); + if (m_session) + { + if(m_session->GetPlayer()->IsVisibleGloballyFor(chr)) + ChatHandler(chr).PSendSysMessage(LANG_TELEPORTED_TO_BY, m_session->GetPlayer()->GetName()); + } + else + ChatHandler(chr).SendSysMessage(LANG_TELEPORTED_TO_BY_CONSOLE); // stop flight if need if(chr->isInFlight()) diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index 43a8efe98..ce942af77 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -40,6 +40,7 @@ #include #include #include +#include "GlobalEvents.h" static uint32 ReputationRankStrIndex[MAX_REPUTATION_RANK] = { @@ -1699,7 +1700,7 @@ bool ChatHandler::HandleKickPlayerCommand(const char *args) return false; } - if(name==m_session->GetPlayer()->GetName()) + if(m_session && name==m_session->GetPlayer()->GetName()) { SendSysMessage(LANG_COMMAND_KICKSELF); SetSentErrorMessage(true); @@ -4006,3 +4007,10 @@ bool ChatHandler::LookupPlayerSearchCommand(QueryResult* result, int32 limit) return true; } + +/// Triggering corpses expire check in world +bool ChatHandler::HandleServerCorpsesCommand(const char* /*args*/) +{ + CorpsesErase(); + return true; +} diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 742ddaef8..455e19052 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -49,6 +49,7 @@ #include "ItemEnchantmentMgr.h" #include "InstanceSaveMgr.h" #include "InstanceData.h" +#include "AccountMgr.h" //reload commands bool ChatHandler::HandleReloadCommand(const char* arg) @@ -666,56 +667,47 @@ bool ChatHandler::HandleLoadScriptsCommand(const char* args) return true; } -bool ChatHandler::HandleSecurityCommand(const char* args) +bool ChatHandler::HandleAccountSetGmLevelCommand(const char* args) { char* arg1 = strtok((char*)args, " "); if( !arg1 ) return false; - char* arg2 = 0; + char* arg2 = strtok(NULL, " "); - std::string targetName; + std::string targetAccountName; uint32 targetAccountId = 0; uint32 targetSecurity = 0; + /// only target player different from self allowed (if targetPlayer!=NULL then not console) Player* targetPlayer = getSelectedPlayer(); - if(targetPlayer) + if(targetPlayer && m_session->GetPlayer()!=targetPlayer) { - targetName = targetPlayer->GetName(); + /// wrong command syntax or unexpected targeting + if(arg2) + return false; + targetAccountId = targetPlayer->GetSession()->GetAccountId(); targetSecurity = targetPlayer->GetSession()->GetSecurity(); - arg2 = arg1; + if(!accmgr.GetName(targetAccountId,targetAccountName)) + { + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str()); + SetSentErrorMessage(true); + return false; + } } else { - targetName = arg1; - if(!normalizePlayerName(targetName)) + targetAccountName = arg1; + if(!AccountMgr::normilizeString(targetAccountName)) { - SendSysMessage(LANG_PLAYER_NOT_FOUND); + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str()); SetSentErrorMessage(true); return false; } - targetPlayer = ObjectAccessor::Instance().FindPlayerByName(targetName.c_str()); - if(targetPlayer) - { - targetAccountId = targetPlayer->GetSession()->GetAccountId(); - targetSecurity = targetPlayer->GetSession()->GetSecurity(); - } - else - { - uint64 targetGUID = objmgr.GetPlayerGUIDByName(targetName.c_str()); - if(!targetGUID) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - targetAccountId = objmgr.GetPlayerAccountIdByGUID(targetGUID); - targetSecurity = accmgr.GetSecurity(targetAccountId); - } - - arg2 = strtok(NULL, " "); + targetAccountId = accmgr.GetId(targetAccountName); + targetSecurity = accmgr.GetSecurity(targetAccountId); } int32 gm = (int32)atoi(arg2); @@ -726,8 +718,12 @@ bool ChatHandler::HandleSecurityCommand(const char* args) return false; } - // can set security level only for target with less security and to less security that we have - if(targetSecurity >= m_session->GetSecurity() || uint32(gm) >= m_session->GetSecurity() ) + /// m_session==NULL only for console + uint32 plSecurity = m_session ? m_session->GetSecurity() : SEC_CONSOLE; + + /// can set security level only for target with less security and to less security that we have + /// This is also reject self apply in fact + if(targetSecurity >= plSecurity || uint32(gm) >= plSecurity ) { SendSysMessage(LANG_YOURS_SECURITY_IS_LOW); SetSentErrorMessage(true); @@ -736,18 +732,91 @@ bool ChatHandler::HandleSecurityCommand(const char* args) if(targetPlayer) { - if( targetPlayer != m_session->GetPlayer() ) - ChatHandler(targetPlayer).PSendSysMessage(LANG_YOURS_SECURITY_CHANGED,m_session->GetPlayer()->GetName(), gm); - + ChatHandler(targetPlayer).PSendSysMessage(LANG_YOURS_SECURITY_CHANGED,m_session->GetPlayer()->GetName(), gm); targetPlayer->GetSession()->SetSecurity(gm); } - PSendSysMessage(LANG_YOU_CHANGE_SECURITY, targetName.c_str(), gm); + PSendSysMessage(LANG_YOU_CHANGE_SECURITY, targetAccountName.c_str(), gm); loginDatabase.PExecute("UPDATE account SET gmlevel = '%i' WHERE id = '%u'", gm, targetAccountId); return true; } +/// Set password for account +bool ChatHandler::HandleAccountSetPasswordCommand(const char* args) +{ + if(!*args) + return false; + + ///- Get the command line arguments + char *szAccount = strtok ((char*)args," "); + char *szPassword1 = strtok (NULL," "); + char *szPassword2 = strtok (NULL," "); + + if (!szAccount||!szPassword1 || !szPassword2) + return false; + + std::string account_name = szAccount; + if(!AccountMgr::normilizeString(account_name)) + { + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + SetSentErrorMessage(true); + return false; + } + + uint32 targetAccountId = accmgr.GetId(account_name); + if (!targetAccountId) + { + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + SetSentErrorMessage(true); + return false; + } + + uint32 targetSecurity = accmgr.GetSecurity(targetAccountId); + + /// m_session==NULL only for console + uint32 plSecurity = m_session ? m_session->GetSecurity() : SEC_CONSOLE; + + /// can set password only for target with less security + /// This is also reject self apply in fact + if (targetSecurity >= plSecurity) + { + SendSysMessage (LANG_YOURS_SECURITY_IS_LOW); + SetSentErrorMessage (true); + return false; + } + + if (strcmp(szPassword1,szPassword2)) + { + SendSysMessage (LANG_NEW_PASSWORDS_NOT_MATCH); + SetSentErrorMessage (true); + return false; + } + + AccountOpResult result = accmgr.ChangePassword(targetAccountId, szPassword1); + + switch(result) + { + case AOR_OK: + SendSysMessage(LANG_COMMAND_PASSWORD); + break; + case AOR_NAME_NOT_EXIST: + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + SetSentErrorMessage(true); + return false; + case AOR_PASS_TOO_LONG: + SendSysMessage(LANG_PASSWORD_TOO_LONG); + SetSentErrorMessage(true); + return false; + default: + SendSysMessage(LANG_COMMAND_NOTCHANGEPASSWORD); + SetSentErrorMessage(true); + return false; + } + + return true; +} + bool ChatHandler::HandleAllowMovementCommand(const char* /*args*/) { if(sWorld.getAllowMovement()) @@ -4688,7 +4757,7 @@ bool ChatHandler::HandleBanCommand(const char* args) if(!reason) return false; - switch(sWorld.BanAccount(type, nameOrIP, duration, reason,m_session->GetPlayerName())) + switch(sWorld.BanAccount(type, nameOrIP, duration, reason,m_session ? m_session->GetPlayerName() : "")) { case BAN_SUCCESS: if(atoi(duration)>0) @@ -4749,17 +4818,20 @@ bool ChatHandler::HandleBanInfoCommand(const char* args) std::string accountname; if(type == "account") { - loginDatabase.escape_string(nameOrIP); - QueryResult *result = loginDatabase.PQuery("SELECT id, username FROM account WHERE username = '%s'",nameOrIP.c_str()); - if (!result) + std::string account_name = nameOrIP; + if(!AccountMgr::normilizeString(account_name)) { - PSendSysMessage(LANG_BANINFO_NOACCOUNT); + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + SetSentErrorMessage(true); + return false; + } + + accountid = accmgr.GetId(account_name); + if(!accountid) + { + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); return true; } - fields = result->Fetch(); - accountid = fields[0].GetUInt32(); - accountname = fields[1].GetCppString(); - delete result; } else if(type == "character") { @@ -4841,16 +4913,17 @@ bool ChatHandler::HandleBanListCommand(const char* args) loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); if(!*args) return false; + char* cType = strtok((char*)args, " "); char* cFilter = strtok(NULL, ""); if(!cType || !cFilter) return false; + std::string Filter = cFilter; std::string Type = cType; loginDatabase.escape_string(Filter); QueryResult* result = NULL; - Field *fields = NULL; if(Type == "ip") { result = loginDatabase.PQuery("SELECT ip FROM ip_banned WHERE ip "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),Filter.c_str()); @@ -4862,7 +4935,7 @@ bool ChatHandler::HandleBanListCommand(const char* args) PSendSysMessage(LANG_BANLIST_MATCHINGIP); do { - fields = result->Fetch(); + Field* fields = result->Fetch(); PSendSysMessage("%s",fields[0].GetString()); } while (result->NextRow()); @@ -4872,7 +4945,7 @@ bool ChatHandler::HandleBanListCommand(const char* args) //lookup accountid if(Type == "account") { - result = loginDatabase.PQuery("SELECT id FROM account WHERE username "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),Filter.c_str()); + result = loginDatabase.PQuery("SELECT id, username FROM account WHERE username "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),Filter.c_str()); if (!result) { PSendSysMessage(LANG_BANLIST_NOACCOUNT); @@ -4880,9 +4953,9 @@ bool ChatHandler::HandleBanListCommand(const char* args) } //do not delete result } - else if(Type == "characters") + else if(Type == "character") { - result = CharacterDatabase.PQuery("SELECT account FROM characters, WHERE name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),Filter.c_str()); + result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),Filter.c_str()); if (!result) { PSendSysMessage(LANG_BANLIST_NOCHARACTER); @@ -4893,18 +4966,108 @@ bool ChatHandler::HandleBanListCommand(const char* args) return false; PSendSysMessage(LANG_BANLIST_MATCHINGACCOUNT); - do + + // Chat short output + if(m_session) { - fields = result->Fetch(); - uint32 accountid = fields[0].GetUInt32(); - QueryResult* banresult = loginDatabase.PQuery("SELECT account.username FROM account,account_banned WHERE account_banned.id='%u' AND account_banned.active = '1' AND account_banned.id=account.id",accountid); - if(banresult) + do { - Field* fields2 = banresult->Fetch(); - PSendSysMessage("%s",fields2[0].GetString()); - delete banresult; + Field* fields = result->Fetch(); + uint32 accountid = fields[0].GetUInt32(); + + QueryResult* banresult = loginDatabase.PQuery("SELECT account.username FROM account,account_banned WHERE account_banned.id='%u' AND account_banned.active = '1' AND account_banned.id=account.id",accountid); + if(banresult) + { + Field* fields2 = banresult->Fetch(); + PSendSysMessage("%s",fields2[0].GetString()); + delete banresult; + } + } while (result->NextRow()); + } + // Console wide output + else + { + if(Type != "ip") + { + SendSysMessage(LANG_BANLIST_ACCOUNTS); + SendSysMessage("==============================================================================="); + SendSysMessage(LANG_BANLIST_ACCOUNTS_HEADER); + do + { + SendSysMessage("-------------------------------------------------------------------------------"); + Field *fields = result->Fetch(); + uint32 account_id = fields[0].GetUInt32 (); + + std::string account_name; + + // "account" case, name can be get in same quary + if(result->GetFieldCount() > 1) + account_name = fields[1].GetCppString(); + // "character" case, name need extract from another DB + else + accmgr.GetName (account_id,account_name); + + // No SQL injection. id is uint32. + QueryResult *banInfo = loginDatabase.PQuery("SELECT bandate,unbandate,bannedby,banreason FROM account_banned WHERE id = %u AND active = 1 ORDER BY unbandate", account_id); + if (banInfo) + { + Field *fields2 = banInfo->Fetch(); + do + { + time_t t_ban = fields2[0].GetUInt64(); + tm* aTm_ban = localtime(&t_ban); + + if (fields2[0].GetUInt64() == fields2[1].GetUInt64()) + { + PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|", + account_name.c_str(),aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min, + fields2[2].GetString(),fields2[3].GetString()); + } + else + { + time_t t_unban = fields2[1].GetUInt64(); + tm* aTm_unban = localtime(&t_unban); + PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|", + account_name.c_str(),aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min, + aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min, + fields2[2].GetString(),fields2[3].GetString()); + } + }while ( banInfo->NextRow() ); + delete banInfo; + } + }while( result->NextRow() ); + SendSysMessage("==============================================================================="); } - } while (result->NextRow()); + else + { + SendSysMessage(LANG_BANLIST_IPS); + SendSysMessage("==============================================================================="); + SendSysMessage(LANG_BANLIST_IPS_HEADER); + do + { + SendSysMessage("-------------------------------------------------------------------------------"); + Field *fields = result->Fetch(); + time_t t_ban = fields[1].GetUInt64(); + tm* aTm_ban = localtime(&t_ban); + if ( fields[1].GetUInt64() == fields[2].GetUInt64() ) + { + PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d| permanent |%-15.15s|%-15.15s|", + fields[0].GetString(), aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min, + fields[3].GetString(), fields[4].GetString()); + } + else + { + time_t t_unban = fields[2].GetUInt64(); + tm* aTm_unban = localtime(&t_unban); + PSendSysMessage("|%-15.15s|%02d-%02d-%02d %02d:%02d|%02d-%02d-%02d %02d:%02d|%-15.15s|%-15.15s|", + fields[0].GetString(), aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min, + aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min, + fields[3].GetString(), fields[4].GetString()); + } + }while( result->NextRow() ); + SendSysMessage("==============================================================================="); + } + } delete result; return true; @@ -4960,19 +5123,29 @@ bool ChatHandler::HandleLoadPDumpCommand(const char *args) if(!args) return false; - char * file = strtok((char*)args, " "); if(!file) return false; - char * acc = strtok(NULL, " "); if(!acc) return false; - if(!file || !acc) + char * file = strtok((char*)args, " "); + if(!file) return false; - uint32 account_id = accmgr.GetId(acc); + char * account = strtok(NULL, " "); + if(!account) + return false; + + std::string account_name = account; + if(!AccountMgr::normilizeString(account_name)) + { + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + SetSentErrorMessage(true); + return false; + } + + uint32 account_id = accmgr.GetId(account_name); if(!account_id) { - account_id = atoi(acc); + account_id = atoi(account); // use original string if(account_id) { - std::string acc_name; - if(!accmgr.GetName(account_id,acc_name)) + if(!accmgr.GetName(account_id,account_name)) return false; } else @@ -5516,3 +5689,132 @@ bool ChatHandler::HandleInstanceSaveDataCommand(const char * /*args*/) ((InstanceMap*)map)->GetInstanceData()->SaveToDB(); return true; } + +/// Display the list of GMs +bool ChatHandler::HandleGMListFullCommand(const char* /*args*/) +{ + ///- Get the accounts with GM Level >0 + QueryResult *result = loginDatabase.Query( "SELECT username,gmlevel FROM account WHERE gmlevel > 0" ); + if(result) + { + SendSysMessage(LANG_GMLIST); + SendSysMessage("========================"); + SendSysMessage(LANG_GMLIST_HEADER); + SendSysMessage("========================"); + + ///- Circle through them. Display username and GM level + do + { + Field *fields = result->Fetch(); + PSendSysMessage("|%15s|%6s|", fields[0].GetString(),fields[1].GetString()); + }while( result->NextRow() ); + + PSendSysMessage("========================"); + delete result; + } + else + PSendSysMessage(LANG_GMLIST_EMPTY); + return true; +} + +/// Define the 'Message of the day' for the realm +bool ChatHandler::HandleServerSetMotdCommand(const char* args) +{ + sWorld.SetMotd(args); + PSendSysMessage(LANG_MOTD_NEW, args); + return true; +} + +/// Set/Unset the expansion level for an account +bool ChatHandler::HandleAccountSetAddonCommand(const char* args) +{ + ///- Get the command line arguments + char *szAcc = strtok((char*)args," "); + char *szExp = strtok(NULL," "); + + if(!szAcc) + return false; + + std::string account_name; + uint32 account_id; + + if(!szExp) + { + Player* player = getSelectedPlayer(); + if(!player) + return false; + + account_id = player->GetSession()->GetAccountId(); + accmgr.GetName(account_id,account_name); + szExp = szAcc; + } + else + { + ///- Convert Account name to Upper Format + account_name = szAcc; + if(!AccountMgr::normilizeString(account_name)) + { + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + SetSentErrorMessage(true); + return false; + } + + account_id = accmgr.GetId(account_name); + if(!account_id) + { + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + SetSentErrorMessage(true); + return false; + } + } + + int lev=atoi(szExp); //get int anyway (0 if error) + if(lev < 0) + return false; + + // No SQL injection + loginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE id = '%u'",lev,account_id); + PSendSysMessage(LANG_ACCOUNT_SETADDON,account_name.c_str(),account_id,lev); + return true; +} + +/// Send a message to a player in game +bool ChatHandler::HandleSendMessageCommand(const char* args) +{ + ///- Get the command line arguments + char* name_str = strtok((char*)args, " "); + char* msg_str = strtok(NULL, ""); + + if(!name_str || !msg_str) + return false; + + std::string name = name_str; + + if(!normalizePlayerName(name)) + return false; + + ///- Find the player and check that he is not logging out. + Player *rPlayer = objmgr.GetPlayer(name.c_str()); + if(!rPlayer) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + if(rPlayer->GetSession()->isLogingOut()) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + ///- Send the message + //Use SendAreaTriggerMessage for fastest delivery. + rPlayer->GetSession()->SendAreaTriggerMessage("%s", msg_str); + rPlayer->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r"); + + //Confirmation message + PSendSysMessage(LANG_SENDMESSAGE,name.c_str(),msg_str); + return true; +} diff --git a/src/game/World.cpp b/src/game/World.cpp index 2badcae6b..7f96992c5 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -2455,20 +2455,25 @@ void World::UpdateSessions( time_t diff ) // This handles the issued and queued CLI commands void World::ProcessCliCommands() { - if (cliCmdQueue.empty()) return; + if (cliCmdQueue.empty()) + return; + + CliCommandHolder::Print* zprint; - CliCommandHolder *command; - pPrintf p_zprintf; while (!cliCmdQueue.empty()) { sLog.outDebug("CLI command under processing..."); - command = cliCmdQueue.next(); - command->Execute(); - p_zprintf=command->GetOutputMethod(); + CliCommandHolder *command = cliCmdQueue.next(); + + zprint = command->m_print; + + CliHandler(zprint).ParseCommands(command->m_command); + delete command; } + // print the console message here so it looks right - p_zprintf("mangos>"); + zprint("mangos>"); } void World::InitResultQueue() diff --git a/src/game/World.h b/src/game/World.h index f70ea7b19..4de067f6d 100644 --- a/src/game/World.h +++ b/src/game/World.h @@ -38,7 +38,6 @@ class Player; class Weather; struct ScriptAction; struct ScriptInfo; -class CliCommandHolder; class SqlResultQueue; class QueryResult; class WorldSocket; @@ -295,37 +294,23 @@ enum BanReturn #define SCRIPT_COMMAND_REMOVE_AURA 14 // source (datalong2!=0) or target (datalong==0) unit, datalong = spell_id #define SCRIPT_COMMAND_CAST_SPELL 15 // source (datalong2!=0) or target (datalong==0) unit, datalong = spell_id -/// CLI related stuff, define here to prevent cyclic dependancies - -typedef int(* pPrintf)(const char*,...); -typedef void(* pCliFunc)(char *,pPrintf); - -/// Command Template class -struct CliCommand -{ - char const * cmd; - pCliFunc Func; - char const * description; -}; - /// Storage class for commands issued for delayed execution -class CliCommandHolder +struct CliCommandHolder { - private: - const CliCommand *cmd; - char *args; - pPrintf m_zprintf; - public: - CliCommandHolder(const CliCommand *command, const char *arguments, pPrintf p_zprintf) - : cmd(command), m_zprintf(p_zprintf) - { - size_t len = strlen(arguments)+1; - args = new char[len]; - memcpy(args, arguments, len); - } - ~CliCommandHolder() { delete[] args; } - void Execute() const { cmd->Func(args, m_zprintf); } - pPrintf GetOutputMethod() const {return (m_zprintf);} + typedef void Print(const char*); + + char *m_command; + Print* m_print; + + CliCommandHolder(const char *command, Print* zprint) + : m_print(zprint) + { + size_t len = strlen(command)+1; + m_command = new char[len]; + memcpy(m_command, command, len); + } + + ~CliCommandHolder() { delete[] m_command; } }; /// The World @@ -463,7 +448,7 @@ class World static float GetVisibleObjectGreyDistance() { return m_VisibleObjectGreyDistance; } void ProcessCliCommands(); - void QueueCliCommand(CliCommandHolder* command) { cliCmdQueue.add(command); } + void QueueCliCommand( CliCommandHolder::Print* zprintf, char const* input ) { cliCmdQueue.add(new CliCommandHolder(input, zprintf)); } void UpdateResultQueue(); void InitResultQueue(); diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp index 3aeb1749b..64136ddec 100644 --- a/src/game/WorldSession.cpp +++ b/src/game/WorldSession.cpp @@ -457,7 +457,7 @@ void WorldSession::SendNotification(int32 string_id,...) } } -const char * WorldSession::GetMangosString( int32 entry ) +const char * WorldSession::GetMangosString( int32 entry ) const { return objmgr.GetMangosString(entry,GetSessionDbLocaleIndex()); } diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h index 6ca124266..aebc44903 100644 --- a/src/game/WorldSession.h +++ b/src/game/WorldSession.h @@ -193,9 +193,9 @@ class MANGOS_DLL_SPEC WorldSession time_t m_muteTime; // Locales - LocaleConstant GetSessionDbcLocale() { return m_sessionDbcLocale; } - int GetSessionDbLocaleIndex() { return m_sessionDbLocaleIndex; } - const char *GetMangosString(int32 entry); + LocaleConstant GetSessionDbcLocale() const { return m_sessionDbcLocale; } + int GetSessionDbLocaleIndex() const { return m_sessionDbLocaleIndex; } + const char *GetMangosString(int32 entry) const; uint32 GetLatency() const { return m_latency; } void SetLatency(uint32 latency) { m_latency = latency; } diff --git a/src/mangosd/CliRunnable.cpp b/src/mangosd/CliRunnable.cpp index 637c8d30b..b48e1c576 100644 --- a/src/mangosd/CliRunnable.cpp +++ b/src/mangosd/CliRunnable.cpp @@ -25,7 +25,6 @@ #include "Log.h" #include "World.h" #include "ScriptCalls.h" -#include "GlobalEvents.h" #include "ObjectMgr.h" #include "WorldSession.h" #include "SystemConfig.h" @@ -34,254 +33,108 @@ #include "AccountMgr.h" #include "CliRunnable.h" #include "MapManager.h" -#include "PlayerDump.h" #include "Player.h" +#include "Chat.h" -//CliCommand and CliCommandHolder are defined in World.h to avoid cyclic deps - -//func prototypes must be defined - -void CliHelp(char*,pPrintf); -void CliInfo(char*,pPrintf); -void CliBan(char*,pPrintf); -void CliBanList(char*,pPrintf); -void CliRemoveBan(char*,pPrintf); -void CliSetGM(char*,pPrintf); -void CliListGM(char*,pPrintf); -void CliVersion(char*,pPrintf); -void CliExit(char*,pPrintf); -void CliIdleRestart(char*,pPrintf zprintf); -void CliRestart(char*,pPrintf zprintf); -void CliIdleShutdown(char*,pPrintf zprintf); -void CliShutdown(char*,pPrintf zprintf); -void CliBroadcast(char*,pPrintf); -void CliCreate(char*,pPrintf); -void CliDelete(char*,pPrintf); -void CliCharDelete(char *,pPrintf); -void CliLoadScripts(char*,pPrintf); -void CliKick(char*,pPrintf); -void CliTele(char*,pPrintf); -void CliMotd(char*,pPrintf); -void CliCorpses(char*,pPrintf); -void CliSetLogLevel(char*,pPrintf); -void CliUpTime(char*,pPrintf); -void CliSetAddon(char*,pPrintf); -void CliWritePlayerDump(char*,pPrintf); -void CliLoadPlayerDump(char*,pPrintf); -void CliSave(char*,pPrintf); -void CliSend(char*,pPrintf); -void CliPLimit(char*,pPrintf); -void CliSetPassword(char*,pPrintf); -/// Table of known commands -const CliCommand Commands[]= +void utf8print(const char* str) { - {"help", & CliHelp,"Display this help message"}, - {"broadcast", & CliBroadcast,"Announce in-game message"}, - {"create", & CliCreate,"Create account"}, - {"delete", & CliDelete,"Delete account and characters"}, - {"chardelete", & CliCharDelete,"Delete character"}, - {"info", & CliInfo,"Display Server infomation"}, - {"uptime", & CliUpTime, "Displays the server uptime"}, - {"motd", & CliMotd,"Change or display motd"}, - {"kick", & CliKick,"Kick user"}, - {"ban", & CliBan,"Ban account|ip"}, - {"listbans", & CliBanList,"List bans"}, - {"unban", & CliRemoveBan,"Remove ban from account|ip"}, - {"setgm", & CliSetGM,"Edit user privileges"}, - {"setpass", & CliSetPassword,"Set password for account"}, - {"setaddon", & CliSetAddon,"Set user expansion addon level allowed"}, - {"listgm", & CliListGM,"Display user privileges"}, - {"loadscripts", & CliLoadScripts,"Load script library"}, - {"setloglevel", & CliSetLogLevel,"Set Log Level"}, - {"corpses", & CliCorpses,"Manually call corpses erase global even code"}, - {"version", & CliVersion,"Display server version"}, - {"idlerestart", & CliIdleRestart,"Restart server with some delay when there are no active connections remaining"}, - {"restart", & CliRestart,"Restart server with some delay"}, - {"idleshutdown", & CliIdleShutdown,"Shutdown server with some delay when there are no active connections remaining"}, - {"shutdown", & CliShutdown,"Shutdown server with some delay"}, - {"exit", & CliExit,"Shutdown server NOW"}, - {"writepdump", &CliWritePlayerDump,"Write a player dump to a file"}, - {"loadpdump", &CliLoadPlayerDump,"Load a player dump from a file"}, - {"saveall", &CliSave,"Save all players"}, - {"send", &CliSend,"Send message to a player"}, - {"tele", &CliTele,"Teleport player to location"}, - {"plimit", &CliPLimit,"Show or set player login limitations"} -}; -/// \todo Need some pragma pack? Else explain why in a comment. -#define CliTotalCmds sizeof(Commands)/sizeof(CliCommand) - #if PLATFORM == PLATFORM_WINDOWS -int utf8printf(const char* str,...) -{ - UTF8PRINTF(stdout,str,1); - return 0; -} -#define UTF8ZPRINTF utf8printf + wchar_t wtemp_buf[6000]; + size_t wtemp_len = 6000-1; + if(!Utf8toWStr(str,strlen(str),wtemp_buf,wtemp_len)) + return; + + char temp_buf[6000]; + CharToOemBuffW(&wtemp_buf[0],&temp_buf[0],wtemp_len+1); + printf(temp_buf); #else -#define UTF8ZPRINTF printf + printf(str); #endif - -/// Create a character dump file -void CliWritePlayerDump(char*command,pPrintf zprintf) -{ - char * file = strtok(command, " "); - char * p2 = strtok(NULL, " "); - if(!file || !p2) - { - zprintf("Syntax is: writepdump $filename $playerNameOrGUID\r\n"); - return; - } - - std::string name; - if(!consoleToUtf8(p2,name)) // convert from console encoding to utf8 - return; - - if(!normalizePlayerName(name)) - { - zprintf("Syntax is: writepdump $filename $playerNameOrGUID\r\n"); - return; - } - - uint32 guid = objmgr.GetPlayerGUIDByName(name); - if(!guid) - guid = atoi(p2); - - if(!guid) - { - zprintf("Syntax is: writepdump $filename $playerNameOrGUID\r\n"); - return; - } - - PlayerDumpWriter().WriteDump(file, guid); -} - -/// Load a character from a dump file -void CliLoadPlayerDump(char*command,pPrintf zprintf) -{ - char * file = strtok(command, " "); - char * acc = strtok(NULL, " "); - if (!file ||!acc) - { - zprintf("Syntax is: loadpdump $filename $account ($newname) ($newguid)\r\n"); - return; - } - - uint32 account_id = accmgr.GetId(acc); - if(!account_id) - { - account_id = atoi(acc); - if(account_id) - { - std::string acc_name; - if(!accmgr.GetName(account_id,acc_name)) - { - zprintf("Failed to load the character! Account not exist.\r\n"); - return; - } - } - else - { - zprintf("Failed to load the character! Account not exist.\r\n"); - return; - } - } - - char * name_str = strtok(NULL, " "); - char * guid_str = name_str ? strtok(NULL, " ") : NULL; - - uint32 guid = guid_str ? atoi(guid_str) : 0; - - std::string name; - if(name_str) - { - if(!consoleToUtf8(name_str,name)) // convert from console encoding to utf8 - return; - - if(!normalizePlayerName(name)) - { - zprintf("Syntax is: loadpdump $filename $account ($newname) ($newguid)\r\n"); - return; - } - } - - if(PlayerDumpReader().LoadDump(file, account_id, name, guid)) - zprintf("Character loaded successfully!\r\n"); - else - zprintf("Failed to load the character!\r\n"); -} - -/// Reload the scripts and notify the players -void CliLoadScripts(char*command,pPrintf zprintf) -{ - char const *del=strtok(command," "); - if (!del) - del=""; - if(!LoadScriptingModule(del)) // Error report is already done by LoadScriptingModule - return; - - sWorld.SendWorldText(LANG_SCRIPTS_RELOADED); } /// Delete a user account and all associated characters in this realm /// \todo This function has to be enhanced to respect the login/realm split (delete char, delete account chars in realm, delete account chars in realm then delete account -void CliDelete(char*command,pPrintf zprintf) +bool ChatHandler::HandleAccountDeleteCommand(const char* args) { + if(!*args) + return false; + ///- Get the account name from the command line - char *account_name_str=strtok(command," "); - if(!account_name_str) + char *account_name_str=strtok ((char*)args," "); + if (!account_name_str) + return false; + + std::string account_name = account_name_str; + if(!AccountMgr::normilizeString(account_name)) { - // \r\n is used because this function can also be called from RA - zprintf("Syntax is: delete $account\r\n"); - return; + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + SetSentErrorMessage(true); + return false; } - std::string account_name; - if(!consoleToUtf8(account_name_str,account_name)) // convert from console encoding to utf8 - return; + uint32 account_id = accmgr.GetId(account_name); + if(!account_id) + { + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + SetSentErrorMessage(true); + return false; + } - AccountOpResult result = accmgr.DeleteAccount(accmgr.GetId(account_name)); + /// Commands not recommended call from chat, but support anyway + if(m_session) + { + uint32 targetSecurity = accmgr.GetSecurity(account_id); + + /// can delete only for account with less security + /// This is also reject self apply in fact + if (targetSecurity >= m_session->GetSecurity()) + { + SendSysMessage (LANG_YOURS_SECURITY_IS_LOW); + SetSentErrorMessage (true); + return false; + } + } + + AccountOpResult result = accmgr.DeleteAccount(account_id); switch(result) { case AOR_OK: - zprintf("We deleted account: %s\r\n",account_name.c_str()); + PSendSysMessage(LANG_ACCOUNT_DELETED,account_name.c_str()); break; case AOR_NAME_NOT_EXIST: - zprintf("User %s does not exist\r\n",account_name.c_str()); - break; + PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); + SetSentErrorMessage(true); + return false; case AOR_DB_INTERNAL_ERROR: - zprintf("User %s NOT deleted (probably sql file format was updated)\r\n",account_name.c_str()); - break; + PSendSysMessage(LANG_ACCOUNT_NOT_DELETED_SQL_ERROR,account_name.c_str()); + SetSentErrorMessage(true); + return false; default: - zprintf("User %s NOT deleted (unknown error)\r\n",account_name.c_str()); - break; + PSendSysMessage(LANG_ACCOUNT_NOT_DELETED,account_name.c_str()); + SetSentErrorMessage(true); + return false; } + + return true; } -void CliCharDelete(char*command,pPrintf zprintf) +bool ChatHandler::HandleCharacterDeleteCommand(const char* args) { - char *character_name_str = strtok(command," "); + if(!*args) + return false; + char *character_name_str = strtok((char*)args," "); if(!character_name_str) - { - zprintf("Syntax is: chardelete $character_name\r\n"); - return; - } - - std::string character_name; - if(!consoleToUtf8(character_name_str,character_name)) // convert from console encoding to utf8 - return; + return false; + std::string character_name = character_name_str; if(!normalizePlayerName(character_name)) - { - zprintf("Syntax is: chardelete $character_name\r\n"); - return; - } - - Player *player = objmgr.GetPlayer(character_name.c_str()); + return false; uint64 character_guid; uint32 account_id; + Player *player = objmgr.GetPlayer(character_name.c_str()); if(player) { character_guid = player->GetGUID(); @@ -293,185 +146,42 @@ void CliCharDelete(char*command,pPrintf zprintf) character_guid = objmgr.GetPlayerGUIDByName(character_name); if(!character_guid) { - zprintf("Player %s not found!\r\n",character_name.c_str()); - return; + PSendSysMessage(LANG_NO_PLAYER,character_name.c_str()); + SetSentErrorMessage(true); + return false; } account_id = objmgr.GetPlayerAccountIdByGUID(character_guid); } + std::string account_name; + accmgr.GetName (account_id,account_name); + Player::DeleteFromDB(character_guid, account_id, true); - zprintf("Player %s (Guid: %u AccountId: %u) deleted\r\n",character_name.c_str(),GUID_LOPART(character_guid),account_id); -} - -/// Broadcast a message to the World -void CliBroadcast(char *text,pPrintf zprintf) -{ - std::string textUtf8; - if(!consoleToUtf8(text,textUtf8)) // convert from console encoding to utf8 - return; - - sWorld.SendWorldText(LANG_SYSTEMMESSAGE,textUtf8.c_str()); - zprintf("Broadcasting to the world: %s\r\n",textUtf8.c_str()); -} - -/// Print the list of commands and associated description -void CliHelp(char*,pPrintf zprintf) -{ - for (unsigned int x=0;x 0"); - if (!resultDB) - return; + return true; ///- Display the list of account/characters online - zprintf("=====================================================================\r\n"); - zprintf("| Account | Character | IP | GM | TBC |\r\n"); - zprintf("=====================================================================\r\n"); + SendSysMessage("====================================================================="); + SendSysMessage(LANG_ACCOUNT_LIST_HEADER); + SendSysMessage("====================================================================="); ///- Circle through accounts do @@ -488,708 +198,77 @@ void CliInfo(char*,pPrintf zprintf) if(resultLogin) { Field *fieldsLogin = resultLogin->Fetch(); - zprintf("|%15s| %20s | %15s |%4d|%5d|\r\n", + PSendSysMessage("|%15s| %20s | %15s |%4d|%5d|", fieldsLogin[0].GetString(),name.c_str(),fieldsLogin[1].GetString(),fieldsLogin[2].GetUInt32(),fieldsLogin[3].GetUInt32()); delete resultLogin; } else - zprintf("| | %20s | |||\r\n",name.c_str()); + PSendSysMessage(LANG_ACCOUNT_LIST_ERROR,name.c_str()); }while(resultDB->NextRow()); delete resultDB; - zprintf("=====================================================================\r\n"); -} - -/// Display a list of banned accounts and ip addresses -void CliBanList(char*,pPrintf zprintf) -{ - bool found = false; - ///- Get the list of banned accounts and display them - QueryResult *result = loginDatabase.Query("SELECT id,username FROM account WHERE id IN (SELECT id FROM account_banned WHERE active = 1)"); - if(result) - { - found = true; - - zprintf("Currently Banned Accounts:\r\n"); - zprintf("===============================================================================\r\n"); - zprintf("| Account | BanDate | UnbanDate | Banned By | Ban Reason |\r\n"); - do - { - zprintf("-------------------------------------------------------------------------------\r\n"); - Field *fields = result->Fetch(); - // No SQL injection. id is uint32. - QueryResult *banInfo = loginDatabase.PQuery("SELECT bandate,unbandate,bannedby,banreason FROM account_banned WHERE id = %u AND active = 1 ORDER BY unbandate", fields[0].GetUInt32()); - if (banInfo) - { - Field *fields2 = banInfo->Fetch(); - do - { - time_t t_ban = fields2[0].GetUInt64(); - tm* aTm_ban = localtime(&t_ban); - zprintf("|%-15.15s|", fields[1].GetString()); - zprintf("%02d-%02d-%02d %02d:%02d|", aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min); - if ( fields2[0].GetUInt64() == fields2[1].GetUInt64() ) - zprintf(" permanent |"); - else - { - time_t t_unban = fields2[1].GetUInt64(); - tm* aTm_unban = localtime(&t_unban); - zprintf("%02d-%02d-%02d %02d:%02d|",aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min); - } - zprintf("%-15.15s|%-15.15s|\r\n",fields2[2].GetString(),fields2[3].GetString()); - }while ( banInfo->NextRow() ); - delete banInfo; - } - }while( result->NextRow() ); - zprintf("===============================================================================\r\n"); - delete result; - } - - ///- Get the list of banned IP addresses and display them - result = loginDatabase.Query( "SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP()) ORDER BY unbandate" ); - if(result) - { - found = true; - - zprintf("Currently Banned IPs:\r\n"); - zprintf("===============================================================================\r\n"); - zprintf("| IP | BanDate | UnbanDate | Banned By | Ban Reason |\r\n"); - do - { - zprintf("-------------------------------------------------------------------------------\r\n"); - Field *fields = result->Fetch(); - time_t t_ban = fields[1].GetUInt64(); - tm* aTm_ban = localtime(&t_ban); - zprintf("|%-15.15s|", fields[0].GetString()); - zprintf("%02d-%02d-%02d %02d:%02d|", aTm_ban->tm_year%100, aTm_ban->tm_mon+1, aTm_ban->tm_mday, aTm_ban->tm_hour, aTm_ban->tm_min); - if ( fields[1].GetUInt64() == fields[2].GetUInt64() ) - zprintf(" permanent |"); - else - { - time_t t_unban = fields[2].GetUInt64(); - tm* aTm_unban = localtime(&t_unban); - zprintf("%02d-%02d-%02d %02d:%02d|", aTm_unban->tm_year%100, aTm_unban->tm_mon+1, aTm_unban->tm_mday, aTm_unban->tm_hour, aTm_unban->tm_min); - } - zprintf("%-15.15s|%-15.15s|\r\n", fields[3].GetString(), fields[4].GetString()); - }while( result->NextRow() ); - zprintf("===============================================================================\r\n"); - delete result; - } - - if(!found) - zprintf("We do not have banned users\r\n"); -} - -/// Ban an IP address or a user account -void CliBan(char*command,pPrintf zprintf) -{ - ///- Get the command parameter - char* type_str = strtok((char*)command, " "); - char* nameOrIP_str = strtok(NULL, " "); - char* duration_str = strtok(NULL," "); - char* reason_str = strtok(NULL,""); - - if(!type_str||!nameOrIP_str||!duration_str||!reason_str)// ?!? input of single char "0"-"9" wouldn't detect when with: || !atoi(duration) - { - zprintf("Syntax: ban account|ip|character $AccountOrIpOrCharacter $duration[s|m|h|d] $reason \r\n"); - return; - } - - std::string type; - if(!consoleToUtf8(type_str,type)) // convert from console encoding to utf8 - return; - - std::string nameOrIP; - if(!consoleToUtf8(nameOrIP_str,nameOrIP)) // convert from console encoding to utf8 - return; - - std::string duration; - if(!consoleToUtf8(duration_str,duration)) // convert from console encoding to utf8 - return; - - std::string reason; - if(!consoleToUtf8(reason_str,reason)) // convert from console encoding to utf8 - return; - - switch (sWorld.BanAccount(type, nameOrIP, duration, reason, "Set by console.")) - { - case BAN_SUCCESS: - if(atoi(duration_str)>0) - zprintf("%s is banned for %s. Reason: %s.\r\n",nameOrIP.c_str(),secsToTimeString(TimeStringToSecs(duration_str),true,false).c_str(),reason.c_str()); - else - zprintf("%s is banned permanently. Reason: %s.\r\n",nameOrIP.c_str(),reason.c_str()); - break; - case BAN_NOTFOUND: - zprintf("%s %s not found\r\n", type.c_str(), nameOrIP.c_str()); - break; - case BAN_SYNTAX_ERROR: - zprintf("Syntax: ban account|ip|character $AccountOrIpOrCharacter $duration[s|m|h|d] $reason \r\n"); - break; - } -} - -/// Display %MaNGOS version -void CliVersion(char*,pPrintf zprintf) -{ - //<--maybe better append to info cmd - zprintf( "%s (world-daemon)\r\n", _FULLVERSION ); -} - -/// Unban an IP adress or a user account -void CliRemoveBan(char *command,pPrintf zprintf) -{ - ///- Get the command parameter - char *type_str = strtok(command," "); - char *nameorip_str = strtok(NULL," "); - if(!nameorip_str||!type_str) - { - zprintf("Syntax is: unban account|ip|character $nameorip\r\n"); - return; - } - - std::string type; - if(!consoleToUtf8(type_str,type)) // convert from console encoding to utf8 - return; - - std::string nameorip; - if(!consoleToUtf8(nameorip_str,nameorip)) // convert from console encoding to utf8 - return; - - if (!sWorld.RemoveBanAccount(type, nameorip)) - zprintf("%s %s not found\r\n", type.c_str(), nameorip.c_str()); - else - zprintf("We removed ban from %s: %s\r\n",type_str,nameorip.c_str()); -} - -/// Display the list of GMs -void CliListGM(char*,pPrintf zprintf) -{ - - ///- Get the accounts with GM Level >0 - Field *fields; - - QueryResult *result = loginDatabase.Query( "SELECT username,gmlevel FROM account WHERE gmlevel > 0" ); - if(result) - { - - zprintf("Current gamemasters:\r\n"); - zprintf("========================\r\n"); - zprintf("| Account | GM |\r\n"); - zprintf("========================\r\n"); - - ///- Circle through them. Display username and GM level - do - { - fields = result->Fetch(); - zprintf("|%15s|", fields[0].GetString()); - zprintf("%6s|\r\n",fields[1].GetString()); - }while( result->NextRow() ); - - zprintf("========================\r\n"); - delete result; - } - else - { - zprintf("No gamemasters\r\n"); - } -} - -/// Set the GM level of an account -void CliSetGM(char *command,pPrintf zprintf) -{ - ///- Get the command line arguments - char *szAcc = strtok(command," "); - char *szLevel = strtok(NULL," "); - - if(!szAcc||!szLevel) //wrong syntax 'setgm' without name - { - zprintf("Syntax is: setgm $account $number (0 - normal, 3 - gamemaster)>\r\n"); - return; - } - - //wow it's ok,let's hope it was integer given - int lev=atoi(szLevel); //get int anyway (0 if error) - - std::string safe_account_name; - if(!consoleToUtf8(szAcc,safe_account_name)) // convert from console encoding to utf8 - return; - - ///- Convert Account name to Upper Format - AccountMgr::normilizeString(safe_account_name); - - ///- Escape the account name to allow quotes in names - loginDatabase.escape_string(safe_account_name); - - ///- Try to find the account, then update the GM level - // No SQL injection (account name is escaped) - QueryResult *result = loginDatabase.PQuery("SELECT id FROM account WHERE username = '%s'",safe_account_name.c_str()); - - if (result) - { - Field *fields = result->Fetch(); - uint32 account_id = fields[0].GetUInt32(); - delete result; - - WorldSession* session = sWorld.FindSession(account_id); - if(session) - session->SetSecurity(lev); - - // No SQL injection (account name is escaped) - loginDatabase.PExecute("UPDATE account SET gmlevel = '%d' WHERE username = '%s'",lev,safe_account_name.c_str()); - zprintf("We set %s gmlevel %d\r\n",safe_account_name.c_str(),lev); - } - else - { - zprintf("No account %s found\r\n",safe_account_name.c_str()); - } -} - -/// Set password for account -void CliSetPassword(char *command,pPrintf zprintf) -{ - ///- Get the command line arguments - char *szAcc = strtok(command," "); - char *szPassword1 = strtok(NULL," "); - char *szPassword2 = strtok(NULL," "); - - if(!szAcc||!szPassword1 || !szPassword2) - { - zprintf("Syntax is: setpass $account $password $password\r\n"); - return; - } - - std::string account_name; - if(!consoleToUtf8(szAcc,account_name)) // convert from console encoding to utf8 - return; - - std::string pass1; - if(!consoleToUtf8(szPassword1,pass1)) // convert from console encoding to utf8 - return; - - std::string pass2; - if(!consoleToUtf8(szPassword2,pass2)) // convert from console encoding to utf8 - return; - - uint32 acc_id = accmgr.GetId(szAcc); - if (!acc_id) - { - zprintf("Account '%s' does not exist!\r\n", account_name.c_str()); - return; - } - - if (pass1 != pass2) - { - zprintf("Password does not match the confirm password, password not changed!\r\n"); - return; - } - - AccountOpResult result = accmgr.ChangePassword(acc_id, pass1); - - switch(result) - { - case AOR_OK: - zprintf("The password was changed for account '%s' (ID: %u).\r\n",account_name.c_str(),acc_id); - break; - case AOR_PASS_TOO_LONG: - zprintf("Password can't be longer than 16 characters (client limit), password not changed!\r\n"); - break; - case AOR_NAME_NOT_EXIST: - zprintf("Account '%s' does not exist!\r\n", account_name.c_str()); - break; - case AOR_DB_INTERNAL_ERROR: - zprintf("Password not changed! (probably sql file format was updated)\r\n"); - break; - default: - zprintf("Password not changed! (unknown error\r\n"); - break; - } + SendSysMessage("====================================================================="); + return true; } /// Create an account -void CliCreate(char *command,pPrintf zprintf) +bool ChatHandler::HandleAccountCreateCommand(const char* args) { - //I see no need in this function (why would an admin personally create accounts - //instead of using account registration page or accessing db directly?) - //but still let it be + if(!*args) + return false; ///- %Parse the command line arguments - char *szAcc = strtok(command, " "); + char *szAcc = strtok((char*)args, " "); char *szPassword = strtok(NULL, " "); if(!szAcc || !szPassword) - { - zprintf("Syntax is: create $username $password\r\n"); - return; - } + return false; - std::string account_name; - if(!consoleToUtf8(szAcc,account_name)) // convert from console encoding to utf8 - return; - - std::string password; - if(!consoleToUtf8(szPassword,password)) // convert from console encoding to utf8 - return; + // normilized in accmgr.CreateAccount + std::string account_name = szAcc; + std::string password = szPassword; AccountOpResult result = accmgr.CreateAccount(account_name, password); switch(result) { case AOR_OK: - zprintf("User %s with password %s created successfully\r\n",account_name.c_str(),password.c_str()); + PSendSysMessage(LANG_ACCOUNT_CREATED,account_name.c_str()); break; case AOR_NAME_TOO_LONG: - zprintf("Username %s is too long\r\n", account_name.c_str()); - break; + SendSysMessage(LANG_ACCOUNT_TOO_LONG); + SetSentErrorMessage(true); + return false; case AOR_NAME_ALREDY_EXIST: - zprintf("User %s already exists\r\n",account_name.c_str()); - break; + SendSysMessage(LANG_ACCOUNT_ALREADY_EXIST); + SetSentErrorMessage(true); + return false; case AOR_DB_INTERNAL_ERROR: - zprintf("User %s with password %s NOT created (probably sql file format was updated)\r\n",account_name.c_str(),password.c_str()); - break; + PSendSysMessage(LANG_ACCOUNT_NOT_CREATED_SQL_ERROR,account_name.c_str()); + SetSentErrorMessage(true); + return false; default: - zprintf("User %s with password %s NOT created (unknown error)\r\n",account_name.c_str(),password.c_str()); - break; - } -} - -/// Command parser and dispatcher -void ParseCommand( pPrintf zprintf, char* input) -{ - unsigned int x; - bool bSuccess=false; - if (!input) - return; - - unsigned int l=strlen(input); - char *supposedCommand=NULL,* arguments=(char*)(""); - if(l) - { - ///- Get the command and the arguments - supposedCommand = strtok(input," "); - if (supposedCommand) - { - if (l>strlen(supposedCommand)) - arguments=&input[strlen(supposedCommand)+1]; - - ///- Circle through the command table and, if found, put the command in the queue - for ( x=0;x"); -} - -/// Kick a character out of the realm -void CliKick(char*command,pPrintf zprintf) -{ - char *kickName = strtok(command, " "); - - if (!kickName) - { - zprintf("Syntax is: kick $charactername\r\n"); - return; + PSendSysMessage(LANG_ACCOUNT_NOT_CREATED,account_name.c_str()); + SetSentErrorMessage(true); + return false; } - std::string name; - if(!consoleToUtf8(kickName,name)) // convert from console encoding to utf8 - return; - - if(!normalizePlayerName(name)) - return; - - sWorld.KickPlayer(name); -} - -/// Teleport a character to location -void CliTele(char*command,pPrintf zprintf) -{ - char *charName = strtok(command, " "); - char *locName = strtok(NULL, " "); - - if (!charName || !locName) - { - zprintf("Syntax is: tele $charactername $location\r\n"); - return; - } - - std::string name = charName; - if(!consoleToUtf8(charName,name)) // convert from console encoding to utf8 - return; - - if(!normalizePlayerName(name)) - return; - - std::string location; - if(!consoleToUtf8(locName,location)) // convert from console encoding to utf8 - return; - - WorldDatabase.escape_string(location); - QueryResult *result = WorldDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map FROM game_tele WHERE name = '%s'",location.c_str()); - if (!result) - { - zprintf(objmgr.GetMangosStringForDBCLocale(LANG_COMMAND_TELE_NOTFOUND),"\r\n"); - return; - } - - Field *fields = result->Fetch(); - float x = fields[0].GetFloat(); - float y = fields[1].GetFloat(); - float z = fields[2].GetFloat(); - float ort = fields[3].GetFloat(); - int mapid = fields[4].GetUInt16(); - delete result; - - if(!MapManager::IsValidMapCoord(mapid,x,y,z,ort)) - { - zprintf(objmgr.GetMangosStringForDBCLocale(LANG_INVALID_TARGET_COORD),"\r\n",x,y,mapid); - return; - } - - Player *chr = objmgr.GetPlayer(name.c_str()); - if (chr) - { - - if(chr->IsBeingTeleported()==true) - { - zprintf(objmgr.GetMangosStringForDBCLocale(LANG_IS_TELEPORTED),"\r\n",chr->GetName()); - return; - } - - if(chr->isInFlight()) - { - zprintf(objmgr.GetMangosStringForDBCLocale(LANG_CHAR_IN_FLIGHT),"\r\n",chr->GetName()); - return; - } - - zprintf(objmgr.GetMangosStringForDBCLocale(LANG_TELEPORTING_TO),"\r\n",chr->GetName(),"", location.c_str()); - - chr->SaveRecallPosition(); - - chr->TeleportTo(mapid,x,y,z,chr->GetOrientation()); - } - else if (uint64 guid = objmgr.GetPlayerGUIDByName(name.c_str())) - { - zprintf(objmgr.GetMangosStringForDBCLocale(LANG_TELEPORTING_TO),"\r\n",name.c_str(), objmgr.GetMangosStringForDBCLocale(LANG_OFFLINE), location.c_str()); - Player::SavePositionInDB(mapid,x,y,z,ort,MapManager::Instance().GetZoneId(mapid,x,y),guid); - } - else - zprintf(objmgr.GetMangosStringForDBCLocale(LANG_NO_PLAYER),"\r\n",name.c_str()); -} - -/// Display/Define the 'Message of the day' for the realm -void CliMotd(char*command,pPrintf zprintf) -{ - - if (strlen(command) == 0) - { - zprintf("Current Message of the day: \r\n%s\r\n", sWorld.GetMotd()); - return; - } - else - { - std::string commandUtf8; - if(!consoleToUtf8(command,commandUtf8)) // convert from console encoding to utf8 - return; - - sWorld.SetMotd(commandUtf8); - zprintf("Message of the day changed to:\r\n%s\r\n", commandUtf8.c_str()); - } -} - -/// Comment me -/// \todo What is CorpsesErase for? -void CliCorpses(char*,pPrintf) -{ - CorpsesErase(); + return true; } /// Set the level of logging -void CliSetLogLevel(char*command,pPrintf zprintf) +bool ChatHandler::HandleServerSetLogLevelCommand(const char *args) { - char *NewLevel = strtok(command, " "); + if(!*args) + return false; + + char *NewLevel = strtok((char*)args, " "); if (!NewLevel) - { - zprintf("Syntax is: setloglevel $loglevel\r\n"); - return; - } + return false; + sLog.SetLogLevel(NewLevel); -} - -/// Display the server uptime -void CliUpTime(char*,pPrintf zprintf) -{ - uint32 uptime = sWorld.GetUptime(); - std::string suptime = secsToTimeString(uptime,true,(uptime > 86400)); - zprintf("Server has been up for: %s\r\n", suptime.c_str()); -} - -/// Set/Unset the expansion level for an account -void CliSetAddon(char *command,pPrintf zprintf) -{ - ///- Get the command line arguments - char *szAcc = strtok(command," "); - char *szExp = strtok(NULL," "); - - if(!szAcc||!szExp) - { - zprintf("Syntax is: setbc $account $number (0 - normal, 1 - tbc, 2 - wotlk)>\r\n"); - return; - } - - int lev=atoi(szExp); //get int anyway (0 if error) - - if(lev < 0) - { - zprintf("Syntax is: setbc $account $number (0 - normal, 1 - tbc, 2 - wotlk)>\r\n"); - return; - } - - ///- Escape the account name to allow quotes in names - std::string safe_account_name; - if(!consoleToUtf8(szAcc,safe_account_name)) // convert from console encoding to utf8 - return; - - ///- Convert Account name to Upper Format - AccountMgr::normilizeString(safe_account_name); - - ///- Escape the account name to allow quotes in names - loginDatabase.escape_string(safe_account_name); - - // No SQL injection (account name is escaped) - QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE username = '%s'",safe_account_name.c_str()); - - if (result) - { - // No SQL injection (account name is escaped) - loginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE username = '%s'",lev,safe_account_name.c_str()); - zprintf("We set %s to expansion allowed %d\r\n",safe_account_name.c_str(),lev); - - delete result; - } - else - { - zprintf("No account %s found\r\n",safe_account_name.c_str()); - } -} - -/// Save all players -void CliSave(char*,pPrintf zprintf) -{ - ///- Save players - ObjectAccessor::Instance().SaveAllPlayers(); - zprintf( objmgr.GetMangosStringForDBCLocale(LANG_PLAYERS_SAVED) ); - - ///- Send a message - sWorld.SendWorldText(LANG_PLAYERS_SAVED); -} - -/// Send a message to a player in game -void CliSend(char *playerN,pPrintf zprintf) -{ - ///- Get the command line arguments - char* name_str = strtok((char*)playerN, " "); - char* msg_str = strtok(NULL, ""); - - if(!name_str || !msg_str) - { - zprintf("Syntax: send $player $message (Player name is case sensitive)\r\n"); - return; - } - - std::string name; - if(!consoleToUtf8(name_str,name)) // convert from console encoding to utf8 - return; - - std::string msg; - if(!consoleToUtf8(msg_str,msg)) // convert from console encoding to utf8 - return; - - if(!normalizePlayerName(name)) - { - zprintf("Syntax: send $player $message (Player name is case sensitive)\r\n"); - return; - } - - ///- Find the player and check that he is not logging out. - Player *rPlayer = objmgr.GetPlayer(name.c_str()); - if(!rPlayer) - { - zprintf("Player %s not found!\r\n", name.c_str()); - return; - } - - if (rPlayer->GetSession()->isLogingOut()) - { - zprintf("Cannot send message while player %s is logging out!\r\n",name.c_str()); - return; - } - - ///- Send the message - //Use SendAreaTriggerMessage for fastest delivery. - rPlayer->GetSession()->SendAreaTriggerMessage("%s", msg.c_str()); - rPlayer->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r"); - - //Confirmation message - zprintf("Message '%s' sent to %s\r\n",msg.c_str(), name.c_str()); -} - -void CliPLimit(char *args,pPrintf zprintf) -{ - if(*args) - { - char* param = strtok((char*)args, " "); - if(!param || !*param) - return; - - int l = strlen(param); - - if( strncmp(param,"player",l) == 0 ) - sWorld.SetPlayerLimit(-SEC_PLAYER); - else if(strncmp(param,"moderator",l) == 0 ) - sWorld.SetPlayerLimit(-SEC_MODERATOR); - else if(strncmp(param,"gamemaster",l) == 0 ) - sWorld.SetPlayerLimit(-SEC_GAMEMASTER); - else if(strncmp(param,"administrator",l) == 0 ) - sWorld.SetPlayerLimit(-SEC_ADMINISTRATOR); - else if(strncmp(param,"reset",l) == 0 ) - sWorld.SetPlayerLimit(sConfig.GetIntDefault("PlayerLimit", DEFAULT_PLAYER_LIMIT)); - else - { - int val = atoi(param); - if(val < -SEC_ADMINISTRATOR) val = -SEC_ADMINISTRATOR; - - sWorld.SetPlayerLimit(val); - } - - // kick all low security level players - if(sWorld.GetPlayerAmountLimit() > SEC_PLAYER) - sWorld.KickAllLess(sWorld.GetPlayerSecurityLimit()); - } - - uint32 pLimit = sWorld.GetPlayerAmountLimit(); - AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit(); - char const* secName = ""; - switch(allowedAccountType) - { - case SEC_PLAYER: secName = "Player"; break; - case SEC_MODERATOR: secName = "Moderator"; break; - case SEC_GAMEMASTER: secName = "Gamemaster"; break; - case SEC_ADMINISTRATOR: secName = "Administrator"; break; - default: secName = ""; break; - } - - zprintf("Player limits: amount %u, min. security level %s.\r\n",pLimit,secName); + return true; } /// @} @@ -1219,13 +298,9 @@ void CliRunnable::run() ///- Display the list of available CLI functions then beep sLog.outString(); - /// \todo Shoudn't we use here also the sLog singleton? - CliHelp(NULL,&UTF8ZPRINTF); if(sConfig.GetBoolDefault("BeepAtStart", true)) - { printf("\a"); // \a = Alert - } // print this here the first time // later it will be printed after command queue updates @@ -1242,17 +317,31 @@ void CliRunnable::run() if (World::m_stopEvent) break; #endif - char *command = fgets(commandbuf,sizeof(commandbuf),stdin); - if (command != NULL) + char *command_str = fgets(commandbuf,sizeof(commandbuf),stdin); + if (command_str != NULL) { - for(int x=0;command[x];x++) - if(command[x]=='\r'||command[x]=='\n') + for(int x=0;command_str[x];x++) + if(command_str[x]=='\r'||command_str[x]=='\n') { - command[x]=0; + command_str[x]=0; break; } - //// \todo Shoudn't we use here also the sLog singleton? - ParseCommand(&UTF8ZPRINTF,command); + + + if(!*command_str) + { + printf("mangos>"); + continue; + } + + std::string command; + if(!consoleToUtf8(command_str,command)) // convert from console encoding to utf8 + { + printf("mangos>"); + continue; + } + + sWorld.QueueCliCommand(&utf8print,command.c_str()); } else if (feof(stdin)) { diff --git a/src/mangosd/RASocket.cpp b/src/mangosd/RASocket.cpp index b881b9a2a..71daf1745 100644 --- a/src/mangosd/RASocket.cpp +++ b/src/mangosd/RASocket.cpp @@ -42,7 +42,7 @@ unsigned int iUsers=0; ///< Number of activ typedef int(* pPrintf)(const char*,...); -void ParseCommand(pPrintf zprintf, char*command); +void ParseCommand(CliCommandHolder::Print*, char*command); /// RASocket constructor RASocket::RASocket(ISocketHandler &h): TcpSocket(h) @@ -220,7 +220,7 @@ void RASocket::OnRead() if(strlen(buff)) { sLog.outRALog("Got '%s' cmd.\n",buff); - ParseCommand(&RASocket::zprintf , buff); + sWorld.QueueCliCommand(&RASocket::zprint , buff); } else Sendf("mangos>"); @@ -232,20 +232,23 @@ void RASocket::OnRead() } /// Output function -int RASocket::zprintf( const char * szText, ... ) +void RASocket::zprint( const char * szText ) { - if( !szText ) return 0; - va_list ap; - va_start(ap, szText); - /// \todo Remove buffer length here. Can be >1024 (e.g. list of users) - char *megabuffer=new char[1024]; - unsigned int sz=vsnprintf(megabuffer,1024,szText,ap); - #ifdef RA_CRYPT - Encrypt(megabuffer,sz); - #endif + if( !szText ) + return; + #ifdef RA_CRYPT + + char *megabuffer=strdup(szText); + unsigned int sz=strlen(megabuffer); + Encrypt(megabuffer,sz); send(r,megabuffer,sz,0); delete [] megabuffer; - va_end(ap); - return 0; + + #else + + unsigned int sz=strlen(szText); + send(r,szText,sz,0); + + #endif } diff --git a/src/mangosd/RASocket.h b/src/mangosd/RASocket.h index 83dcfcdaa..fe539af65 100644 --- a/src/mangosd/RASocket.h +++ b/src/mangosd/RASocket.h @@ -59,7 +59,7 @@ class RASocket: public TcpSocket OK, //both login and pass were given, and they are correct and user have enough priv. }stage; - static int zprintf( const char * szText, ... ); + static void zprint( const char * szText ); }; #endif /// @} diff --git a/src/shared/Common.h b/src/shared/Common.h index b2b11181f..41faa2098 100644 --- a/src/shared/Common.h +++ b/src/shared/Common.h @@ -165,7 +165,8 @@ enum AccountTypes SEC_PLAYER = 0, SEC_MODERATOR = 1, SEC_GAMEMASTER = 2, - SEC_ADMINISTRATOR = 3 + SEC_ADMINISTRATOR = 3, + SEC_CONSOLE = 4 // must be always last in list, accounts must have less security level always also }; enum LocaleConstant