root/trunk/src/game/Chat.cpp @ 9

Revision 9, 59.3 kB (checked in by yumileroy, 17 years ago)

[svn] -enabled instantiated battlegrounds
-enabled arena matches
-rewritten battleground queuing to support joining as group
-removed queue announcements

Original author: w12x
Date: 2008-10-05 08:48:32-05:00

Line 
1/*
2 * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 */
18
19#include "Common.h"
20#include "Language.h"
21#include "Database/DatabaseEnv.h"
22#include "WorldPacket.h"
23#include "WorldSession.h"
24#include "Opcodes.h"
25#include "Log.h"
26#include "World.h"
27#include "ObjectMgr.h"
28#include "Player.h"
29#include "UpdateMask.h"
30#include "Chat.h"
31#include "MapManager.h"
32#include "GridNotifiersImpl.h"
33#include "CellImpl.h"
34
35bool ChatHandler::load_command_table = true;
36
37LanguageDesc lang_description[LANGUAGES_COUNT] =
38{
39    { LANG_ADDON,           0, 0                       },
40    { LANG_UNIVERSAL,       0, 0                       },
41    { LANG_ORCISH,        669, SKILL_LANG_ORCISH       },
42    { LANG_DARNASSIAN,    671, SKILL_LANG_DARNASSIAN   },
43    { LANG_TAURAHE,       670, SKILL_LANG_TAURAHE      },
44    { LANG_DWARVISH,      672, SKILL_LANG_DWARVEN      },
45    { LANG_COMMON,        668, SKILL_LANG_COMMON       },
46    { LANG_DEMONIC,       815, SKILL_LANG_DEMON_TONGUE },
47    { LANG_TITAN,         816, SKILL_LANG_TITAN        },
48    { LANG_THALASSIAN,    813, SKILL_LANG_THALASSIAN   },
49    { LANG_DRACONIC,      814, SKILL_LANG_DRACONIC     },
50    { LANG_KALIMAG,       817, SKILL_LANG_OLD_TONGUE   },
51    { LANG_GNOMISH,      7340, SKILL_LANG_GNOMISH      },
52    { LANG_TROLL,        7341, SKILL_LANG_TROLL        },
53    { LANG_GUTTERSPEAK, 17737, SKILL_LANG_GUTTERSPEAK  },
54    { LANG_DRAENEI,     29932, SKILL_LANG_DRAENEI      },
55    { LANG_ZOMBIE,          0, 0                       },
56    { LANG_GNOMISH_BINARY,  0, 0                       },
57    { LANG_GOBLIN_BINARY,   0, 0                       }
58};
59
60LanguageDesc const* GetLanguageDescByID(uint32 lang)
61{
62    for(int i = 0; i < LANGUAGES_COUNT; ++i)
63    {
64        if(uint32(lang_description[i].lang_id) == lang)
65            return &lang_description[i];
66    }
67
68    return NULL;
69}
70
71LanguageDesc const* GetLanguageDescBySpell(uint32 spell_id)
72{
73    for(int i = 0; i < LANGUAGES_COUNT; ++i)
74    {
75        if(lang_description[i].spell_id == spell_id)
76            return &lang_description[i];
77    }
78
79    return NULL;
80}
81
82LanguageDesc const* GetLanguageDescBySkill(uint32 skill_id)
83{
84    for(int i = 0; i < LANGUAGES_COUNT; ++i)
85    {
86        if(lang_description[i].skill_id == skill_id)
87            return &lang_description[i];
88    }
89
90    return NULL;
91}
92
93ChatCommand * ChatHandler::getCommandTable()
94{
95    static ChatCommand serverCommandTable[] =
96    {
97        { "idlerestart",    SEC_ADMINISTRATOR,  &ChatHandler::HandleIdleRestartCommand,         "", NULL },
98        { "idleshutdown",   SEC_ADMINISTRATOR,  &ChatHandler::HandleIdleShutDownCommand,        "", NULL },
99        { "info",           SEC_PLAYER,         &ChatHandler::HandleInfoCommand,                "", NULL },
100        { "restart",        SEC_ADMINISTRATOR,  &ChatHandler::HandleRestartCommand,             "", NULL },
101        { "shutdown",       SEC_ADMINISTRATOR,  &ChatHandler::HandleShutDownCommand,            "", NULL },
102        { NULL,             0,                  NULL,                                           "", NULL }
103    };
104
105    static ChatCommand modifyCommandTable[] =
106    {
107        { "hp",             SEC_MODERATOR,      &ChatHandler::HandleModifyHPCommand,            "", NULL },
108        { "mana",           SEC_MODERATOR,      &ChatHandler::HandleModifyManaCommand,          "", NULL },
109        { "rage",           SEC_MODERATOR,      &ChatHandler::HandleModifyRageCommand,          "", NULL },
110        { "energy",         SEC_MODERATOR,      &ChatHandler::HandleModifyEnergyCommand,        "", NULL },
111        { "money",          SEC_MODERATOR,      &ChatHandler::HandleModifyMoneyCommand,         "", NULL },
112        { "speed",          SEC_MODERATOR,      &ChatHandler::HandleModifySpeedCommand,         "", NULL },
113        { "swim",           SEC_MODERATOR,      &ChatHandler::HandleModifySwimCommand,          "", NULL },
114        { "scale",          SEC_MODERATOR,      &ChatHandler::HandleModifyScaleCommand,         "", NULL },
115        { "bit",            SEC_MODERATOR,      &ChatHandler::HandleModifyBitCommand,           "", NULL },
116        { "bwalk",          SEC_MODERATOR,      &ChatHandler::HandleModifyBWalkCommand,         "", NULL },
117        { "fly",            SEC_MODERATOR,      &ChatHandler::HandleModifyFlyCommand,           "", NULL },
118        { "aspeed",         SEC_MODERATOR,      &ChatHandler::HandleModifyASpeedCommand,        "", NULL },
119        { "faction",        SEC_MODERATOR,      &ChatHandler::HandleModifyFactionCommand,       "", NULL },
120        { "spell",          SEC_MODERATOR,      &ChatHandler::HandleModifySpellCommand,         "", NULL },
121        { "tp",             SEC_MODERATOR,      &ChatHandler::HandleModifyTalentCommand,        "", NULL },
122        { "titles",         SEC_MODERATOR,      &ChatHandler::HandleModifyKnownTitlesCommand,   "", NULL },
123        { "mount",          SEC_MODERATOR,      &ChatHandler::HandleModifyMountCommand,         "", NULL },
124        { "honor",          SEC_MODERATOR,      &ChatHandler::HandleModifyHonorCommand,         "", NULL },
125        { "rep",            SEC_MODERATOR,      &ChatHandler::HandleModifyRepCommand,           "", NULL },
126        { "arena",          SEC_MODERATOR,      &ChatHandler::HandleModifyArenaCommand,         "", NULL },
127        { "drunk",          SEC_MODERATOR,      &ChatHandler::HandleDrunkCommand,               "", NULL },
128        { "standstate",     SEC_GAMEMASTER,     &ChatHandler::HandleStandStateCommand,          "", NULL },
129        { "morph",          SEC_GAMEMASTER,     &ChatHandler::HandleMorphCommand,               "", NULL },
130        { NULL,             0,                  NULL,                                           "", NULL }
131    };
132
133    static ChatCommand wpCommandTable[] =
134    {
135        { "show",           SEC_GAMEMASTER,     &ChatHandler::HandleWpShowCommand,              "", NULL },
136        { "add",            SEC_GAMEMASTER,     &ChatHandler::HandleWpAddCommand,               "", NULL },
137        { "modify",         SEC_GAMEMASTER,     &ChatHandler::HandleWpModifyCommand,            "", NULL },
138        { "export",         SEC_ADMINISTRATOR,  &ChatHandler::HandleWpExportCommand,            "", NULL },
139        { "import",         SEC_ADMINISTRATOR,  &ChatHandler::HandleWpImportCommand,            "", NULL },
140        { NULL,             0,                  NULL,                                           "", NULL }
141    };
142
143    static ChatCommand debugCommandTable[] =
144    {
145        { "inarc",          SEC_ADMINISTRATOR,  &ChatHandler::HandleDebugInArcCommand,          "", NULL },
146        { "spellfail",      SEC_ADMINISTRATOR,  &ChatHandler::HandleDebugSpellFailCommand,      "", NULL },
147        { "setpoi",         SEC_ADMINISTRATOR,  &ChatHandler::HandleSetPoiCommand,              "", NULL },
148        { "qpartymsg",      SEC_ADMINISTRATOR,  &ChatHandler::HandleSendQuestPartyMsgCommand,   "", NULL },
149        { "qinvalidmsg",    SEC_ADMINISTRATOR,  &ChatHandler::HandleSendQuestInvalidMsgCommand, "", NULL },
150        { "equiperr",       SEC_ADMINISTRATOR,  &ChatHandler::HandleEquipErrorCommand,          "", NULL },
151        { "sellerr",        SEC_ADMINISTRATOR,  &ChatHandler::HandleSellErrorCommand,           "", NULL },
152        { "buyerr",         SEC_ADMINISTRATOR,  &ChatHandler::HandleBuyErrorCommand,            "", NULL },
153        { "sendopcode",     SEC_ADMINISTRATOR,  &ChatHandler::HandleSendOpcodeCommand,          "", NULL },
154        { "uws",            SEC_ADMINISTRATOR,  &ChatHandler::HandleUpdateWorldStateCommand,    "", NULL },
155        { "ps",             SEC_ADMINISTRATOR,  &ChatHandler::HandlePlaySound2Command,          "", NULL },
156        { "scn",            SEC_ADMINISTRATOR,  &ChatHandler::HandleSendChannelNotifyCommand,   "", NULL },
157        { "scm",            SEC_ADMINISTRATOR,  &ChatHandler::HandleSendChatMsgCommand,         "", NULL },
158        { "getitemstate",   SEC_ADMINISTRATOR,  &ChatHandler::HandleGetItemState,               "", NULL },
159        { "playsound",      SEC_MODERATOR,      &ChatHandler::HandlePlaySoundCommand,           "", NULL },
160        { "update",         SEC_ADMINISTRATOR,  &ChatHandler::HandleUpdate,                     "", NULL },
161        { "setvalue",       SEC_ADMINISTRATOR,  &ChatHandler::HandleSetValue,                   "", NULL },
162        { "getvalue",       SEC_ADMINISTRATOR,  &ChatHandler::HandleGetValue,                   "", NULL },
163        { "Mod32Value",     SEC_ADMINISTRATOR,  &ChatHandler::HandleMod32Value,                 "", NULL },
164        { "anim",           SEC_GAMEMASTER,     &ChatHandler::HandleAnimCommand,                "", NULL },
165        { "lootrecipient",  SEC_GAMEMASTER,     &ChatHandler::HandleGetLootRecipient,           "", NULL },
166        { "arena",          SEC_ADMINISTRATOR,  &ChatHandler::HandleDebugArenaCommand,          "", NULL },
167        { NULL,             0,                  NULL,                                           "", NULL }
168    };
169
170    static ChatCommand eventCommandTable[] =
171    {
172        { "activelist",     SEC_GAMEMASTER,     &ChatHandler::HandleEventActiveListCommand,     "", NULL },
173        { "start",          SEC_GAMEMASTER,     &ChatHandler::HandleEventStartCommand,          "", NULL },
174        { "stop",           SEC_GAMEMASTER,     &ChatHandler::HandleEventStopCommand,           "", NULL },
175        { "",               SEC_GAMEMASTER,     &ChatHandler::HandleEventInfoCommand,           "", NULL },
176        { NULL,             0,                  NULL,                                           "", NULL }
177    };
178
179    static ChatCommand learnCommandTable[] =
180    {
181        { "all",            SEC_ADMINISTRATOR,  &ChatHandler::HandleLearnAllCommand,            "", NULL },
182        { "all_gm",         SEC_GAMEMASTER,     &ChatHandler::HandleLearnAllGMCommand,          "", NULL },
183        { "all_crafts",     SEC_GAMEMASTER,     &ChatHandler::HandleLearnAllCraftsCommand,      "", NULL },
184        { "all_default",    SEC_MODERATOR,      &ChatHandler::HandleLearnAllDefaultCommand,     "", NULL },
185        { "all_lang",       SEC_MODERATOR,      &ChatHandler::HandleLearnAllLangCommand,        "", NULL },
186        { "all_myclass",    SEC_ADMINISTRATOR,  &ChatHandler::HandleLearnAllMyClassCommand,     "", NULL },
187        { "all_myspells",   SEC_ADMINISTRATOR,  &ChatHandler::HandleLearnAllMySpellsCommand,    "", NULL },
188        { "all_mytalents",  SEC_ADMINISTRATOR,  &ChatHandler::HandleLearnAllMyTalentsCommand,   "", NULL },
189        { "all_recipes",    SEC_GAMEMASTER,     &ChatHandler::HandleLearnAllRecipesCommand,     "", NULL },
190        { "",               SEC_ADMINISTRATOR,  &ChatHandler::HandleLearnCommand,               "", NULL },
191        { NULL,             0,                  NULL,                                           "", NULL }
192    };
193
194    static ChatCommand reloadCommandTable[] =
195    {
196        { "all",            SEC_ADMINISTRATOR,  &ChatHandler::HandleReloadAllCommand,           "", NULL },
197        { "all_loot",       SEC_ADMINISTRATOR,  &ChatHandler::HandleReloadAllLootCommand,       "", NULL },
198        { "all_npc",        SEC_ADMINISTRATOR,  &ChatHandler::HandleReloadAllNpcCommand,        "", NULL },
199        { "all_quest",      SEC_ADMINISTRATOR,  &ChatHandler::HandleReloadAllQuestCommand,      "", NULL },
200        { "all_scripts",    SEC_ADMINISTRATOR,  &ChatHandler::HandleReloadAllScriptsCommand,    "", NULL },
201        { "all_spell",      SEC_ADMINISTRATOR,  &ChatHandler::HandleReloadAllSpellCommand,      "", NULL },
202        { "all_item",       SEC_ADMINISTRATOR,  &ChatHandler::HandleReloadAllItemCommand,       "", NULL },
203
204        { "config",         SEC_ADMINISTRATOR,  &ChatHandler::HandleReloadConfigCommand,        "", NULL },
205
206        { "areatrigger_tavern",          SEC_ADMINISTRATOR, &ChatHandler::HandleReloadAreaTriggerTavernCommand,       "", NULL },
207        { "areatrigger_teleport",        SEC_ADMINISTRATOR, &ChatHandler::HandleReloadAreaTriggerTeleportCommand,     "", NULL },
208        { "areatrigger_involvedrelation",SEC_ADMINISTRATOR, &ChatHandler::HandleReloadQuestAreaTriggersCommand,       "", NULL },
209        { "event_scripts",               SEC_ADMINISTRATOR, &ChatHandler::HandleReloadEventScriptsCommand,            "", NULL },
210        { "command",                     SEC_ADMINISTRATOR, &ChatHandler::HandleReloadCommandCommand,                 "", NULL },
211        { "creature_involvedrelation",   SEC_ADMINISTRATOR, &ChatHandler::HandleReloadCreatureQuestInvRelationsCommand,"",NULL },
212        { "creature_loot_template",      SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesCreatureCommand,   "", NULL },
213        { "creature_questrelation",      SEC_ADMINISTRATOR, &ChatHandler::HandleReloadCreatureQuestRelationsCommand,  "", NULL },
214        { "disenchant_loot_template",    SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesDisenchantCommand, "", NULL },
215        { "fishing_loot_template",       SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesFishingCommand,    "", NULL },
216        { "game_graveyard_zone",         SEC_ADMINISTRATOR, &ChatHandler::HandleReloadGameGraveyardZoneCommand,       "", NULL },
217        { "game_tele",                   SEC_ADMINISTRATOR, &ChatHandler::HandleReloadGameTeleCommand,                "", NULL },
218        { "gameobject_involvedrelation", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadGOQuestInvRelationsCommand,     "", NULL },
219        { "gameobject_loot_template",    SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesGameobjectCommand, "", NULL },
220        { "gameobject_questrelation",    SEC_ADMINISTRATOR, &ChatHandler::HandleReloadGOQuestRelationsCommand,        "", NULL },
221        { "gameobject_scripts",          SEC_ADMINISTRATOR, &ChatHandler::HandleReloadGameObjectScriptsCommand,       "", NULL },
222        { "item_enchantment_template",   SEC_ADMINISTRATOR, &ChatHandler::HandleReloadItemEnchantementsCommand,       "", NULL },
223        { "item_loot_template",          SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesItemCommand,       "", NULL },
224        { "mangos_string",               SEC_ADMINISTRATOR, &ChatHandler::HandleReloadMangosStringCommand,            "", NULL },
225        { "npc_gossip",                  SEC_ADMINISTRATOR, &ChatHandler::HandleReloadNpcGossipCommand,               "", NULL },
226        { "npc_trainer",                 SEC_ADMINISTRATOR, &ChatHandler::HandleReloadNpcTrainerCommand,              "", NULL },
227        { "npc_vendor",                  SEC_ADMINISTRATOR, &ChatHandler::HandleReloadNpcVendorCommand,               "", NULL },
228        { "page_text",                   SEC_ADMINISTRATOR, &ChatHandler::HandleReloadPageTextsCommand,               "", NULL },
229        { "pickpocketing_loot_template", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesPickpocketingCommand,"",NULL},
230        { "prospecting_loot_template",   SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesProspectingCommand,"", NULL },
231        { "quest_mail_loot_template",    SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesQuestMailCommand,  "", NULL },
232        { "quest_end_scripts",           SEC_ADMINISTRATOR, &ChatHandler::HandleReloadQuestEndScriptsCommand,         "", NULL },
233        { "quest_start_scripts",         SEC_ADMINISTRATOR, &ChatHandler::HandleReloadQuestStartScriptsCommand,       "", NULL },
234        { "quest_template",              SEC_ADMINISTRATOR, &ChatHandler::HandleReloadQuestTemplateCommand,           "", NULL },
235        { "reference_loot_template",     SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesReferenceCommand,  "", NULL },
236        { "reserved_name",               SEC_ADMINISTRATOR, &ChatHandler::HandleReloadReservedNameCommand,            "", NULL },
237        { "skill_discovery_template",    SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSkillDiscoveryTemplateCommand,  "", NULL },
238        { "skill_extra_item_template",   SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSkillExtraItemTemplateCommand,  "", NULL },
239        { "skill_fishing_base_level",    SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSkillFishingBaseLevelCommand,   "", NULL },
240        { "skinning_loot_template",      SEC_ADMINISTRATOR, &ChatHandler::HandleReloadLootTemplatesSkinningCommand,   "", NULL },
241        { "spell_affect",                SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellAffectCommand,             "", NULL },
242        { "spell_chain",                 SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellChainCommand,              "", NULL },
243        { "spell_elixir",                SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellElixirCommand,             "", NULL },
244        { "spell_learn_spell",           SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellLearnSpellCommand,         "", NULL },
245        { "spell_pet_auras",             SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellPetAurasCommand,           "", NULL },
246        { "spell_proc_event",            SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellProcEventCommand,          "", NULL },
247        { "spell_script_target",         SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellScriptTargetCommand,       "", NULL },
248        { "spell_scripts",               SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellScriptsCommand,            "", NULL },
249        { "spell_target_position",       SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellTargetPositionCommand,     "", NULL },
250        { "spell_threats",               SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellThreatsCommand,            "", NULL },
251        { "",                            SEC_ADMINISTRATOR, &ChatHandler::HandleReloadCommand,                        "", NULL },
252        { NULL,                          0,                 NULL,                                                     "", NULL }
253    };
254
255    static ChatCommand honorCommandTable[] =
256    {
257        { "add",            SEC_GAMEMASTER,     &ChatHandler::HandleAddHonorCommand,            "", NULL },
258        { "addkill",        SEC_GAMEMASTER,     &ChatHandler::HandleHonorAddKillCommand,        "", NULL },
259        { "update",         SEC_GAMEMASTER,     &ChatHandler::HandleUpdateHonorFieldsCommand,   "", NULL },
260        { NULL,             0,                  NULL,                                           "", NULL }
261    };
262
263    static ChatCommand guildCommandTable[] =
264    {
265        { "create",         SEC_GAMEMASTER,     &ChatHandler::HandleGuildCreateCommand,         "", NULL },
266        { "delete",         SEC_GAMEMASTER,     &ChatHandler::HandleGuildDeleteCommand,         "", NULL },
267        { "invite",         SEC_GAMEMASTER,     &ChatHandler::HandleGuildInviteCommand,         "", NULL },
268        { "uninvite",       SEC_GAMEMASTER,     &ChatHandler::HandleGuildUninviteCommand,       "", NULL },
269        { "rank",           SEC_GAMEMASTER,     &ChatHandler::HandleGuildRankCommand,           "", NULL },
270        { NULL,             0,                  NULL,                                           "", NULL }
271    };
272
273    static ChatCommand lookupPlayerCommandTable[] =
274    {
275        { "ip",            SEC_GAMEMASTER,     &ChatHandler::HandleLookupPlayerIpCommand,       "", NULL },
276        { "account",       SEC_GAMEMASTER,     &ChatHandler::HandleLookupPlayerAccountCommand,  "", NULL },
277        { "email",         SEC_GAMEMASTER,     &ChatHandler::HandleLookupPlayerEmailCommand,    "", NULL },
278        { NULL,            0,                  NULL,                                            "", NULL }
279    };
280
281    static ChatCommand lookupCommandTable[] =
282    {
283        { "area",           SEC_MODERATOR,      &ChatHandler::HandleLookupAreaCommand,          "", NULL },
284        { "creature",       SEC_ADMINISTRATOR,  &ChatHandler::HandleLookupCreatureCommand,      "", NULL },
285        { "event",          SEC_GAMEMASTER,     &ChatHandler::HandleLookupEventCommand,         "", NULL },
286        { "faction",        SEC_ADMINISTRATOR,  &ChatHandler::HandleLookupFactionCommand,       "", NULL },
287        { "item",           SEC_ADMINISTRATOR,  &ChatHandler::HandleLookupItemCommand,          "", NULL },
288        { "itemset",        SEC_ADMINISTRATOR,  &ChatHandler::HandleLookupItemSetCommand,       "", NULL },
289        { "object",         SEC_ADMINISTRATOR,  &ChatHandler::HandleLookupObjectCommand,        "", NULL },
290        { "quest",          SEC_ADMINISTRATOR,  &ChatHandler::HandleLookupQuestCommand,         "", NULL },
291        { "player",         SEC_GAMEMASTER,     NULL,                                           "", lookupPlayerCommandTable },
292        { "skill",          SEC_ADMINISTRATOR,  &ChatHandler::HandleLookupSkillCommand,         "", NULL },
293        { "spell",          SEC_ADMINISTRATOR,  &ChatHandler::HandleLookupSpellCommand,         "", NULL },
294        { "tele",           SEC_MODERATOR,      &ChatHandler::HandleLookupTeleCommand,          "", NULL },
295        { NULL,             0,                  NULL,                                           "", NULL }
296    };
297
298    static ChatCommand resetCommandTable[] =
299    {
300        { "honor",          SEC_ADMINISTRATOR,  &ChatHandler::HandleResetHonorCommand,          "", NULL },
301        { "level",          SEC_ADMINISTRATOR,  &ChatHandler::HandleResetLevelCommand,          "", NULL },
302        { "spells",         SEC_ADMINISTRATOR,  &ChatHandler::HandleResetSpellsCommand,         "", NULL },
303        { "stats",          SEC_ADMINISTRATOR,  &ChatHandler::HandleResetStatsCommand,          "", NULL },
304        { "talents",        SEC_ADMINISTRATOR,  &ChatHandler::HandleResetTalentsCommand,        "", NULL },
305        { "all",            SEC_ADMINISTRATOR,  &ChatHandler::HandleResetAllCommand,            "", NULL },
306        { NULL,             0,                  NULL,                                           "", NULL }
307    };
308
309    static ChatCommand castCommandTable[] =
310    {
311        { "back",           SEC_ADMINISTRATOR,  &ChatHandler::HandleCastBackCommand,            "", NULL },
312        { "dist",           SEC_ADMINISTRATOR,  &ChatHandler::HandleCastDistCommand,            "", NULL },
313        { "self",           SEC_ADMINISTRATOR,  &ChatHandler::HandleCastSelfCommand,            "", NULL },
314        { "target",         SEC_ADMINISTRATOR,  &ChatHandler::HandleCastTargetCommand,          "", NULL },
315        { "",               SEC_ADMINISTRATOR,  &ChatHandler::HandleCastCommand,                "", NULL },
316        { NULL,             0,                  NULL,                                           "", NULL }
317    };
318
319    static ChatCommand pdumpCommandTable[] =
320    {
321        { "load",           SEC_ADMINISTRATOR,  &ChatHandler::HandleLoadPDumpCommand,           "", NULL },
322        { "write",          SEC_ADMINISTRATOR,  &ChatHandler::HandleWritePDumpCommand,          "", NULL },
323        { NULL,             0,                  NULL,                                           "", NULL }
324    };
325
326    static ChatCommand listCommandTable[] =
327    {
328        { "creature",       SEC_ADMINISTRATOR,  &ChatHandler::HandleListCreatureCommand,        "", NULL },
329        { "item",           SEC_ADMINISTRATOR,  &ChatHandler::HandleListItemCommand,            "", NULL },
330        { "object",         SEC_ADMINISTRATOR,  &ChatHandler::HandleListObjectCommand,          "", NULL },
331        { "auras",          SEC_ADMINISTRATOR,  &ChatHandler::HandleListAurasCommand,           "", NULL },
332        { NULL,             0,                  NULL,                                           "", NULL }
333    };
334
335    static ChatCommand teleCommandTable[] =
336    {
337        { "add",            SEC_ADMINISTRATOR,  &ChatHandler::HandleAddTeleCommand,             "", NULL },
338        { "del",            SEC_ADMINISTRATOR,  &ChatHandler::HandleDelTeleCommand,             "", NULL },
339        { "name",           SEC_MODERATOR,      &ChatHandler::HandleNameTeleCommand,            "", NULL },
340        { "group",          SEC_MODERATOR,      &ChatHandler::HandleGroupTeleCommand,           "", NULL },
341        { "",               SEC_MODERATOR,      &ChatHandler::HandleTeleCommand,                "", NULL },
342        { NULL,             0,                  NULL,                                           "", NULL }
343    };
344
345    static ChatCommand npcCommandTable[] =
346    {
347        { "say",            SEC_MODERATOR,      &ChatHandler::HandleSayCommand,                 "", NULL },
348        { "whisper",        SEC_MODERATOR,      &ChatHandler::HandleNpcWhisperCommand,          "", NULL },
349        { "yell",           SEC_MODERATOR,      &ChatHandler::HandleYellCommand,                "", NULL },
350        { "textemote",      SEC_MODERATOR,      &ChatHandler::HandleTextEmoteCommand,           "", NULL },
351        { "add",            SEC_GAMEMASTER,     &ChatHandler::HandleAddSpwCommand,              "", NULL },
352        { "delete",         SEC_GAMEMASTER,     &ChatHandler::HandleDelCreatureCommand,         "", NULL },
353        { "spawndist",      SEC_GAMEMASTER,     &ChatHandler::HandleSpawnDistCommand,           "", NULL },
354        { "spawntime",      SEC_GAMEMASTER,     &ChatHandler::HandleSpawnTimeCommand,           "", NULL },
355        { "factionid",      SEC_GAMEMASTER,     &ChatHandler::HandleFactionIdCommand,           "", NULL },
356        { "addmove",        SEC_GAMEMASTER,     &ChatHandler::HandleAddMoveCommand,             "", NULL },
357        { "setmovetype",    SEC_GAMEMASTER,     &ChatHandler::HandleSetMoveTypeCommand,         "", NULL },
358        { "move",           SEC_GAMEMASTER,     &ChatHandler::HandleMoveCreatureCommand,        "", NULL },
359        { "changelevel",    SEC_GAMEMASTER,     &ChatHandler::HandleChangeLevelCommand,         "", NULL },
360        { "setmodel",       SEC_GAMEMASTER,     &ChatHandler::HandleSetModelCommand,            "", NULL },
361        { "additem",        SEC_GAMEMASTER,     &ChatHandler::HandleAddVendorItemCommand,       "", NULL },
362        { "delitem",        SEC_GAMEMASTER,     &ChatHandler::HandleDelVendorItemCommand,       "", NULL },
363        { "flag",           SEC_GAMEMASTER,     &ChatHandler::HandleNPCFlagCommand,             "", NULL },
364        { "changeentry",    SEC_ADMINISTRATOR,  &ChatHandler::HandleChangeEntryCommand,         "", NULL },
365        { "info",           SEC_ADMINISTRATOR,  &ChatHandler::HandleNpcInfoCommand,             "", NULL },
366        { "playemote",      SEC_ADMINISTRATOR,  &ChatHandler::HandlePlayEmoteCommand,           "", NULL },
367
368        //{ TODO: fix or remove this commands
369        { "name",           SEC_GAMEMASTER,     &ChatHandler::HandleNameCommand,                "", NULL },
370        { "subname",        SEC_GAMEMASTER,     &ChatHandler::HandleSubNameCommand,             "", NULL },
371        { "addweapon",      SEC_ADMINISTRATOR,  &ChatHandler::HandleAddWeaponCommand,           "", NULL },
372        //}
373
374        { NULL,             0,                  NULL,                                           "", NULL }
375    };
376
377    static ChatCommand goCommandTable[] =
378    {
379        { "grid",           SEC_MODERATOR,      &ChatHandler::HandleGoGridCommand,              "", NULL },
380        { "creature",       SEC_GAMEMASTER,     &ChatHandler::HandleGoCreatureCommand,          "", NULL },
381        { "object",         SEC_GAMEMASTER,     &ChatHandler::HandleGoObjectCommand,            "", NULL },
382        { "trigger",        SEC_GAMEMASTER,     &ChatHandler::HandleGoTriggerCommand,           "", NULL },
383        { "graveyard",      SEC_GAMEMASTER,     &ChatHandler::HandleGoGraveyardCommand,         "", NULL },
384        { "zonexy",         SEC_MODERATOR,      &ChatHandler::HandleGoZoneXYCommand,            "", NULL },
385        { "xy",             SEC_MODERATOR,      &ChatHandler::HandleGoXYCommand,                "", NULL },
386        { "xyz",            SEC_MODERATOR,      &ChatHandler::HandleGoXYZCommand,               "", NULL },
387        { "",               SEC_MODERATOR,      &ChatHandler::HandleGoXYZCommand,               "", NULL },
388        { NULL,             0,                  NULL,                                           "", NULL }
389    };
390
391    static ChatCommand gobjectCommandTable[] =
392    {
393        { "add",            SEC_GAMEMASTER,     &ChatHandler::HandleGameObjectCommand,          "", NULL },
394        { "delete",         SEC_GAMEMASTER,     &ChatHandler::HandleDelObjectCommand,           "", NULL },
395        { "target",         SEC_GAMEMASTER,     &ChatHandler::HandleTargetObjectCommand,        "", NULL },
396        { "turn",           SEC_GAMEMASTER,     &ChatHandler::HandleTurnObjectCommand,          "", NULL },
397        { "move",           SEC_GAMEMASTER,     &ChatHandler::HandleMoveObjectCommand,          "", NULL },
398        { "near",           SEC_ADMINISTRATOR,  &ChatHandler::HandleNearObjectCommand,          "", NULL },
399        { NULL,             0,                  NULL,                                           "", NULL }
400    };
401
402    static ChatCommand questCommandTable[] =
403    {
404        { "add",            SEC_ADMINISTRATOR,  &ChatHandler::HandleAddQuest,                   "", NULL },
405        { "complete",       SEC_ADMINISTRATOR,  &ChatHandler::HandleCompleteQuest,              "", NULL },
406        { "remove",         SEC_ADMINISTRATOR,  &ChatHandler::HandleRemoveQuest,                "", NULL },
407        { NULL,             0,                  NULL,                                           "", NULL }
408    };
409
410    static ChatCommand gmCommandTable[] =
411    {
412        { "list",           SEC_PLAYER,         &ChatHandler::HandleGMListCommand,              "", NULL },
413        { "visible",        SEC_MODERATOR,      &ChatHandler::HandleVisibleCommand,             "", NULL },
414        { "fly",            SEC_ADMINISTRATOR,  &ChatHandler::HandleFlyModeCommand,             "", NULL },
415        { "",               SEC_MODERATOR,      &ChatHandler::HandleGMmodeCommand,              "", NULL },
416        { NULL,             0,                  NULL,                                           "", NULL }
417    };
418
419    static ChatCommand instanceCommandTable[] =
420    {
421        { "listbinds",      SEC_MODERATOR,      &ChatHandler::HandleInstanceListBindsCommand,   "", NULL },
422        { "unbind",         SEC_MODERATOR,      &ChatHandler::HandleInstanceUnbindCommand,      "", NULL },
423        { "stats",          SEC_MODERATOR,      &ChatHandler::HandleInstanceStatsCommand,       "", NULL },
424        { "savedata",       SEC_MODERATOR,      &ChatHandler::HandleInstanceSaveDataCommand,    "", NULL },
425        { NULL,             0,                  NULL,                                           "", NULL }
426    };
427
428    static ChatCommand commandTable[] =
429    {
430        { "gm",             SEC_MODERATOR,      NULL,                                           "", gmCommandTable },
431        { "npc",            SEC_MODERATOR,      NULL,                                           "", npcCommandTable },
432        { "go",             SEC_MODERATOR,      NULL,                                           "", goCommandTable },
433        { "learn",          SEC_MODERATOR,      NULL,                                           "", learnCommandTable },
434        { "modify",         SEC_MODERATOR,      NULL,                                           "", modifyCommandTable },
435        { "debug",          SEC_MODERATOR,      NULL,                                           "", debugCommandTable },
436        { "tele",           SEC_MODERATOR,      NULL,                                           "", teleCommandTable },
437        { "event",          SEC_GAMEMASTER,     NULL,                                           "", eventCommandTable },
438        { "gobject",        SEC_GAMEMASTER,     NULL,                                           "", gobjectCommandTable },
439        { "honor",          SEC_GAMEMASTER,     NULL,                                           "", honorCommandTable },
440        { "wp",             SEC_GAMEMASTER,     NULL,                                           "", wpCommandTable },
441        { "quest",          SEC_ADMINISTRATOR,  NULL,                                           "", questCommandTable },
442        { "reload",         SEC_ADMINISTRATOR,  NULL,                                           "", reloadCommandTable },
443        { "list",           SEC_ADMINISTRATOR,  NULL,                                           "", listCommandTable },
444        { "lookup",         SEC_ADMINISTRATOR,  NULL,                                           "", lookupCommandTable },
445        { "pdump",          SEC_ADMINISTRATOR,  NULL,                                           "", pdumpCommandTable },
446        { "guild",          SEC_ADMINISTRATOR,  NULL,                                           "", guildCommandTable },
447        { "cast",           SEC_ADMINISTRATOR,  NULL,                                           "", castCommandTable },
448        { "reset",          SEC_ADMINISTRATOR,  NULL,                                           "", resetCommandTable },
449        { "instance",       SEC_ADMINISTRATOR,  NULL,                                           "", instanceCommandTable },
450        { "server",         SEC_ADMINISTRATOR,  NULL,                                           "", serverCommandTable },
451
452        { "aura",           SEC_ADMINISTRATOR,  &ChatHandler::HandleAuraCommand,                "", NULL },
453        { "unaura",         SEC_ADMINISTRATOR,  &ChatHandler::HandleUnAuraCommand,              "", NULL },
454        { "acct",           SEC_PLAYER,         &ChatHandler::HandleAcctCommand,                "", NULL },
455        { "announce",       SEC_MODERATOR,      &ChatHandler::HandleAnnounceCommand,            "", NULL },
456        { "notify",         SEC_MODERATOR,      &ChatHandler::HandleNotifyCommand,              "", NULL },
457        { "goname",         SEC_MODERATOR,      &ChatHandler::HandleGonameCommand,              "", NULL },
458        { "namego",         SEC_MODERATOR,      &ChatHandler::HandleNamegoCommand,              "", NULL },
459        { "groupgo",        SEC_MODERATOR,      &ChatHandler::HandleGroupgoCommand,             "", NULL },
460        { "commands",       SEC_PLAYER,         &ChatHandler::HandleCommandsCommand,            "", NULL },
461        { "demorph",        SEC_GAMEMASTER,     &ChatHandler::HandleDeMorphCommand,             "", NULL },
462        { "die",            SEC_ADMINISTRATOR,  &ChatHandler::HandleDieCommand,                 "", NULL },
463        { "revive",         SEC_ADMINISTRATOR,  &ChatHandler::HandleReviveCommand,              "", NULL },
464        { "dismount",       SEC_PLAYER,         &ChatHandler::HandleDismountCommand,            "", NULL },
465        { "gps",            SEC_MODERATOR,      &ChatHandler::HandleGPSCommand,                 "", NULL },
466        { "guid",           SEC_GAMEMASTER,     &ChatHandler::HandleGUIDCommand,                "", NULL },
467        { "help",           SEC_PLAYER,         &ChatHandler::HandleHelpCommand,                "", NULL },
468        { "itemmove",       SEC_GAMEMASTER,     &ChatHandler::HandleItemMoveCommand,            "", NULL },
469        { "cooldown",       SEC_ADMINISTRATOR,  &ChatHandler::HandleCooldownCommand,            "", NULL },
470        { "unlearn",        SEC_ADMINISTRATOR,  &ChatHandler::HandleUnLearnCommand,             "", NULL },
471        { "distance",       SEC_ADMINISTRATOR,  &ChatHandler::HandleGetDistanceCommand,         "", NULL },
472        { "recall",         SEC_MODERATOR,      &ChatHandler::HandleRecallCommand,              "", NULL },
473        { "save",           SEC_PLAYER,         &ChatHandler::HandleSaveCommand,                "", NULL },
474        { "saveall",        SEC_MODERATOR,      &ChatHandler::HandleSaveAllCommand,             "", NULL },
475        { "kick",           SEC_GAMEMASTER,     &ChatHandler::HandleKickPlayerCommand,          "", NULL },
476        { "security",       SEC_ADMINISTRATOR,  &ChatHandler::HandleSecurityCommand,            "", NULL },
477        { "ban",            SEC_ADMINISTRATOR,  &ChatHandler::HandleBanCommand,                 "", NULL },
478        { "unban",          SEC_ADMINISTRATOR,  &ChatHandler::HandleUnBanCommand,               "", NULL },
479        { "baninfo",        SEC_ADMINISTRATOR,  &ChatHandler::HandleBanInfoCommand,             "", NULL },
480        { "banlist",        SEC_ADMINISTRATOR,  &ChatHandler::HandleBanListCommand,             "", NULL },
481        { "plimit",         SEC_ADMINISTRATOR,  &ChatHandler::HandlePLimitCommand,              "", NULL },
482        { "start",          SEC_PLAYER,         &ChatHandler::HandleStartCommand,               "", NULL },
483        { "taxicheat",      SEC_MODERATOR,      &ChatHandler::HandleTaxiCheatCommand,           "", NULL },
484        { "allowmove",      SEC_ADMINISTRATOR,  &ChatHandler::HandleAllowMovementCommand,       "", NULL },
485        { "linkgrave",      SEC_ADMINISTRATOR,  &ChatHandler::HandleLinkGraveCommand,           "", NULL },
486        { "neargrave",      SEC_ADMINISTRATOR,  &ChatHandler::HandleNearGraveCommand,           "", NULL },
487        { "transport",      SEC_ADMINISTRATOR,  &ChatHandler::HandleSpawnTransportCommand,      "", NULL },
488        { "explorecheat",   SEC_ADMINISTRATOR,  &ChatHandler::HandleExploreCheatCommand,        "", NULL },
489        { "hover",          SEC_ADMINISTRATOR,  &ChatHandler::HandleHoverCommand,               "", NULL },
490        { "levelup",        SEC_ADMINISTRATOR,  &ChatHandler::HandleLevelUpCommand,             "", NULL },
491        { "showarea",       SEC_ADMINISTRATOR,  &ChatHandler::HandleShowAreaCommand,            "", NULL },
492        { "hidearea",       SEC_ADMINISTRATOR,  &ChatHandler::HandleHideAreaCommand,            "", NULL },
493        { "additem",        SEC_ADMINISTRATOR,  &ChatHandler::HandleAddItemCommand,             "", NULL },
494        { "additemset",     SEC_ADMINISTRATOR,  &ChatHandler::HandleAddItemSetCommand,          "", NULL },
495        { "bank",           SEC_ADMINISTRATOR,  &ChatHandler::HandleBankCommand,                "", NULL },
496        { "wchange",        SEC_ADMINISTRATOR,  &ChatHandler::HandleChangeWeather,              "", NULL },
497        { "ticket",         SEC_GAMEMASTER,     &ChatHandler::HandleTicketCommand,              "", NULL },
498        { "delticket",      SEC_GAMEMASTER,     &ChatHandler::HandleDelTicketCommand,           "", NULL },
499        { "maxskill",       SEC_ADMINISTRATOR,  &ChatHandler::HandleMaxSkillCommand,            "", NULL },
500        { "setskill",       SEC_ADMINISTRATOR,  &ChatHandler::HandleSetSkillCommand,            "", NULL },
501        { "whispers",       SEC_MODERATOR,      &ChatHandler::HandleWhispersCommand,            "", NULL },
502        { "pinfo",          SEC_GAMEMASTER,     &ChatHandler::HandlePInfoCommand,               "", NULL },
503        { "password",       SEC_PLAYER,         &ChatHandler::HandlePasswordCommand,            "", NULL },
504        { "lockaccount",    SEC_PLAYER,         &ChatHandler::HandleLockAccountCommand,         "", NULL },
505        { "respawn",        SEC_ADMINISTRATOR,  &ChatHandler::HandleRespawnCommand,             "", NULL },
506        { "sendmail",       SEC_MODERATOR,      &ChatHandler::HandleSendMailCommand,            "", NULL },
507        { "rename",         SEC_GAMEMASTER,     &ChatHandler::HandleRenameCommand,              "", NULL },
508        { "loadscripts",    SEC_ADMINISTRATOR,  &ChatHandler::HandleLoadScriptsCommand,         "", NULL },
509        { "mute",           SEC_GAMEMASTER,     &ChatHandler::HandleMuteCommand,                "", NULL },
510        { "unmute",         SEC_GAMEMASTER,     &ChatHandler::HandleUnmuteCommand,              "", NULL },
511        { "movegens",       SEC_ADMINISTRATOR,  &ChatHandler::HandleMovegensCommand,            "", NULL },
512        { "cometome",       SEC_ADMINISTRATOR,  &ChatHandler::HandleComeToMeCommand,            "", NULL },
513        { "damage",         SEC_ADMINISTRATOR,  &ChatHandler::HandleDamageCommand,              "", NULL },
514        { "combatstop",     SEC_GAMEMASTER,     &ChatHandler::HandleCombatStopCommand,          "", NULL },
515        { "flusharenapoints",    SEC_ADMINISTRATOR, &ChatHandler::HandleFlushArenaPointsCommand,         "",   NULL },
516
517        { NULL,             0,                  NULL,                                           "", NULL }
518    };
519
520    if(load_command_table)
521    {
522        load_command_table = false;
523
524        QueryResult *result = WorldDatabase.Query("SELECT name,security,help FROM command");
525        if (result)
526        {
527            do
528            {
529                Field *fields = result->Fetch();
530                std::string name = fields[0].GetCppString();
531                for(uint32 i = 0; commandTable[i].Name != NULL; i++)
532                {
533                    if (name == commandTable[i].Name)
534                    {
535                        commandTable[i].SecurityLevel = (uint16)fields[1].GetUInt16();
536                        commandTable[i].Help = fields[2].GetCppString();
537                    }
538                    if(commandTable[i].ChildCommands != NULL)
539                    {
540                        ChatCommand *ptable = commandTable[i].ChildCommands;
541                        for(uint32 j = 0; ptable[j].Name != NULL; j++)
542                        {
543                            // first case for "" named subcommand
544                            if (ptable[j].Name[0]=='\0' && name == commandTable[i].Name ||
545                                name == fmtstring("%s %s", commandTable[i].Name, ptable[j].Name) )
546                            {
547                                ptable[j].SecurityLevel = (uint16)fields[1].GetUInt16();
548                                ptable[j].Help = fields[2].GetCppString();
549                            }
550                        }
551                    }
552                }
553            } while(result->NextRow());
554            delete result;
555        }
556    }
557
558    return commandTable;
559}
560
561const char *ChatHandler::GetMangosString(int32 entry)
562{
563    return m_session->GetMangosString(entry);
564}
565
566bool ChatHandler::hasStringAbbr(const char* s1, const char* s2)
567{
568    for(;;)
569    {
570        if( !*s2 )
571            return true;
572        else if( !*s1 )
573            return false;
574        else if( tolower( *s1 ) != tolower( *s2 ) )
575            return false;
576        ++s1; ++s2;
577    }
578}
579
580void ChatHandler::SendSysMessage(const char *str)
581{
582    WorldPacket data;
583
584    // need copy to prevent corruption by strtok call in LineFromMessage original string
585    char* buf = strdup(str);
586    char* pos = buf;
587
588    while(char* line = LineFromMessage(pos))
589    {
590        FillSystemMessageData(&data, line);
591        m_session->SendPacket(&data);
592    }
593
594    free(buf);
595}
596
597void ChatHandler::SendGlobalSysMessage(const char *str)
598{
599    WorldPacket data;
600
601    // need copy to prevent corruption by strtok call in LineFromMessage original string
602    char* buf = strdup(str);
603    char* pos = buf;
604
605    while(char* line = LineFromMessage(pos))
606    {
607        FillSystemMessageData(&data, line);
608        sWorld.SendGlobalMessage(&data);
609    }
610
611    free(buf);
612}
613
614void ChatHandler::SendSysMessage(int32 entry)
615{
616    SendSysMessage(GetMangosString(entry));
617}
618
619void ChatHandler::PSendSysMessage(int32 entry, ...)
620{
621    const char *format = GetMangosString(entry);
622    va_list ap;
623    char str [1024];
624    va_start(ap, entry);
625    vsnprintf(str,1024,format, ap );
626    va_end(ap);
627    SendSysMessage(str);
628}
629
630void ChatHandler::PSendSysMessage(const char *format, ...)
631{
632    va_list ap;
633    char str [1024];
634    va_start(ap, format);
635    vsnprintf(str,1024,format, ap );
636    va_end(ap);
637    SendSysMessage(str);
638}
639
640bool ChatHandler::ExecuteCommandInTable(ChatCommand *table, const char* text, std::string fullcmd)
641{
642    char const* oldtext = text;
643    std::string cmd = "";
644
645    while (*text != ' ' && *text != '\0')
646    {
647        cmd += *text;
648        ++text;
649    }
650
651    while (*text == ' ') ++text;
652
653    if(!cmd.length())
654        return false;
655
656    for(uint32 i = 0; table[i].Name != NULL; i++)
657    {
658        // allow pass "" command name in table
659        if(strlen(table[i].Name) && !hasStringAbbr(table[i].Name, cmd.c_str()))
660            continue;
661
662        // select subcommand from child commands list
663        if(table[i].ChildCommands != NULL)
664        {
665            if(!ExecuteCommandInTable(table[i].ChildCommands, text, fullcmd))
666            {
667                if(text && text[0] != '\0')
668                    SendSysMessage(LANG_NO_SUBCMD);
669                else
670                    SendSysMessage(LANG_CMD_SYNTAX);
671
672                ShowHelpForCommand(table[i].ChildCommands,text);
673            }
674
675            return true;
676        }
677
678        // check security level only for simple  command (without child commands)
679        if(m_session->GetSecurity() < table[i].SecurityLevel)
680            continue;
681
682        SetSentErrorMessage(false);
683        // table[i].Name == "" is special case: send original command to handler
684        if((this->*(table[i].Handler))(strlen(table[i].Name)!=0 ? text : oldtext))
685        {
686            if(table[i].SecurityLevel > SEC_PLAYER)
687            {
688                Player* p = m_session->GetPlayer();
689                uint64 sel_guid = p->GetSelection();
690                sLog.outCommand("Command: %s [Player: %s (Account: %u) X: %f Y: %f Z: %f Map: %u Selected: %s (GUID: %u)]",
691                    fullcmd.c_str(),p->GetName(),m_session->GetAccountId(),p->GetPositionX(),p->GetPositionY(),p->GetPositionZ(),p->GetMapId(),
692                    GetLogNameForGuid(sel_guid),GUID_LOPART(sel_guid));
693            }
694        }
695        // some commands have custom error messages. Don't send the default one in these cases.
696        else if(!sentErrorMessage)
697        {
698            if(!table[i].Help.empty())
699                SendSysMessage(table[i].Help.c_str());
700            else
701                SendSysMessage(LANG_CMD_SYNTAX);
702        }
703
704        return true;
705    }
706
707    return false;
708}
709
710int ChatHandler::ParseCommands(const char* text)
711{
712    ASSERT(text);
713    ASSERT(*text);
714
715    //if(m_session->GetSecurity() == 0)
716    //    return 0;
717
718    if(text[0] != '!' && text[0] != '.')
719        return 0;
720
721    // ignore single . and ! in line
722    if(strlen(text) < 2)
723        return 0;
724
725    // ignore messages staring from many dots.
726    if(text[0] == '.' && text[1] == '.' || text[0] == '!' && text[1] == '!')
727        return 0;
728
729    ++text;
730
731    std::string fullcmd = text;                             // original `text` can't be used. It content destroyed in command code processing.
732
733    if(!ExecuteCommandInTable(getCommandTable(), text, fullcmd))
734        SendSysMessage(LANG_NO_CMD);
735
736    return 1;
737}
738
739bool ChatHandler::ShowHelpForSubCommands(ChatCommand *table, char const* cmd, char const* subcmd)
740{
741    std::string list;
742    for(uint32 i = 0; table[i].Name != NULL; ++i)
743    {
744        if(m_session->GetSecurity() < table[i].SecurityLevel)
745            continue;
746
747        if(strlen(table[i].Name) && !hasStringAbbr(table[i].Name, subcmd))
748            continue;
749
750        (list += "\n    ") += table[i].Name;
751    }
752
753    if(list.empty())
754        return false;
755
756    if(table==getCommandTable())
757    {
758        SendSysMessage(LANG_AVIABLE_CMD);
759        PSendSysMessage("%s",list.c_str());
760    }
761    else
762        PSendSysMessage(LANG_SUBCMDS_LIST,cmd,list.c_str());
763
764    return true;
765}
766
767bool ChatHandler::ShowHelpForCommand(ChatCommand *table, const char* cmd)
768{
769    if(*cmd)
770    {
771        for(uint32 i = 0; table[i].Name != NULL; ++i)
772        {
773            if(m_session->GetSecurity() < table[i].SecurityLevel)
774                continue;
775
776            if(strlen(table[i].Name) && !hasStringAbbr(table[i].Name, cmd))
777                continue;
778
779            // have subcommand
780            char const* subcmd = (*cmd) ? strtok(NULL, " ") : "";
781
782            if(table[i].ChildCommands && subcmd && *subcmd)
783            {
784                if(ShowHelpForCommand(table[i].ChildCommands, subcmd))
785                    return true;
786            }
787
788            if(!table[i].Help.empty())
789                SendSysMessage(table[i].Help.c_str());
790
791            if(table[i].ChildCommands)
792                if(ShowHelpForSubCommands(table[i].ChildCommands,table[i].Name,subcmd ? subcmd : ""))
793                    return true;
794
795            return !table[i].Help.empty();
796        }
797    }
798    else
799    {
800        for(uint32 i = 0; table[i].Name != NULL; ++i)
801        {
802            if(m_session->GetSecurity() < table[i].SecurityLevel)
803                continue;
804
805            if(strlen(table[i].Name))
806                continue;
807
808            if(!table[i].Help.empty())
809                SendSysMessage(table[i].Help.c_str());
810
811            if(table[i].ChildCommands)
812                if(ShowHelpForSubCommands(table[i].ChildCommands,"",""))
813                    return true;
814
815            return !table[i].Help.empty();
816        }
817    }
818
819    return ShowHelpForSubCommands(table,"",cmd);
820}
821
822//Note: target_guid used only in CHAT_MSG_WHISPER_INFORM mode (in this case channelName ignored)
823void ChatHandler::FillMessageData( WorldPacket *data, WorldSession* session, uint8 type, uint32 language, const char *channelName, uint64 target_guid, const char *message, Unit *speaker)
824{
825    uint32 messageLength = (message ? strlen(message) : 0) + 1;
826
827    data->Initialize(SMSG_MESSAGECHAT, 100);                // guess size
828    *data << uint8(type);
829    if ((type != CHAT_MSG_CHANNEL && type != CHAT_MSG_WHISPER) || language == LANG_ADDON)
830        *data << uint32(language);
831    else
832        *data << uint32(LANG_UNIVERSAL);
833
834    switch(type)
835    {
836        case CHAT_MSG_SAY:
837        case CHAT_MSG_PARTY:
838        case CHAT_MSG_RAID:
839        case CHAT_MSG_GUILD:
840        case CHAT_MSG_OFFICER:
841        case CHAT_MSG_YELL:
842        case CHAT_MSG_WHISPER:
843        case CHAT_MSG_CHANNEL:
844        case CHAT_MSG_RAID_LEADER:
845        case CHAT_MSG_RAID_WARNING:
846        case CHAT_MSG_BG_SYSTEM_NEUTRAL:
847        case CHAT_MSG_BG_SYSTEM_ALLIANCE:
848        case CHAT_MSG_BG_SYSTEM_HORDE:
849        case CHAT_MSG_BATTLEGROUND:
850        case CHAT_MSG_BATTLEGROUND_LEADER:
851            target_guid = session ? session->GetPlayer()->GetGUID() : 0;
852            break;
853        case CHAT_MSG_MONSTER_SAY:
854        case CHAT_MSG_MONSTER_PARTY:
855        case CHAT_MSG_MONSTER_YELL:
856        case CHAT_MSG_MONSTER_WHISPER:
857        case CHAT_MSG_MONSTER_EMOTE:
858        case CHAT_MSG_RAID_BOSS_WHISPER:
859        case CHAT_MSG_RAID_BOSS_EMOTE:
860        {
861            *data << uint64(speaker->GetGUID());
862            *data << uint32(0);                             // 2.1.0
863            *data << uint32(strlen(speaker->GetName()) + 1);
864            *data << speaker->GetName();
865            uint64 listener_guid = 0;
866            *data << uint64(listener_guid);
867            if(listener_guid && !IS_PLAYER_GUID(listener_guid))
868            {
869                *data << uint32(1);                         // string listener_name_length
870                *data << uint8(0);                          // string listener_name
871            }
872            *data << uint32(messageLength);
873            *data << message;
874            *data << uint8(0);
875            return;
876        }
877        default:
878            if (type != CHAT_MSG_REPLY && type != CHAT_MSG_IGNORED && type != CHAT_MSG_DND && type != CHAT_MSG_AFK)
879                target_guid = 0;                            // only for CHAT_MSG_WHISPER_INFORM used original value target_guid
880            break;
881    }
882
883    *data << uint64(target_guid);                           // there 0 for BG messages
884    *data << uint32(0);                                     // can be chat msg group or something
885
886    if (type == CHAT_MSG_CHANNEL)
887    {
888        ASSERT(channelName);
889        *data << channelName;
890    }
891
892    *data << uint64(target_guid);
893    *data << uint32(messageLength);
894    *data << message;
895    if(session != 0 && type != CHAT_MSG_REPLY && type != CHAT_MSG_DND && type != CHAT_MSG_AFK)
896        *data << uint8(session->GetPlayer()->chatTag());
897    else
898        *data << uint8(0);
899}
900
901Player * ChatHandler::getSelectedPlayer()
902{
903    uint64 guid  = m_session->GetPlayer()->GetSelection();
904
905    if (guid == 0)
906        return m_session->GetPlayer();
907
908    return objmgr.GetPlayer(guid);
909}
910
911Unit* ChatHandler::getSelectedUnit()
912{
913    uint64 guid = m_session->GetPlayer()->GetSelection();
914
915    if (guid == 0)
916        return m_session->GetPlayer();
917
918    return ObjectAccessor::GetUnit(*m_session->GetPlayer(),guid);
919}
920
921Creature* ChatHandler::getSelectedCreature()
922{
923    return ObjectAccessor::GetCreatureOrPet(*m_session->GetPlayer(),m_session->GetPlayer()->GetSelection());
924}
925
926char* ChatHandler::extractKeyFromLink(char* text, char const* linkType, char** something1)
927{
928    // skip empty
929    if(!text)
930        return NULL;
931
932    // skip speces
933    while(*text==' '||*text=='\t'||*text=='\b')
934        ++text;
935
936    if(!*text)
937        return NULL;
938
939    // return non link case
940    if(text[0]!='|')
941        return strtok(text, " ");
942
943    // [name] Shift-click form |color|linkType:key|h[name]|h|r
944    // or
945    // [name] Shift-click form |color|linkType:key:something1:...:somethingN|h[name]|h|r
946
947    char* check = strtok(text, "|");                        // skip color
948    if(!check)
949        return NULL;                                        // end of data
950
951    char* cLinkType = strtok(NULL, ":");                    // linktype
952    if(!cLinkType)
953        return NULL;                                        // end of data
954
955    if(strcmp(cLinkType,linkType) != 0)
956    {
957        strtok(NULL, " ");                                  // skip link tail (to allow continue strtok(NULL,s) use after retturn from function
958        SendSysMessage(LANG_WRONG_LINK_TYPE);
959        return NULL;
960    }
961
962    char* cKeys = strtok(NULL, "|");                        // extract keys and values
963    char* cKeysTail = strtok(NULL, "");
964
965    char* cKey = strtok(cKeys, ":|");                       // extract key
966    if(something1)
967        *something1 = strtok(NULL, ":|");                   // extract something
968
969    strtok(cKeysTail, "]");                                 // restart scan tail and skip name with possible spaces
970    strtok(NULL, " ");                                      // skip link tail (to allow continue strtok(NULL,s) use after retturn from function
971    return cKey;
972}
973
974char* ChatHandler::extractKeyFromLink(char* text, char const* const* linkTypes, int* found_idx, char** something1)
975{
976    // skip empty
977    if(!text)
978        return NULL;
979
980    // skip speces
981    while(*text==' '||*text=='\t'||*text=='\b')
982        ++text;
983
984    if(!*text)
985        return NULL;
986
987    // return non link case
988    if(text[0]!='|')
989        return strtok(text, " ");
990
991    // [name] Shift-click form |color|linkType:key|h[name]|h|r
992    // or
993    // [name] Shift-click form |color|linkType:key:something1:...:somethingN|h[name]|h|r
994
995    char* check = strtok(text, "|");                        // skip color
996    if(!check)
997        return NULL;                                        // end of data
998
999    char* cLinkType = strtok(NULL, ":");                    // linktype
1000    if(!cLinkType)
1001        return NULL;                                        // end of data
1002
1003    for(int i = 0; linkTypes[i]; ++i)
1004    {
1005        if(strcmp(cLinkType,linkTypes[i]) == 0)
1006        {
1007            char* cKeys = strtok(NULL, "|");                // extract keys and values
1008            char* cKeysTail = strtok(NULL, "");
1009
1010            char* cKey = strtok(cKeys, ":|");               // extract key
1011            if(something1)
1012                *something1 = strtok(NULL, ":|");           // extract something
1013
1014            strtok(cKeysTail, "]");                         // restart scan tail and skip name with possible spaces
1015            strtok(NULL, " ");                              // skip link tail (to allow continue strtok(NULL,s) use after return from function
1016            if(found_idx)
1017                *found_idx = i;
1018            return cKey;
1019        }
1020    }
1021
1022    strtok(NULL, " ");                                      // skip link tail (to allow continue strtok(NULL,s) use after return from function
1023    SendSysMessage(LANG_WRONG_LINK_TYPE);
1024    return NULL;
1025}
1026
1027char const *fmtstring( char const *format, ... )
1028{
1029    va_list        argptr;
1030    #define    MAX_FMT_STRING    32000
1031    static char        temp_buffer[MAX_FMT_STRING];
1032    static char        string[MAX_FMT_STRING];
1033    static int        index = 0;
1034    char    *buf;
1035    int len;
1036
1037    va_start(argptr, format);
1038    vsnprintf(temp_buffer,MAX_FMT_STRING, format, argptr);
1039    va_end(argptr);
1040
1041    len = strlen(temp_buffer);
1042
1043    if( len >= MAX_FMT_STRING )
1044        return "ERROR";
1045
1046    if (len + index >= MAX_FMT_STRING-1)
1047    {
1048        index = 0;
1049    }
1050
1051    buf = &string[index];
1052    memcpy( buf, temp_buffer, len+1 );
1053
1054    index += len + 1;
1055
1056    return buf;
1057}
1058
1059GameObject* ChatHandler::GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid,uint32 entry)
1060{
1061    Player* pl = m_session->GetPlayer();
1062
1063    GameObject* obj = ObjectAccessor::GetGameObject(*pl, MAKE_NEW_GUID(lowguid, entry, HIGHGUID_GAMEOBJECT));
1064
1065    if(!obj && objmgr.GetGOData(lowguid))                   // guid is DB guid of object
1066    {
1067        // search near player then
1068        CellPair p(MaNGOS::ComputeCellPair(pl->GetPositionX(), pl->GetPositionY()));
1069        Cell cell(p);
1070        cell.data.Part.reserved = ALL_DISTRICT;
1071
1072        MaNGOS::GameObjectWithDbGUIDCheck go_check(*pl,lowguid);
1073        MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck> checker(obj,go_check);
1074
1075        TypeContainerVisitor<MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > object_checker(checker);
1076        CellLock<GridReadGuard> cell_lock(cell, p);
1077        cell_lock->Visit(cell_lock, object_checker, *MapManager::Instance().GetMap(pl->GetMapId(), pl));
1078    }
1079
1080    return obj;
1081}
1082
1083static char const* const spellTalentKeys[] = {
1084    "Hspell",
1085    "Htalent",
1086    0
1087};
1088
1089uint32 ChatHandler::extractSpellIdFromLink(char* text)
1090{
1091    // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
1092    // number or [name] Shift-click form |color|Htalent:telen_id,rank|h[name]|h|r
1093    int type = 0;
1094    char* rankS = NULL;
1095    char* idS = extractKeyFromLink(text,spellTalentKeys,&type,&rankS);
1096    if(!idS)
1097        return 0;
1098
1099    uint32 id = (uint32)atol(idS);
1100
1101    // spell
1102    if(type==0)
1103        return id;
1104
1105    // talent
1106    TalentEntry const* talentEntry = sTalentStore.LookupEntry(id);
1107    if(!talentEntry)
1108        return 0;
1109
1110    int32 rank = rankS ? (uint32)atol(rankS) : 0;
1111    if(rank >= 5)
1112        return 0;
1113
1114    if(rank < 0)
1115        rank = 0;
1116
1117    return talentEntry->RankID[rank];
1118}
1119
1120GameTele const* ChatHandler::extractGameTeleFromLink(char* text)
1121{
1122    // id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r
1123    char* cId = extractKeyFromLink(text,"Htele");
1124    if(!cId)
1125        return false;
1126
1127    // id case (explicit or from shift link)
1128    if(cId[0] >= '0' || cId[0] >= '9')
1129        if(uint32 id = atoi(cId))
1130            return objmgr.GetGameTele(id);
1131
1132    return objmgr.GetGameTele(cId);
1133}
Note: See TracBrowser for help on using the browser.