[8483] Implement glyph 43361.
[getmangos.git] / src / game / Chat.cpp
blob9ae5cd7228bbcc9e140347a4ebcb58533a92fde8
1 /*
2 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
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.
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.
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
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 "GridNotifiersImpl.h"
32 #include "CellImpl.h"
33 #include "AccountMgr.h"
34 #include "SpellMgr.h"
36 // Supported shift-links (client generated and server side)
37 // |color|Hachievement:achievement_id:player_guid:0:0:0:0:0:0:0:0|h[name]|h|r
38 // - client, item icon shift click, not used in server currently
39 // |color|Harea:area_id|h[name]|h|r
40 // |color|Hcreature:creature_guid|h[name]|h|r
41 // |color|Hcreature_entry:creature_id|h[name]|h|r
42 // |color|Henchant:recipe_spell_id|h[prof_name: recipe_name]|h|r - client, at shift click in recipes list dialog
43 // |color|Hgameevent:id|h[name]|h|r
44 // |color|Hgameobject:go_guid|h[name]|h|r
45 // |color|Hgameobject_entry:go_id|h[name]|h|r
46 // |color|Hglyph:glyph_slot_id:glyph_prop_id|h[%s]|h|r - client, at shift click in glyphs dialog, GlyphSlot.dbc, GlyphProperties.dbc
47 // |color|Hitem:item_id:perm_ench_id:gem1:gem2:gem3:0:0:0:0:reporter_level|h[name]|h|r
48 // - client, item icon shift click
49 // |color|Hitemset:itemset_id|h[name]|h|r
50 // |color|Hplayer:name|h[name]|h|r - client, in some messages, at click copy only name instead link
51 // |color|Hquest:quest_id:quest_level|h[name]|h|r - client, quest list name shift-click
52 // |color|Hskill:skill_id|h[name]|h|r
53 // |color|Hspell:spell_id|h[name]|h|r - client, spellbook spell icon shift-click
54 // |color|Htalent:talent_id,rank|h[name]|h|r - client, talent icon shift-click
55 // |color|Htaxinode:id|h[name]|h|r
56 // |color|Htele:id|h[name]|h|r
57 // |color|Htrade:spell_id,cur_value,max_value,unk3int,unk3str|h[name]|h|r - client, spellbook profession icon shift-click
59 bool ChatHandler::load_command_table = true;
61 ChatCommand * ChatHandler::getCommandTable()
63 static ChatCommand accountSetCommandTable[] =
65 { "addon", SEC_ADMINISTRATOR, true, &ChatHandler::HandleAccountSetAddonCommand, "", NULL },
66 { "gmlevel", SEC_CONSOLE, true, &ChatHandler::HandleAccountSetGmLevelCommand, "", NULL },
67 { "password", SEC_CONSOLE, true, &ChatHandler::HandleAccountSetPasswordCommand, "", NULL },
68 { NULL, 0, false, NULL, "", NULL }
71 static ChatCommand accountCommandTable[] =
73 { "create", SEC_CONSOLE, true, &ChatHandler::HandleAccountCreateCommand, "", NULL },
74 { "delete", SEC_CONSOLE, true, &ChatHandler::HandleAccountDeleteCommand, "", NULL },
75 { "onlinelist", SEC_CONSOLE, true, &ChatHandler::HandleAccountOnlineListCommand, "", NULL },
76 { "lock", SEC_PLAYER, false, &ChatHandler::HandleAccountLockCommand, "", NULL },
77 { "set", SEC_ADMINISTRATOR, true, NULL, "", accountSetCommandTable },
78 { "password", SEC_PLAYER, false, &ChatHandler::HandleAccountPasswordCommand, "", NULL },
79 { "", SEC_PLAYER, false, &ChatHandler::HandleAccountCommand, "", NULL },
80 { NULL, 0, false, NULL, "", NULL }
83 static ChatCommand banCommandTable[] =
85 { "account", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanAccountCommand, "", NULL },
86 { "character", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanCharacterCommand, "", NULL },
87 { "ip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanIPCommand, "", NULL },
88 { NULL, 0, false, NULL, "", NULL }
91 static ChatCommand baninfoCommandTable[] =
93 { "account", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanInfoAccountCommand, "", NULL },
94 { "character", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanInfoCharacterCommand, "", NULL },
95 { "ip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanInfoIPCommand, "", NULL },
96 { NULL, 0, false, NULL, "", NULL }
99 static ChatCommand banlistCommandTable[] =
101 { "account", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanListAccountCommand, "", NULL },
102 { "character", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanListCharacterCommand, "", NULL },
103 { "ip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanListIPCommand, "", NULL },
104 { NULL, 0, false, NULL, "", NULL }
107 static ChatCommand castCommandTable[] =
109 { "back", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCastBackCommand, "", NULL },
110 { "dist", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCastDistCommand, "", NULL },
111 { "self", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCastSelfCommand, "", NULL },
112 { "target", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCastTargetCommand, "", NULL },
113 { "", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCastCommand, "", NULL },
114 { NULL, 0, false, NULL, "", NULL }
117 static ChatCommand characterCommandTable[] =
119 { "customize", SEC_GAMEMASTER, true, &ChatHandler::HandleCharacterCustomizeCommand, "", NULL },
120 { "delete", SEC_CONSOLE, true, &ChatHandler::HandleCharacterDeleteCommand, "", NULL },
121 { "level", SEC_ADMINISTRATOR, true, &ChatHandler::HandleCharacterLevelCommand, "", NULL },
122 { "rename", SEC_GAMEMASTER, true, &ChatHandler::HandleCharacterRenameCommand, "", NULL },
123 { "reputation", SEC_GAMEMASTER, true, &ChatHandler::HandleCharacterReputationCommand, "", NULL },
124 { NULL, 0, false, NULL, "", NULL }
127 static ChatCommand debugPlayCommandTable[] =
129 { "cinematic", SEC_MODERATOR, false, &ChatHandler::HandleDebugPlayCinematicCommand, "", NULL },
130 { "movie", SEC_MODERATOR, false, &ChatHandler::HandleDebugPlayMovieCommand, "", NULL },
131 { "sound", SEC_MODERATOR, false, &ChatHandler::HandleDebugPlaySoundCommand, "", NULL },
132 { NULL, 0, false, NULL, "", NULL }
135 static ChatCommand debugSendCommandTable[] =
137 { "buyerror", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendBuyErrorCommand, "", NULL },
138 { "channelnotify", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendChannelNotifyCommand, "", NULL },
139 { "chatmmessage", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendChatMsgCommand, "", NULL },
140 { "equiperror", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendEquipErrorCommand, "", NULL },
141 { "largepacket", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendLargePacketCommand, "", NULL },
142 { "opcode", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendOpcodeCommand, "", NULL },
143 { "poi", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendPoiCommand, "", NULL },
144 { "qpartymsg", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendQuestPartyMsgCommand, "", NULL },
145 { "qinvalidmsg", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendQuestInvalidMsgCommand, "", NULL },
146 { "sellerror", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendSellErrorCommand, "", NULL },
147 { "setphaseshift", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendSetPhaseShiftCommand, "", NULL },
148 { "spellfail", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendSpellFailCommand, "", NULL },
149 { NULL, 0, false, NULL, "", NULL }
152 static ChatCommand debugCommandTable[] =
154 { "anim", SEC_GAMEMASTER, false, &ChatHandler::HandleDebugAnimCommand, "", NULL },
155 { "arena", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugArenaCommand, "", NULL },
156 { "bg", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugBattlegroundCommand, "", NULL },
157 { "getitemstate", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugGetItemStateCommand, "", NULL },
158 { "lootrecipient", SEC_GAMEMASTER, false, &ChatHandler::HandleDebugGetLootRecipientCommand, "", NULL },
159 { "getvalue", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugGetValueCommand, "", NULL },
160 { "Mod32Value", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugMod32ValueCommand, "", NULL },
161 { "play", SEC_MODERATOR, false, NULL, "", debugPlayCommandTable },
162 { "send", SEC_ADMINISTRATOR, false, NULL, "", debugSendCommandTable },
163 { "setaurastate", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSetAuraStateCommand, "", NULL },
164 { "setitemflag", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSetItemFlagCommand, "", NULL },
165 { "setvalue", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSetValueCommand, "", NULL },
166 { "spellcheck", SEC_CONSOLE, true, &ChatHandler::HandleDebugSpellCheckCommand, "", NULL },
167 { "spawnvehicle", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSpawnVehicle, "", NULL },
168 { "uws", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugUpdateWorldStateCommand, "", NULL },
169 { "update", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugUpdateCommand, "", NULL },
170 { NULL, 0, false, NULL, "", NULL }
173 static ChatCommand eventCommandTable[] =
175 { "activelist", SEC_GAMEMASTER, true, &ChatHandler::HandleEventActiveListCommand, "", NULL },
176 { "start", SEC_GAMEMASTER, true, &ChatHandler::HandleEventStartCommand, "", NULL },
177 { "stop", SEC_GAMEMASTER, true, &ChatHandler::HandleEventStopCommand, "", NULL },
178 { "", SEC_GAMEMASTER, true, &ChatHandler::HandleEventInfoCommand, "", NULL },
179 { NULL, 0, false, NULL, "", NULL }
182 static ChatCommand gmCommandTable[] =
184 { "chat", SEC_MODERATOR, false, &ChatHandler::HandleGMChatCommand, "", NULL },
185 { "fly", SEC_ADMINISTRATOR, false, &ChatHandler::HandleGMFlyCommand, "", NULL },
186 { "ingame", SEC_PLAYER, true, &ChatHandler::HandleGMListIngameCommand, "", NULL },
187 { "list", SEC_ADMINISTRATOR, true, &ChatHandler::HandleGMListFullCommand, "", NULL },
188 { "visible", SEC_MODERATOR, false, &ChatHandler::HandleGMVisibleCommand, "", NULL },
189 { "", SEC_MODERATOR, false, &ChatHandler::HandleGMCommand, "", NULL },
190 { NULL, 0, false, NULL, "", NULL }
193 static ChatCommand goCommandTable[] =
195 { "creature", SEC_MODERATOR, false, &ChatHandler::HandleGoCreatureCommand, "", NULL },
196 { "graveyard", SEC_MODERATOR, false, &ChatHandler::HandleGoGraveyardCommand, "", NULL },
197 { "grid", SEC_MODERATOR, false, &ChatHandler::HandleGoGridCommand, "", NULL },
198 { "object", SEC_MODERATOR, false, &ChatHandler::HandleGoObjectCommand, "", NULL },
199 { "taxinode", SEC_MODERATOR, false, &ChatHandler::HandleGoTaxinodeCommand, "", NULL },
200 { "trigger", SEC_MODERATOR, false, &ChatHandler::HandleGoTriggerCommand, "", NULL },
201 { "zonexy", SEC_MODERATOR, false, &ChatHandler::HandleGoZoneXYCommand, "", NULL },
202 { "xy", SEC_MODERATOR, false, &ChatHandler::HandleGoXYCommand, "", NULL },
203 { "xyz", SEC_MODERATOR, false, &ChatHandler::HandleGoXYZCommand, "", NULL },
204 { "", SEC_MODERATOR, false, &ChatHandler::HandleGoXYZCommand, "", NULL },
205 { NULL, 0, false, NULL, "", NULL }
208 static ChatCommand gobjectCommandTable[] =
210 { "add", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectAddCommand, "", NULL },
211 { "delete", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectDeleteCommand, "", NULL },
212 { "move", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectMoveCommand, "", NULL },
213 { "near", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectNearCommand, "", NULL },
214 { "setphase", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectPhaseCommand, "", NULL },
215 { "target", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectTargetCommand, "", NULL },
216 { "turn", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectTurnCommand, "", NULL },
217 { NULL, 0, false, NULL, "", NULL }
220 static ChatCommand guildCommandTable[] =
222 { "create", SEC_GAMEMASTER, true, &ChatHandler::HandleGuildCreateCommand, "", NULL },
223 { "delete", SEC_GAMEMASTER, true, &ChatHandler::HandleGuildDeleteCommand, "", NULL },
224 { "invite", SEC_GAMEMASTER, true, &ChatHandler::HandleGuildInviteCommand, "", NULL },
225 { "uninvite", SEC_GAMEMASTER, true, &ChatHandler::HandleGuildUninviteCommand, "", NULL },
226 { "rank", SEC_GAMEMASTER, true, &ChatHandler::HandleGuildRankCommand, "", NULL },
227 { NULL, 0, false, NULL, "", NULL }
230 static ChatCommand honorCommandTable[] =
232 { "add", SEC_GAMEMASTER, false, &ChatHandler::HandleHonorAddCommand, "", NULL },
233 { "addkill", SEC_GAMEMASTER, false, &ChatHandler::HandleHonorAddKillCommand, "", NULL },
234 { "update", SEC_GAMEMASTER, false, &ChatHandler::HandleHonorUpdateCommand, "", NULL },
235 { NULL, 0, false, NULL, "", NULL }
238 static ChatCommand instanceCommandTable[] =
240 { "listbinds", SEC_ADMINISTRATOR, false, &ChatHandler::HandleInstanceListBindsCommand, "", NULL },
241 { "unbind", SEC_ADMINISTRATOR, false, &ChatHandler::HandleInstanceUnbindCommand, "", NULL },
242 { "stats", SEC_ADMINISTRATOR, true, &ChatHandler::HandleInstanceStatsCommand, "", NULL },
243 { "savedata", SEC_ADMINISTRATOR, false, &ChatHandler::HandleInstanceSaveDataCommand, "", NULL },
244 { NULL, 0, false, NULL, "", NULL }
247 static ChatCommand learnCommandTable[] =
249 { "all", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLearnAllCommand, "", NULL },
250 { "all_gm", SEC_GAMEMASTER, false, &ChatHandler::HandleLearnAllGMCommand, "", NULL },
251 { "all_crafts", SEC_GAMEMASTER, false, &ChatHandler::HandleLearnAllCraftsCommand, "", NULL },
252 { "all_default", SEC_MODERATOR, false, &ChatHandler::HandleLearnAllDefaultCommand, "", NULL },
253 { "all_lang", SEC_MODERATOR, false, &ChatHandler::HandleLearnAllLangCommand, "", NULL },
254 { "all_myclass", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLearnAllMyClassCommand, "", NULL },
255 { "all_mypettalents",SEC_ADMINISTRATOR, false, &ChatHandler::HandleLearnAllMyPetTalentsCommand,"", NULL },
256 { "all_myspells", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLearnAllMySpellsCommand, "", NULL },
257 { "all_mytalents", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLearnAllMyTalentsCommand, "", NULL },
258 { "all_recipes", SEC_GAMEMASTER, false, &ChatHandler::HandleLearnAllRecipesCommand, "", NULL },
259 { "", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLearnCommand, "", NULL },
260 { NULL, 0, false, NULL, "", NULL }
263 static ChatCommand listCommandTable[] =
265 { "creature", SEC_ADMINISTRATOR, true, &ChatHandler::HandleListCreatureCommand, "", NULL },
266 { "item", SEC_ADMINISTRATOR, true, &ChatHandler::HandleListItemCommand, "", NULL },
267 { "object", SEC_ADMINISTRATOR, true, &ChatHandler::HandleListObjectCommand, "", NULL },
268 { "auras", SEC_ADMINISTRATOR, false, &ChatHandler::HandleListAurasCommand, "", NULL },
269 { NULL, 0, false, NULL, "", NULL }
272 static ChatCommand lookupPlayerCommandTable[] =
274 { "ip", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupPlayerIpCommand, "", NULL },
275 { "account", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupPlayerAccountCommand, "", NULL },
276 { "email", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupPlayerEmailCommand, "", NULL },
277 { NULL, 0, false, NULL, "", NULL }
280 static ChatCommand lookupCommandTable[] =
282 { "area", SEC_MODERATOR, true, &ChatHandler::HandleLookupAreaCommand, "", NULL },
283 { "creature", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupCreatureCommand, "", NULL },
284 { "event", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupEventCommand, "", NULL },
285 { "faction", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupFactionCommand, "", NULL },
286 { "item", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupItemCommand, "", NULL },
287 { "itemset", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupItemSetCommand, "", NULL },
288 { "object", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupObjectCommand, "", NULL },
289 { "quest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupQuestCommand, "", NULL },
290 { "player", SEC_GAMEMASTER, true, NULL, "", lookupPlayerCommandTable },
291 { "skill", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupSkillCommand, "", NULL },
292 { "spell", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupSpellCommand, "", NULL },
293 { "taxinode", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupTaxiNodeCommand, "", NULL },
294 { "tele", SEC_MODERATOR, true, &ChatHandler::HandleLookupTeleCommand, "", NULL },
295 { NULL, 0, false, NULL, "", NULL }
298 static ChatCommand modifyCommandTable[] =
300 { "hp", SEC_MODERATOR, false, &ChatHandler::HandleModifyHPCommand, "", NULL },
301 { "mana", SEC_MODERATOR, false, &ChatHandler::HandleModifyManaCommand, "", NULL },
302 { "rage", SEC_MODERATOR, false, &ChatHandler::HandleModifyRageCommand, "", NULL },
303 { "runicpower", SEC_MODERATOR, false, &ChatHandler::HandleModifyRunicPowerCommand, "", NULL },
304 { "energy", SEC_MODERATOR, false, &ChatHandler::HandleModifyEnergyCommand, "", NULL },
305 { "money", SEC_MODERATOR, false, &ChatHandler::HandleModifyMoneyCommand, "", NULL },
306 { "speed", SEC_MODERATOR, false, &ChatHandler::HandleModifySpeedCommand, "", NULL },
307 { "swim", SEC_MODERATOR, false, &ChatHandler::HandleModifySwimCommand, "", NULL },
308 { "scale", SEC_MODERATOR, false, &ChatHandler::HandleModifyScaleCommand, "", NULL },
309 { "bit", SEC_MODERATOR, false, &ChatHandler::HandleModifyBitCommand, "", NULL },
310 { "bwalk", SEC_MODERATOR, false, &ChatHandler::HandleModifyBWalkCommand, "", NULL },
311 { "fly", SEC_MODERATOR, false, &ChatHandler::HandleModifyFlyCommand, "", NULL },
312 { "aspeed", SEC_MODERATOR, false, &ChatHandler::HandleModifyASpeedCommand, "", NULL },
313 { "faction", SEC_MODERATOR, false, &ChatHandler::HandleModifyFactionCommand, "", NULL },
314 { "spell", SEC_MODERATOR, false, &ChatHandler::HandleModifySpellCommand, "", NULL },
315 { "tp", SEC_MODERATOR, false, &ChatHandler::HandleModifyTalentCommand, "", NULL },
316 { "titles", SEC_MODERATOR, false, &ChatHandler::HandleModifyKnownTitlesCommand, "", NULL },
317 { "mount", SEC_MODERATOR, false, &ChatHandler::HandleModifyMountCommand, "", NULL },
318 { "honor", SEC_MODERATOR, false, &ChatHandler::HandleModifyHonorCommand, "", NULL },
319 { "rep", SEC_GAMEMASTER, false, &ChatHandler::HandleModifyRepCommand, "", NULL },
320 { "arena", SEC_MODERATOR, false, &ChatHandler::HandleModifyArenaCommand, "", NULL },
321 { "drunk", SEC_MODERATOR, false, &ChatHandler::HandleModifyDrunkCommand, "", NULL },
322 { "standstate", SEC_GAMEMASTER, false, &ChatHandler::HandleModifyStandStateCommand, "", NULL },
323 { "morph", SEC_GAMEMASTER, false, &ChatHandler::HandleModifyMorphCommand, "", NULL },
324 { "phase", SEC_ADMINISTRATOR, false, &ChatHandler::HandleModifyPhaseCommand, "", NULL },
325 { "gender", SEC_GAMEMASTER, false, &ChatHandler::HandleModifyGenderCommand, "", NULL },
326 { NULL, 0, false, NULL, "", NULL }
329 static ChatCommand npcCommandTable[] =
331 { "add", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcAddCommand, "", NULL },
332 { "additem", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcAddVendorItemCommand, "", NULL },
333 { "addmove", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcAddMoveCommand, "", NULL },
334 { "allowmove", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcAllowMovementCommand, "", NULL },
335 { "changeentry", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcChangeEntryCommand, "", NULL },
336 { "changelevel", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcChangeLevelCommand, "", NULL },
337 { "delete", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcDeleteCommand, "", NULL },
338 { "delitem", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcDelVendorItemCommand, "", NULL },
339 { "factionid", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcFactionIdCommand, "", NULL },
340 { "flag", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcFlagCommand, "", NULL },
341 { "follow", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcFollowCommand, "", NULL },
342 { "info", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcInfoCommand, "", NULL },
343 { "move", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcMoveCommand, "", NULL },
344 { "playemote", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcPlayEmoteCommand, "", NULL },
345 { "setmodel", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSetModelCommand, "", NULL },
346 { "setmovetype", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSetMoveTypeCommand, "", NULL },
347 { "setphase", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSetPhaseCommand, "", NULL },
348 { "spawndist", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSpawnDistCommand, "", NULL },
349 { "spawntime", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSpawnTimeCommand, "", NULL },
350 { "say", SEC_MODERATOR, false, &ChatHandler::HandleNpcSayCommand, "", NULL },
351 { "textemote", SEC_MODERATOR, false, &ChatHandler::HandleNpcTextEmoteCommand, "", NULL },
352 { "unfollow", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcUnFollowCommand, "", NULL },
353 { "whisper", SEC_MODERATOR, false, &ChatHandler::HandleNpcWhisperCommand, "", NULL },
354 { "yell", SEC_MODERATOR, false, &ChatHandler::HandleNpcYellCommand, "", NULL },
355 { "tame", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcTameCommand, "", NULL },
356 { "setdeathstate", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSetDeathStateCommand, "", NULL },
358 //{ TODO: fix or remove this commands
359 { "addweapon", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcAddWeaponCommand, "", NULL },
360 { "name", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcNameCommand, "", NULL },
361 { "subname", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSubNameCommand, "", NULL },
364 { NULL, 0, false, NULL, "", NULL }
367 static ChatCommand pdumpCommandTable[] =
369 { "load", SEC_ADMINISTRATOR, true, &ChatHandler::HandlePDumpLoadCommand, "", NULL },
370 { "write", SEC_ADMINISTRATOR, true, &ChatHandler::HandlePDumpWriteCommand, "", NULL },
371 { NULL, 0, false, NULL, "", NULL }
374 static ChatCommand questCommandTable[] =
376 { "add", SEC_ADMINISTRATOR, false, &ChatHandler::HandleQuestAdd, "", NULL },
377 { "complete", SEC_ADMINISTRATOR, false, &ChatHandler::HandleQuestComplete, "", NULL },
378 { "remove", SEC_ADMINISTRATOR, false, &ChatHandler::HandleQuestRemove, "", NULL },
379 { NULL, 0, false, NULL, "", NULL }
382 static ChatCommand reloadCommandTable[] =
384 { "all", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllCommand, "", NULL },
385 { "all_achievement",SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllAchievementCommand,"", NULL },
386 { "all_area", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllAreaCommand, "", NULL },
387 { "all_eventai", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllEventAICommand, "", NULL },
388 { "all_item", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllItemCommand, "", NULL },
389 { "all_locales", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllLocalesCommand, "", NULL },
390 { "all_loot", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllLootCommand, "", NULL },
391 { "all_npc", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllNpcCommand, "", NULL },
392 { "all_quest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllQuestCommand, "", NULL },
393 { "all_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllScriptsCommand, "", NULL },
394 { "all_spell", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllSpellCommand, "", NULL },
396 { "config", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadConfigCommand, "", NULL },
398 { "achievement_criteria_data", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAchievementCriteriaDataCommand, "", NULL },
399 { "achievement_reward", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAchievementRewardCommand, "", NULL },
400 { "areatrigger_involvedrelation",SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestAreaTriggersCommand, "", NULL },
401 { "areatrigger_tavern", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAreaTriggerTavernCommand, "", NULL },
402 { "areatrigger_teleport", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAreaTriggerTeleportCommand, "", NULL },
403 { "command", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCommandCommand, "", NULL },
404 { "creature_ai_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadEventAIScriptsCommand, "", NULL },
405 { "creature_ai_summons", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadEventAISummonsCommand, "", NULL },
406 { "creature_ai_texts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadEventAITextsCommand, "", NULL },
407 { "creature_involvedrelation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureQuestInvRelationsCommand,"",NULL },
408 { "creature_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesCreatureCommand, "", NULL },
409 { "creature_questrelation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureQuestRelationsCommand, "", NULL },
410 { "db_script_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadDbScriptStringCommand, "", NULL },
411 { "disenchant_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesDisenchantCommand, "", NULL },
412 { "event_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadEventScriptsCommand, "", NULL },
413 { "fishing_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesFishingCommand, "", NULL },
414 { "game_graveyard_zone", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGameGraveyardZoneCommand, "", NULL },
415 { "game_tele", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGameTeleCommand, "", NULL },
416 { "gameobject_involvedrelation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGOQuestInvRelationsCommand, "", NULL },
417 { "gameobject_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesGameobjectCommand, "", NULL },
418 { "gameobject_questrelation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGOQuestRelationsCommand, "", NULL },
419 { "gameobject_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGameObjectScriptsCommand, "", NULL },
420 { "item_enchantment_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadItemEnchantementsCommand, "", NULL },
421 { "item_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesItemCommand, "", NULL },
422 { "item_required_target", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadItemRequiredTragetCommand, "", NULL },
423 { "locales_achievement_reward", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesAchievementRewardCommand,"", NULL },
424 { "locales_creature", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesCreatureCommand, "", NULL },
425 { "locales_gameobject", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesGameobjectCommand, "", NULL },
426 { "locales_item", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesItemCommand, "", NULL },
427 { "locales_npc_text", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesNpcTextCommand, "", NULL },
428 { "locales_page_text", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesPageTextCommand, "", NULL },
429 { "locales_points_of_interest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesPointsOfInterestCommand, "", NULL },
430 { "locales_quest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesQuestCommand, "", NULL },
431 { "mangos_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadMangosStringCommand, "", NULL },
432 { "milling_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesMillingCommand, "", NULL },
433 { "npc_gossip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcGossipCommand, "", NULL },
434 { "npc_option", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcOptionCommand, "", NULL },
435 { "npc_spellclick_spells", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellClickSpellsCommand, "",NULL},
436 { "npc_trainer", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcTrainerCommand, "", NULL },
437 { "npc_vendor", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcVendorCommand, "", NULL },
438 { "page_text", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadPageTextsCommand, "", NULL },
439 { "pickpocketing_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesPickpocketingCommand,"",NULL},
440 { "points_of_interest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadPointsOfInterestCommand, "",NULL},
441 { "prospecting_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesProspectingCommand,"", NULL },
442 { "quest_end_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestEndScriptsCommand, "", NULL },
443 { "quest_mail_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesQuestMailCommand, "", NULL },
444 { "quest_start_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestStartScriptsCommand, "", NULL },
445 { "quest_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestTemplateCommand, "", NULL },
446 { "reference_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesReferenceCommand, "", NULL },
447 { "reserved_name", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadReservedNameCommand, "", NULL },
448 { "skill_discovery_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSkillDiscoveryTemplateCommand, "", NULL },
449 { "skill_extra_item_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSkillExtraItemTemplateCommand, "", NULL },
450 { "skill_fishing_base_level", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSkillFishingBaseLevelCommand, "", NULL },
451 { "skinning_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesSkinningCommand, "", NULL },
452 { "spell_area", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellAreaCommand, "", NULL },
453 { "spell_bonus_data", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellBonusesCommand, "", NULL },
454 { "spell_chain", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellChainCommand, "", NULL },
455 { "spell_elixir", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellElixirCommand, "", NULL },
456 { "spell_learn_spell", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellLearnSpellCommand, "", NULL },
457 { "spell_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesSpellCommand, "", NULL },
458 { "spell_pet_auras", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellPetAurasCommand, "", NULL },
459 { "spell_proc_event", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellProcEventCommand, "", NULL },
460 { "spell_proc_item_enchant", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellProcItemEnchantCommand, "", NULL },
461 { "spell_script_target", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellScriptTargetCommand, "", NULL },
462 { "spell_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellScriptsCommand, "", NULL },
463 { "spell_target_position", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellTargetPositionCommand, "", NULL },
464 { "spell_threats", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellThreatsCommand, "", NULL },
466 { NULL, 0, false, NULL, "", NULL }
469 static ChatCommand resetCommandTable[] =
471 { "achievements", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetAchievementsCommand, "", NULL },
472 { "honor", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetHonorCommand, "", NULL },
473 { "level", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetLevelCommand, "", NULL },
474 { "spells", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetSpellsCommand, "", NULL },
475 { "stats", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetStatsCommand, "", NULL },
476 { "talents", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetTalentsCommand, "", NULL },
477 { "all", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetAllCommand, "", NULL },
478 { NULL, 0, false, NULL, "", NULL }
481 static ChatCommand sendCommandTable[] =
483 { "items", SEC_ADMINISTRATOR, true, &ChatHandler::HandleSendItemsCommand, "", NULL },
484 { "mail", SEC_MODERATOR, true, &ChatHandler::HandleSendMailCommand, "", NULL },
485 { "message", SEC_ADMINISTRATOR, true, &ChatHandler::HandleSendMessageCommand, "", NULL },
486 { "money", SEC_ADMINISTRATOR, true, &ChatHandler::HandleSendMoneyCommand, "", NULL },
487 { NULL, 0, false, NULL, "", NULL }
490 static ChatCommand serverIdleRestartCommandTable[] =
492 { "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL },
493 { "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerIdleRestartCommand, "", NULL },
494 { NULL, 0, false, NULL, "", NULL }
497 static ChatCommand serverIdleShutdownCommandTable[] =
499 { "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL },
500 { "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerIdleShutDownCommand, "", NULL },
501 { NULL, 0, false, NULL, "", NULL }
504 static ChatCommand serverRestartCommandTable[] =
506 { "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL },
507 { "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerRestartCommand, "", NULL },
508 { NULL, 0, false, NULL, "", NULL }
511 static ChatCommand serverShutdownCommandTable[] =
513 { "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL },
514 { "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCommand, "", NULL },
515 { NULL, 0, false, NULL, "", NULL }
518 static ChatCommand serverSetCommandTable[] =
520 { "loglevel", SEC_CONSOLE, true, &ChatHandler::HandleServerSetLogLevelCommand, "", NULL },
521 { "motd", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerSetMotdCommand, "", NULL },
522 { NULL, 0, false, NULL, "", NULL }
525 static ChatCommand serverCommandTable[] =
527 { "corpses", SEC_GAMEMASTER, true, &ChatHandler::HandleServerCorpsesCommand, "", NULL },
528 { "exit", SEC_CONSOLE, true, &ChatHandler::HandleServerExitCommand, "", NULL },
529 { "idlerestart", SEC_ADMINISTRATOR, true, NULL, "", serverIdleRestartCommandTable },
530 { "idleshutdown", SEC_ADMINISTRATOR, true, NULL, "", serverShutdownCommandTable },
531 { "info", SEC_PLAYER, true, &ChatHandler::HandleServerInfoCommand, "", NULL },
532 { "motd", SEC_PLAYER, true, &ChatHandler::HandleServerMotdCommand, "", NULL },
533 { "plimit", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerPLimitCommand, "", NULL },
534 { "restart", SEC_ADMINISTRATOR, true, NULL, "", serverRestartCommandTable },
535 { "shutdown", SEC_ADMINISTRATOR, true, NULL, "", serverShutdownCommandTable },
536 { "set", SEC_ADMINISTRATOR, true, NULL, "", serverSetCommandTable },
537 { NULL, 0, false, NULL, "", NULL }
540 static ChatCommand teleCommandTable[] =
542 { "add", SEC_ADMINISTRATOR, false, &ChatHandler::HandleTeleAddCommand, "", NULL },
543 { "del", SEC_ADMINISTRATOR, true, &ChatHandler::HandleTeleDelCommand, "", NULL },
544 { "name", SEC_MODERATOR, true, &ChatHandler::HandleTeleNameCommand, "", NULL },
545 { "group", SEC_MODERATOR, false, &ChatHandler::HandleTeleGroupCommand, "", NULL },
546 { "", SEC_MODERATOR, false, &ChatHandler::HandleTeleCommand, "", NULL },
547 { NULL, 0, false, NULL, "", NULL }
550 static ChatCommand unbanCommandTable[] =
552 { "account", SEC_ADMINISTRATOR, true, &ChatHandler::HandleUnBanAccountCommand, "", NULL },
553 { "character", SEC_ADMINISTRATOR, true, &ChatHandler::HandleUnBanCharacterCommand, "", NULL },
554 { "ip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleUnBanIPCommand, "", NULL },
555 { NULL, 0, false, NULL, "", NULL }
558 static ChatCommand wpCommandTable[] =
560 { "show", SEC_GAMEMASTER, false, &ChatHandler::HandleWpShowCommand, "", NULL },
561 { "add", SEC_GAMEMASTER, false, &ChatHandler::HandleWpAddCommand, "", NULL },
562 { "modify", SEC_GAMEMASTER, false, &ChatHandler::HandleWpModifyCommand, "", NULL },
563 { "export", SEC_ADMINISTRATOR, false, &ChatHandler::HandleWpExportCommand, "", NULL },
564 { "import", SEC_ADMINISTRATOR, false, &ChatHandler::HandleWpImportCommand, "", NULL },
565 { NULL, 0, false, NULL, "", NULL }
568 static ChatCommand commandTable[] =
570 { "account", SEC_PLAYER, true, NULL, "", accountCommandTable },
571 { "gm", SEC_MODERATOR, true, NULL, "", gmCommandTable },
572 { "npc", SEC_MODERATOR, false, NULL, "", npcCommandTable },
573 { "go", SEC_MODERATOR, false, NULL, "", goCommandTable },
574 { "learn", SEC_MODERATOR, false, NULL, "", learnCommandTable },
575 { "modify", SEC_MODERATOR, false, NULL, "", modifyCommandTable },
576 { "debug", SEC_MODERATOR, true, NULL, "", debugCommandTable },
577 { "tele", SEC_MODERATOR, true, NULL, "", teleCommandTable },
578 { "character", SEC_GAMEMASTER, false, NULL, "", characterCommandTable},
579 { "event", SEC_GAMEMASTER, false, NULL, "", eventCommandTable },
580 { "gobject", SEC_GAMEMASTER, false, NULL, "", gobjectCommandTable },
581 { "honor", SEC_GAMEMASTER, false, NULL, "", honorCommandTable },
582 { "wp", SEC_GAMEMASTER, false, NULL, "", wpCommandTable },
583 { "quest", SEC_ADMINISTRATOR, false, NULL, "", questCommandTable },
584 { "reload", SEC_ADMINISTRATOR, true, NULL, "", reloadCommandTable },
585 { "list", SEC_ADMINISTRATOR, true, NULL, "", listCommandTable },
586 { "lookup", SEC_ADMINISTRATOR, true, NULL, "", lookupCommandTable },
587 { "pdump", SEC_ADMINISTRATOR, true, NULL, "", pdumpCommandTable },
588 { "guild", SEC_ADMINISTRATOR, true, NULL, "", guildCommandTable },
589 { "cast", SEC_ADMINISTRATOR, false, NULL, "", castCommandTable },
590 { "reset", SEC_ADMINISTRATOR, true, NULL, "", resetCommandTable },
591 { "instance", SEC_ADMINISTRATOR, true, NULL, "", instanceCommandTable },
592 { "server", SEC_ADMINISTRATOR, true, NULL, "", serverCommandTable },
594 { "aura", SEC_ADMINISTRATOR, false, &ChatHandler::HandleAuraCommand, "", NULL },
595 { "unaura", SEC_ADMINISTRATOR, false, &ChatHandler::HandleUnAuraCommand, "", NULL },
596 { "announce", SEC_MODERATOR, true, &ChatHandler::HandleAnnounceCommand, "", NULL },
597 { "notify", SEC_MODERATOR, true, &ChatHandler::HandleNotifyCommand, "", NULL },
598 { "goname", SEC_MODERATOR, false, &ChatHandler::HandleGonameCommand, "", NULL },
599 { "namego", SEC_MODERATOR, false, &ChatHandler::HandleNamegoCommand, "", NULL },
600 { "groupgo", SEC_MODERATOR, false, &ChatHandler::HandleGroupgoCommand, "", NULL },
601 { "commands", SEC_PLAYER, true, &ChatHandler::HandleCommandsCommand, "", NULL },
602 { "demorph", SEC_GAMEMASTER, false, &ChatHandler::HandleDeMorphCommand, "", NULL },
603 { "die", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDieCommand, "", NULL },
604 { "revive", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReviveCommand, "", NULL },
605 { "dismount", SEC_PLAYER, false, &ChatHandler::HandleDismountCommand, "", NULL },
606 { "gps", SEC_MODERATOR, false, &ChatHandler::HandleGPSCommand, "", NULL },
607 { "guid", SEC_GAMEMASTER, false, &ChatHandler::HandleGUIDCommand, "", NULL },
608 { "help", SEC_PLAYER, true, &ChatHandler::HandleHelpCommand, "", NULL },
609 { "itemmove", SEC_GAMEMASTER, false, &ChatHandler::HandleItemMoveCommand, "", NULL },
610 { "cooldown", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCooldownCommand, "", NULL },
611 { "unlearn", SEC_ADMINISTRATOR, false, &ChatHandler::HandleUnLearnCommand, "", NULL },
612 { "distance", SEC_ADMINISTRATOR, false, &ChatHandler::HandleGetDistanceCommand, "", NULL },
613 { "recall", SEC_MODERATOR, false, &ChatHandler::HandleRecallCommand, "", NULL },
614 { "save", SEC_PLAYER, false, &ChatHandler::HandleSaveCommand, "", NULL },
615 { "saveall", SEC_MODERATOR, true, &ChatHandler::HandleSaveAllCommand, "", NULL },
616 { "kick", SEC_GAMEMASTER, true, &ChatHandler::HandleKickPlayerCommand, "", NULL },
617 { "ban", SEC_ADMINISTRATOR, true, NULL, "", banCommandTable },
618 { "unban", SEC_ADMINISTRATOR, true, NULL, "", unbanCommandTable },
619 { "baninfo", SEC_ADMINISTRATOR, false, NULL, "", baninfoCommandTable },
620 { "banlist", SEC_ADMINISTRATOR, true, NULL, "", banlistCommandTable },
621 { "start", SEC_PLAYER, false, &ChatHandler::HandleStartCommand, "", NULL },
622 { "taxicheat", SEC_MODERATOR, false, &ChatHandler::HandleTaxiCheatCommand, "", NULL },
623 { "linkgrave", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLinkGraveCommand, "", NULL },
624 { "neargrave", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNearGraveCommand, "", NULL },
625 { "explorecheat", SEC_ADMINISTRATOR, false, &ChatHandler::HandleExploreCheatCommand, "", NULL },
626 { "hover", SEC_ADMINISTRATOR, false, &ChatHandler::HandleHoverCommand, "", NULL },
627 { "levelup", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLevelUpCommand, "", NULL },
628 { "showarea", SEC_ADMINISTRATOR, false, &ChatHandler::HandleShowAreaCommand, "", NULL },
629 { "hidearea", SEC_ADMINISTRATOR, false, &ChatHandler::HandleHideAreaCommand, "", NULL },
630 { "additem", SEC_ADMINISTRATOR, false, &ChatHandler::HandleAddItemCommand, "", NULL },
631 { "additemset", SEC_ADMINISTRATOR, false, &ChatHandler::HandleAddItemSetCommand, "", NULL },
632 { "bank", SEC_ADMINISTRATOR, false, &ChatHandler::HandleBankCommand, "", NULL },
633 { "wchange", SEC_ADMINISTRATOR, false, &ChatHandler::HandleChangeWeather, "", NULL },
634 { "ticket", SEC_GAMEMASTER, true, &ChatHandler::HandleTicketCommand, "", NULL },
635 { "delticket", SEC_GAMEMASTER, true, &ChatHandler::HandleDelTicketCommand, "", NULL },
636 { "maxskill", SEC_ADMINISTRATOR, false, &ChatHandler::HandleMaxSkillCommand, "", NULL },
637 { "setskill", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSetSkillCommand, "", NULL },
638 { "whispers", SEC_MODERATOR, false, &ChatHandler::HandleWhispersCommand, "", NULL },
639 { "pinfo", SEC_GAMEMASTER, true, &ChatHandler::HandlePInfoCommand, "", NULL },
640 { "respawn", SEC_ADMINISTRATOR, false, &ChatHandler::HandleRespawnCommand, "", NULL },
641 { "send", SEC_MODERATOR, true, NULL, "", sendCommandTable },
642 { "loadscripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLoadScriptsCommand, "", NULL },
643 { "mute", SEC_MODERATOR, true, &ChatHandler::HandleMuteCommand, "", NULL },
644 { "unmute", SEC_MODERATOR, true, &ChatHandler::HandleUnmuteCommand, "", NULL },
645 { "movegens", SEC_ADMINISTRATOR, false, &ChatHandler::HandleMovegensCommand, "", NULL },
646 { "cometome", SEC_ADMINISTRATOR, false, &ChatHandler::HandleComeToMeCommand, "", NULL },
647 { "damage", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDamageCommand, "", NULL },
648 { "combatstop", SEC_GAMEMASTER, false, &ChatHandler::HandleCombatStopCommand, "", NULL },
649 { "flusharenapoints",SEC_ADMINISTRATOR, false, &ChatHandler::HandleFlushArenaPointsCommand, "", NULL },
650 { "repairitems", SEC_GAMEMASTER, true, &ChatHandler::HandleRepairitemsCommand, "", NULL },
651 { "waterwalk", SEC_GAMEMASTER, false, &ChatHandler::HandleWaterwalkCommand, "", NULL },
653 { NULL, 0, false, NULL, "", NULL }
656 if(load_command_table)
658 load_command_table = false;
660 QueryResult *result = WorldDatabase.Query("SELECT name,security,help FROM command");
661 if (result)
665 Field *fields = result->Fetch();
666 std::string name = fields[0].GetCppString();
668 SetDataForCommandInTable(commandTable, name.c_str(), fields[1].GetUInt16(), fields[2].GetCppString(), name);
670 } while(result->NextRow());
671 delete result;
675 return commandTable;
678 const char *ChatHandler::GetMangosString(int32 entry) const
680 return m_session->GetMangosString(entry);
683 bool ChatHandler::isAvailable(ChatCommand const& cmd) const
685 // check security level only for simple command (without child commands)
686 return m_session->GetSecurity() >= cmd.SecurityLevel;
689 bool ChatHandler::HasLowerSecurity(Player* target, uint64 guid, bool strong)
691 WorldSession* target_session = NULL;
692 uint32 target_account = 0;
694 if (target)
695 target_session = target->GetSession();
696 else if (guid)
697 target_account = objmgr.GetPlayerAccountIdByGUID(guid);
699 if(!target_session && !target_account)
701 SendSysMessage(LANG_PLAYER_NOT_FOUND);
702 SetSentErrorMessage(true);
703 return true;
706 return HasLowerSecurityAccount(target_session,target_account,strong);
709 bool ChatHandler::HasLowerSecurityAccount(WorldSession* target, uint32 target_account, bool strong)
711 uint32 target_sec;
713 // allow everything from console and RA console
714 if (!m_session)
715 return false;
717 // ignore only for non-players for non strong checks (when allow apply command at least to same sec level)
718 if (m_session->GetSecurity() > SEC_PLAYER && !strong && !sWorld.getConfig(CONFIG_GM_LOWER_SECURITY))
719 return false;
721 if (target)
722 target_sec = target->GetSecurity();
723 else if (target_account)
724 target_sec = accmgr.GetSecurity(target_account);
725 else
726 return true; // caller must report error for (target==NULL && target_account==0)
728 if (m_session->GetSecurity() < target_sec || (strong && m_session->GetSecurity() <= target_sec))
730 SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
731 SetSentErrorMessage(true);
732 return true;
735 return false;
738 bool ChatHandler::hasStringAbbr(const char* name, const char* part)
740 // non "" command
741 if( *name )
743 // "" part from non-"" command
744 if( !*part )
745 return false;
747 for(;;)
749 if( !*part )
750 return true;
751 else if( !*name )
752 return false;
753 else if( tolower( *name ) != tolower( *part ) )
754 return false;
755 ++name; ++part;
758 // allow with any for ""
760 return true;
763 void ChatHandler::SendSysMessage(const char *str)
765 WorldPacket data;
767 // need copy to prevent corruption by strtok call in LineFromMessage original string
768 char* buf = strdup(str);
769 char* pos = buf;
771 while(char* line = LineFromMessage(pos))
773 FillSystemMessageData(&data, line);
774 m_session->SendPacket(&data);
777 free(buf);
780 void ChatHandler::SendGlobalSysMessage(const char *str)
782 // Chat output
783 WorldPacket data;
785 // need copy to prevent corruption by strtok call in LineFromMessage original string
786 char* buf = strdup(str);
787 char* pos = buf;
789 while(char* line = LineFromMessage(pos))
791 FillSystemMessageData(&data, line);
792 sWorld.SendGlobalMessage(&data);
795 free(buf);
798 void ChatHandler::SendSysMessage(int32 entry)
800 SendSysMessage(GetMangosString(entry));
803 void ChatHandler::PSendSysMessage(int32 entry, ...)
805 const char *format = GetMangosString(entry);
806 va_list ap;
807 char str [2048];
808 va_start(ap, entry);
809 vsnprintf(str,2048,format, ap );
810 va_end(ap);
811 SendSysMessage(str);
814 void ChatHandler::PSendSysMessage(const char *format, ...)
816 va_list ap;
817 char str [2048];
818 va_start(ap, format);
819 vsnprintf(str,2048,format, ap );
820 va_end(ap);
821 SendSysMessage(str);
824 bool ChatHandler::ExecuteCommandInTable(ChatCommand *table, const char* text, const std::string& fullcmd)
826 char const* oldtext = text;
827 std::string cmd = "";
829 while (*text != ' ' && *text != '\0')
831 cmd += *text;
832 ++text;
835 while (*text == ' ') ++text;
837 for(uint32 i = 0; table[i].Name != NULL; ++i)
839 if( !hasStringAbbr(table[i].Name, cmd.c_str()) )
840 continue;
842 // select subcommand from child commands list
843 if(table[i].ChildCommands != NULL)
845 if(!ExecuteCommandInTable(table[i].ChildCommands, text, fullcmd))
847 if(text && text[0] != '\0')
848 SendSysMessage(LANG_NO_SUBCMD);
849 else
850 SendSysMessage(LANG_CMD_SYNTAX);
852 ShowHelpForCommand(table[i].ChildCommands,text);
855 return true;
858 // must be available and have handler
859 if(!table[i].Handler || !isAvailable(table[i]))
860 continue;
862 SetSentErrorMessage(false);
863 // table[i].Name == "" is special case: send original command to handler
864 if((this->*(table[i].Handler))(strlen(table[i].Name)!=0 ? text : oldtext))
866 if(table[i].SecurityLevel > SEC_PLAYER)
868 // chat case
869 if(m_session)
871 Player* p = m_session->GetPlayer();
872 uint64 sel_guid = p->GetSelection();
873 sLog.outCommand(m_session->GetAccountId(),"Command: %s [Player: %s (Account: %u) X: %f Y: %f Z: %f Map: %u Selected: %s (GUID: %u)]",
874 fullcmd.c_str(),p->GetName(),m_session->GetAccountId(),p->GetPositionX(),p->GetPositionY(),p->GetPositionZ(),p->GetMapId(),
875 GetLogNameForGuid(sel_guid),GUID_LOPART(sel_guid));
879 // some commands have custom error messages. Don't send the default one in these cases.
880 else if(!sentErrorMessage)
882 if(!table[i].Help.empty())
883 SendSysMessage(table[i].Help.c_str());
884 else
885 SendSysMessage(LANG_CMD_SYNTAX);
888 return true;
891 return false;
894 bool ChatHandler::SetDataForCommandInTable(ChatCommand *table, const char* text, uint32 security, std::string const& help, std::string const& fullcommand )
896 std::string cmd = "";
898 while (*text != ' ' && *text != '\0')
900 cmd += *text;
901 ++text;
904 while (*text == ' ') ++text;
906 for(uint32 i = 0; table[i].Name != NULL; i++)
908 // for data fill use full explicit command names
909 if( table[i].Name != cmd )
910 continue;
912 // select subcommand from child commands list (including "")
913 if(table[i].ChildCommands != NULL)
915 if(SetDataForCommandInTable(table[i].ChildCommands, text, security, help, fullcommand))
916 return true;
917 else if(*text)
918 return false;
920 // fail with "" subcommands, then use normal level up command instead
922 // expected subcommand by full name DB content
923 else if(*text)
925 sLog.outErrorDb("Table `command` have unexpected subcommand '%s' in command '%s', skip.",text,fullcommand.c_str());
926 return false;
929 if(table[i].SecurityLevel != security)
930 sLog.outDetail("Table `command` overwrite for command '%s' default security (%u) by %u",fullcommand.c_str(),table[i].SecurityLevel,security);
932 table[i].SecurityLevel = security;
933 table[i].Help = help;
934 return true;
937 // in case "" command let process by caller
938 if(!cmd.empty())
940 if(table==getCommandTable())
941 sLog.outErrorDb("Table `command` have not existed command '%s', skip.",cmd.c_str());
942 else
943 sLog.outErrorDb("Table `command` have not existed subcommand '%s' in command '%s', skip.",cmd.c_str(),fullcommand.c_str());
946 return false;
949 int ChatHandler::ParseCommands(const char* text)
951 ASSERT(text);
952 ASSERT(*text);
954 //if(m_session->GetSecurity() == 0)
955 // return 0;
957 /// chat case (.command or !command format)
958 if (m_session)
960 if(text[0] != '!' && text[0] != '.')
961 return 0;
964 /// ignore single . and ! in line
965 if (strlen(text) < 2)
966 return 0;
968 /// ignore messages staring from many dots.
969 if ((text[0] == '.' && text[1] == '.') || (text[0] == '!' && text[1] == '!'))
970 return 0;
972 /// skip first . or ! (in console allowed use command with . and ! and without its)
973 if (text[0] == '!' || text[0] == '.')
974 ++text;
976 std::string fullcmd = text; // original `text` can't be used. It content destroyed in command code processing.
978 if (!ExecuteCommandInTable(getCommandTable(), text, fullcmd))
979 SendSysMessage(LANG_NO_CMD);
981 return 1;
984 bool ChatHandler::isValidChatMessage(const char* message)
988 valid examples:
989 |cffa335ee|Hitem:812:0:0:0:0:0:0:0:70|h[Glowing Brightwood Staff]|h|r
990 |cff808080|Hquest:2278:47|h[The Platinum Discs]|h|r
991 |cffffd000|Htrade:4037:1:150:1:6AAAAAAAAAAAAAAAAAAAAAAOAADAAAAAAAAAAAAAAAAIAAAAAAAAA|h[Engineering]|h|r
992 |cff4e96f7|Htalent:2232:-1|h[Taste for Blood]|h|r
993 |cff71d5ff|Hspell:21563|h[Command]|h|r
994 |cffffd000|Henchant:3919|h[Engineering: Rough Dynamite]|h|r
995 |cffffff00|Hachievement:546:0000000000000001:0:0:0:-1:0:0:0:0|h[Safe Deposit]|h|r
996 |cff66bbff|Hglyph:21:762|h[Glyph of Bladestorm]|h|r
998 | will be escaped to ||
1001 if(strlen(message) > 255)
1002 return false;
1004 const char validSequence[6] = "cHhhr";
1005 const char* validSequenceIterator = validSequence;
1007 // more simple checks
1008 if (sWorld.getConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY) < 3)
1010 const std::string validCommands = "cHhr|";
1012 while(*message)
1014 // find next pipe command
1015 message = strchr(message, '|');
1017 if(!message)
1018 return true;
1020 ++message;
1021 char commandChar = *message;
1022 if(validCommands.find(commandChar) == std::string::npos)
1023 return false;
1025 ++message;
1026 // validate sequence
1027 if(sWorld.getConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY) == 2)
1029 if(commandChar == *validSequenceIterator)
1031 if (validSequenceIterator == validSequence+4)
1032 validSequenceIterator = validSequence;
1033 else
1034 ++validSequenceIterator;
1036 else
1037 return false;
1040 return true;
1043 std::istringstream reader(message);
1044 char buffer[256];
1046 uint32 color;
1048 ItemPrototype const* linkedItem;
1049 Quest const* linkedQuest;
1050 SpellEntry const *linkedSpell;
1051 AchievementEntry const* linkedAchievement;
1053 while(!reader.eof())
1055 if (validSequence == validSequenceIterator)
1057 linkedItem = NULL;
1058 linkedQuest = NULL;
1059 linkedSpell = NULL;
1060 linkedAchievement = NULL;
1062 reader.ignore(255, '|');
1064 else if(reader.get() != '|')
1066 #ifdef MANGOS_DEBUG
1067 sLog.outBasic("ChatHandler::isValidChatMessage sequence aborted unexpectedly");
1068 #endif
1069 return false;
1072 // pipe has always to be followed by at least one char
1073 if ( reader.peek() == '\0')
1075 #ifdef MANGOS_DEBUG
1076 sLog.outBasic("ChatHandler::isValidChatMessage pipe followed by \\0");
1077 #endif
1078 return false;
1081 // no further pipe commands
1082 if (reader.eof())
1083 break;
1085 char commandChar;
1086 reader >> commandChar;
1088 // | in normal messages is escaped by ||
1089 if (commandChar != '|')
1091 if(commandChar == *validSequenceIterator)
1093 if (validSequenceIterator == validSequence+4)
1094 validSequenceIterator = validSequence;
1095 else
1096 ++validSequenceIterator;
1098 else
1100 #ifdef MANGOS_DEBUG
1101 sLog.outBasic("ChatHandler::isValidChatMessage invalid sequence, expected %c but got %c", *validSequenceIterator, commandChar);
1102 #endif
1103 return false;
1106 else if(validSequence != validSequenceIterator)
1108 // no escaped pipes in sequences
1109 #ifdef MANGOS_DEBUG
1110 sLog.outBasic("ChatHandler::isValidChatMessage got escaped pipe in sequence");
1111 #endif
1112 return false;
1115 switch (commandChar)
1117 case 'c':
1118 color = 0;
1119 // validate color, expect 8 hex chars
1120 for(int i=0; i<8; i++)
1122 char c;
1123 reader >> c;
1124 if(!c)
1126 #ifdef MANGOS_DEBUG
1127 sLog.outBasic("ChatHandler::isValidChatMessage got \\0 while reading color in |c command");
1128 #endif
1129 return false;
1132 color <<= 4;
1133 // check for hex char
1134 if(c >= '0' && c <='9')
1136 color |= c-'0';
1137 continue;
1139 if(c >= 'a' && c <='f')
1141 color |= 10+c-'a';
1142 continue;
1144 #ifdef MANGOS_DEBUG
1145 sLog.outBasic("ChatHandler::isValidChatMessage got non hex char '%c' while reading color", c);
1146 #endif
1147 return false;
1149 break;
1150 case 'H':
1151 // read chars up to colon = link type
1152 reader.getline(buffer, 256, ':');
1154 if (strcmp(buffer, "item") == 0)
1156 // read item entry
1157 reader.getline(buffer, 256, ':');
1159 linkedItem= objmgr.GetItemPrototype(atoi(buffer));
1160 if(!linkedItem)
1162 #ifdef MANGOS_DEBUG
1163 sLog.outBasic("ChatHandler::isValidChatMessage got invalid itemID %u in |item command", atoi(buffer));
1164 #endif
1165 return false;
1168 if (color != ItemQualityColors[linkedItem->Quality])
1170 #ifdef MANGOS_DEBUG
1171 sLog.outBasic("ChatHandler::isValidChatMessage linked item has color %u, but user claims %u", ItemQualityColors[linkedItem->Quality],
1172 color);
1173 #endif
1174 return false;
1177 char c = reader.peek();
1179 // ignore enchants etc.
1180 while ((c >= '0' && c <= '9') || c== ':')
1182 reader.ignore(1);
1183 c = reader.peek();
1186 else if(strcmp(buffer, "quest") == 0)
1188 // no color check for questlinks, each client will adapt it anyway
1189 uint32 questid= 0;
1190 // read questid
1191 char c = reader.peek();
1192 while(c >='0' && c<='9')
1194 reader.ignore(1);
1195 questid *= 10;
1196 questid += c-'0';
1197 c = reader.peek();
1200 linkedQuest = objmgr.GetQuestTemplate(questid);
1202 if(!linkedQuest)
1204 #ifdef MANOGS_DEBUG
1205 sLog.outBasic("ChatHandler::isValidChatMessage Questtemplate %u not found", questid);
1206 #endif
1207 return false;
1209 c = reader.peek();
1210 // level
1211 while(c !='|' && c!='\0')
1213 reader.ignore(1);
1214 c = reader.peek();
1217 else if(strcmp(buffer, "trade") == 0)
1219 if(color != CHAT_LINK_COLOR_TRADE)
1220 return false;
1222 // read spell entry
1223 reader.getline(buffer, 256, ':');
1224 linkedSpell = sSpellStore.LookupEntry(atoi(buffer));
1225 if(!linkedSpell)
1226 return false;
1228 char c = reader.peek();
1229 // base64 encoded stuff
1230 while(c !='|' && c!='\0')
1232 reader.ignore(1);
1233 c = reader.peek();
1236 else if(strcmp(buffer, "talent") == 0)
1238 // talent links are always supposed to be blue
1239 if(color != CHAT_LINK_COLOR_TALENT)
1240 return false;
1242 // read talent entry
1243 reader.getline(buffer, 256, ':');
1244 TalentEntry const *talentInfo = sTalentStore.LookupEntry(atoi(buffer));
1245 if(!talentInfo)
1246 return false;
1248 linkedSpell = sSpellStore.LookupEntry(talentInfo->RankID[0]);
1249 if(!linkedSpell)
1250 return false;
1252 char c = reader.peek();
1253 // skillpoints? whatever, drop it
1254 while(c !='|' && c!='\0')
1256 reader.ignore(1);
1257 c = reader.peek();
1260 else if(strcmp(buffer, "spell") == 0)
1262 if(color != CHAT_LINK_COLOR_SPELL)
1263 return false;
1265 uint32 spellid = 0;
1266 // read spell entry
1267 char c = reader.peek();
1268 while(c >='0' && c<='9')
1270 reader.ignore(1);
1271 spellid *= 10;
1272 spellid += c-'0';
1273 c = reader.peek();
1275 linkedSpell = sSpellStore.LookupEntry(spellid);
1276 if(!linkedSpell)
1277 return false;
1279 else if(strcmp(buffer, "enchant") == 0)
1281 if(color != CHAT_LINK_COLOR_ENCHANT)
1282 return false;
1284 uint32 spellid = 0;
1285 // read spell entry
1286 char c = reader.peek();
1287 while(c >='0' && c<='9')
1289 reader.ignore(1);
1290 spellid *= 10;
1291 spellid += c-'0';
1292 c = reader.peek();
1294 linkedSpell = sSpellStore.LookupEntry(spellid);
1295 if(!linkedSpell)
1296 return false;
1298 else if(strcmp(buffer, "achievement") == 0)
1300 if(color != CHAT_LINK_COLOR_ACHIEVEMENT)
1301 return false;
1302 reader.getline(buffer, 256, ':');
1303 uint32 achievementId = atoi(buffer);
1304 linkedAchievement = sAchievementStore.LookupEntry(achievementId);
1306 if(!linkedAchievement)
1307 return false;
1309 char c = reader.peek();
1310 // skip progress
1311 while(c !='|' && c!='\0')
1313 reader.ignore(1);
1314 c = reader.peek();
1317 else if(strcmp(buffer, "glyph") == 0)
1319 if(color != CHAT_LINK_COLOR_GLYPH)
1320 return false;
1322 // first id is slot, drop it
1323 reader.getline(buffer, 256, ':');
1324 uint32 glyphId = 0;
1325 char c = reader.peek();
1326 while(c>='0' && c <='9')
1328 glyphId *= 10;
1329 glyphId += c-'0';
1330 reader.ignore(1);
1331 c = reader.peek();
1333 GlyphPropertiesEntry const* glyph = sGlyphPropertiesStore.LookupEntry(glyphId);
1334 if (!glyph)
1335 return false;
1337 linkedSpell = sSpellStore.LookupEntry(glyph->SpellId);
1339 if (!linkedSpell)
1340 return false;
1342 else
1344 #ifdef MANGOS_DEBUG
1345 sLog.outBasic("ChatHandler::isValidChatMessage user sent unsupported link type '%s'", buffer);
1346 #endif
1347 return false;
1349 break;
1350 case 'h':
1351 // if h is next element in sequence, this one must contain the linked text :)
1352 if (*validSequenceIterator == 'h')
1354 // links start with '['
1355 if (reader.get() != '[')
1357 #ifdef MANGOS_DEBUG
1358 sLog.outBasic("ChatHandler::isValidChatMessage link caption doesn't start with '['");
1359 #endif
1360 return false;
1362 reader.getline(buffer, 256, ']');
1364 // verify the link name
1365 if (linkedSpell)
1367 // spells with that flag have a prefix of "$PROFESSION: "
1368 if (linkedSpell->Attributes & SPELL_ATTR_TRADESPELL)
1370 // lookup skillid
1371 SkillLineAbilityMapBounds bounds = spellmgr.GetSkillLineAbilityMapBounds(linkedSpell->Id);
1372 if (bounds.first == bounds.second)
1374 return false;
1377 SkillLineAbilityEntry const *skillInfo = bounds.first->second;
1379 if (!skillInfo)
1381 return false;
1384 SkillLineEntry const *skillLine = sSkillLineStore.LookupEntry(skillInfo->skillId);
1385 if (!skillLine)
1387 return false;
1390 for(uint8 i=0; i<MAX_LOCALE; ++i)
1392 uint32 skillLineNameLength = strlen(skillLine->name[i]);
1393 if (skillLineNameLength > 0 && strncmp(skillLine->name[i], buffer, skillLineNameLength) == 0)
1395 // found the prefix, remove it to perform spellname validation below
1396 // -2 = strlen(": ")
1397 uint32 spellNameLength = strlen(buffer)-skillLineNameLength-2;
1398 memmove(buffer, buffer+skillLineNameLength+2, spellNameLength+1);
1402 bool foundName = false;
1403 for(uint8 i=0; i<MAX_LOCALE; ++i)
1405 if (*linkedSpell->SpellName[i] && strcmp(linkedSpell->SpellName[i], buffer) == 0)
1407 foundName = true;
1408 break;
1411 if (!foundName)
1412 return false;
1414 else if (linkedQuest)
1416 if (linkedQuest->GetTitle() != buffer)
1418 QuestLocale const *ql = objmgr.GetQuestLocale(linkedQuest->GetQuestId());
1420 if (!ql)
1422 #ifdef MANOGS_DEBUG
1423 sLog.outBasic("ChatHandler::isValidChatMessage default questname didn't match and there is no locale");
1424 #endif
1425 return false;
1428 bool foundName = false;
1429 for(uint8 i=0; i<ql->Title.size(); i++)
1431 if (ql->Title[i] == buffer)
1433 foundName = true;
1434 break;
1437 if (!foundName)
1439 #ifdef MANOGS_DEBUG
1440 sLog.outBasic("ChatHandler::isValidChatMessage no quest locale title matched")
1441 #endif
1442 return false;
1446 else if(linkedItem)
1448 if (strcmp(linkedItem->Name1, buffer) != 0)
1450 ItemLocale const *il = objmgr.GetItemLocale(linkedItem->ItemId);
1452 if (!il)
1454 #ifdef MANGOS_DEBUG
1455 sLog.outBasic("ChatHandler::isValidChatMessage linked item name doesn't is wrong and there is no localization");
1456 #endif
1457 return false;
1460 bool foundName = false;
1461 for(uint8 i=0; i<il->Name.size(); ++i)
1463 if (il->Name[i] == buffer)
1465 foundName = true;
1466 break;
1469 if (!foundName)
1471 #ifdef MANGOS_DEBUG
1472 sLog.outBasic("ChatHandler::isValidChatMessage linked item name wasn't found in any localization");
1473 #endif
1474 return false;
1478 else if (linkedAchievement)
1480 bool foundName = false;
1481 for(uint8 i=0; i<MAX_LOCALE; ++i)
1483 if (*linkedAchievement->name[i] && strcmp(linkedAchievement->name[i], buffer) == 0)
1485 foundName = true;
1486 break;
1489 if (!foundName)
1490 return false;
1492 // that place should never be reached - if nothing linked has been set in |H
1493 // it will return false before
1494 else
1495 return false;
1497 break;
1498 case 'r':
1499 case '|':
1500 // no further payload
1501 break;
1502 default:
1503 #ifdef MANGOS_DEBUG
1504 sLog.outBasic("ChatHandler::isValidChatMessage got invalid command |%c", commandChar);
1505 #endif
1506 return false;
1510 // check if every opened sequence was also closed properly
1511 #ifdef MANGOS_DEBUG
1512 if(validSequence != validSequenceIterator)
1513 sLog.outBasic("ChatHandler::isValidChatMessage EOF in active sequence");
1514 #endif
1515 return validSequence == validSequenceIterator;
1518 bool ChatHandler::ShowHelpForSubCommands(ChatCommand *table, char const* cmd, char const* subcmd)
1520 std::string list;
1521 for(uint32 i = 0; table[i].Name != NULL; ++i)
1523 // must be available (ignore handler existence for show command with possibe avalable subcomands
1524 if(!isAvailable(table[i]))
1525 continue;
1527 /// for empty subcmd show all available
1528 if( *subcmd && !hasStringAbbr(table[i].Name, subcmd))
1529 continue;
1531 if(m_session)
1532 list += "\n ";
1533 else
1534 list += "\n\r ";
1536 list += table[i].Name;
1538 if(table[i].ChildCommands)
1539 list += " ...";
1542 if(list.empty())
1543 return false;
1545 if(table==getCommandTable())
1547 SendSysMessage(LANG_AVIABLE_CMD);
1548 PSendSysMessage("%s",list.c_str());
1550 else
1551 PSendSysMessage(LANG_SUBCMDS_LIST,cmd,list.c_str());
1553 return true;
1556 bool ChatHandler::ShowHelpForCommand(ChatCommand *table, const char* cmd)
1558 if(*cmd)
1560 for(uint32 i = 0; table[i].Name != NULL; ++i)
1562 // must be available (ignore handler existence for show command with possibe avalable subcomands
1563 if(!isAvailable(table[i]))
1564 continue;
1566 if( !hasStringAbbr(table[i].Name, cmd) )
1567 continue;
1569 // have subcommand
1570 char const* subcmd = (*cmd) ? strtok(NULL, " ") : "";
1572 if(table[i].ChildCommands && subcmd && *subcmd)
1574 if(ShowHelpForCommand(table[i].ChildCommands, subcmd))
1575 return true;
1578 if(!table[i].Help.empty())
1579 SendSysMessage(table[i].Help.c_str());
1581 if(table[i].ChildCommands)
1582 if(ShowHelpForSubCommands(table[i].ChildCommands,table[i].Name,subcmd ? subcmd : ""))
1583 return true;
1585 return !table[i].Help.empty();
1588 else
1590 for(uint32 i = 0; table[i].Name != NULL; ++i)
1592 // must be available (ignore handler existence for show command with possibe avalable subcomands
1593 if(!isAvailable(table[i]))
1594 continue;
1596 if(strlen(table[i].Name))
1597 continue;
1599 if(!table[i].Help.empty())
1600 SendSysMessage(table[i].Help.c_str());
1602 if(table[i].ChildCommands)
1603 if(ShowHelpForSubCommands(table[i].ChildCommands,"",""))
1604 return true;
1606 return !table[i].Help.empty();
1610 return ShowHelpForSubCommands(table,"",cmd);
1613 //Note: target_guid used only in CHAT_MSG_WHISPER_INFORM mode (in this case channelName ignored)
1614 void ChatHandler::FillMessageData( WorldPacket *data, WorldSession* session, uint8 type, uint32 language, const char *channelName, uint64 target_guid, const char *message, Unit *speaker)
1616 uint32 messageLength = (message ? strlen(message) : 0) + 1;
1618 data->Initialize(SMSG_MESSAGECHAT, 100); // guess size
1619 *data << uint8(type);
1620 if ((type != CHAT_MSG_CHANNEL && type != CHAT_MSG_WHISPER) || language == LANG_ADDON)
1621 *data << uint32(language);
1622 else
1623 *data << uint32(LANG_UNIVERSAL);
1625 switch(type)
1627 case CHAT_MSG_SAY:
1628 case CHAT_MSG_PARTY:
1629 case CHAT_MSG_RAID:
1630 case CHAT_MSG_GUILD:
1631 case CHAT_MSG_OFFICER:
1632 case CHAT_MSG_YELL:
1633 case CHAT_MSG_WHISPER:
1634 case CHAT_MSG_CHANNEL:
1635 case CHAT_MSG_RAID_LEADER:
1636 case CHAT_MSG_RAID_WARNING:
1637 case CHAT_MSG_BG_SYSTEM_NEUTRAL:
1638 case CHAT_MSG_BG_SYSTEM_ALLIANCE:
1639 case CHAT_MSG_BG_SYSTEM_HORDE:
1640 case CHAT_MSG_BATTLEGROUND:
1641 case CHAT_MSG_BATTLEGROUND_LEADER:
1642 target_guid = session ? session->GetPlayer()->GetGUID() : 0;
1643 break;
1644 case CHAT_MSG_MONSTER_SAY:
1645 case CHAT_MSG_MONSTER_PARTY:
1646 case CHAT_MSG_MONSTER_YELL:
1647 case CHAT_MSG_MONSTER_WHISPER:
1648 case CHAT_MSG_MONSTER_EMOTE:
1649 case CHAT_MSG_RAID_BOSS_WHISPER:
1650 case CHAT_MSG_RAID_BOSS_EMOTE:
1651 case CHAT_MSG_BN:
1653 *data << uint64(speaker->GetGUID());
1654 *data << uint32(0); // 2.1.0
1655 *data << uint32(strlen(speaker->GetName()) + 1);
1656 *data << speaker->GetName();
1657 uint64 listener_guid = 0;
1658 *data << uint64(listener_guid);
1659 if(listener_guid && !IS_PLAYER_GUID(listener_guid))
1661 *data << uint32(1); // string listener_name_length
1662 *data << uint8(0); // string listener_name
1664 *data << uint32(messageLength);
1665 *data << message;
1666 *data << uint8(0);
1667 return;
1669 default:
1670 if (type != CHAT_MSG_REPLY && type != CHAT_MSG_IGNORED && type != CHAT_MSG_DND && type != CHAT_MSG_AFK)
1671 target_guid = 0; // only for CHAT_MSG_WHISPER_INFORM used original value target_guid
1672 break;
1675 *data << uint64(target_guid); // there 0 for BG messages
1676 *data << uint32(0); // can be chat msg group or something
1678 if (type == CHAT_MSG_CHANNEL)
1680 ASSERT(channelName);
1681 *data << channelName;
1684 *data << uint64(target_guid);
1685 *data << uint32(messageLength);
1686 *data << message;
1687 if(session != 0 && type != CHAT_MSG_REPLY && type != CHAT_MSG_DND && type != CHAT_MSG_AFK)
1688 *data << uint8(session->GetPlayer()->chatTag());
1689 else
1690 *data << uint8(0);
1693 Player * ChatHandler::getSelectedPlayer()
1695 if(!m_session)
1696 return NULL;
1698 uint64 guid = m_session->GetPlayer()->GetSelection();
1700 if (guid == 0)
1701 return m_session->GetPlayer();
1703 return objmgr.GetPlayer(guid);
1706 Unit* ChatHandler::getSelectedUnit()
1708 if(!m_session)
1709 return NULL;
1711 uint64 guid = m_session->GetPlayer()->GetSelection();
1713 if (guid == 0)
1714 return m_session->GetPlayer();
1716 return ObjectAccessor::GetUnit(*m_session->GetPlayer(),guid);
1719 Creature* ChatHandler::getSelectedCreature()
1721 if(!m_session)
1722 return NULL;
1724 return ObjectAccessor::GetCreatureOrPetOrVehicle(*m_session->GetPlayer(),m_session->GetPlayer()->GetSelection());
1727 char* ChatHandler::extractKeyFromLink(char* text, char const* linkType, char** something1)
1729 // skip empty
1730 if(!text)
1731 return NULL;
1733 // skip speces
1734 while(*text==' '||*text=='\t'||*text=='\b')
1735 ++text;
1737 if(!*text)
1738 return NULL;
1740 // return non link case
1741 if(text[0]!='|')
1742 return strtok(text, " ");
1744 // [name] Shift-click form |color|linkType:key|h[name]|h|r
1745 // or
1746 // [name] Shift-click form |color|linkType:key:something1:...:somethingN|h[name]|h|r
1748 char* check = strtok(text, "|"); // skip color
1749 if(!check)
1750 return NULL; // end of data
1752 char* cLinkType = strtok(NULL, ":"); // linktype
1753 if(!cLinkType)
1754 return NULL; // end of data
1756 if(strcmp(cLinkType,linkType) != 0)
1758 strtok(NULL, " "); // skip link tail (to allow continue strtok(NULL,s) use after retturn from function
1759 SendSysMessage(LANG_WRONG_LINK_TYPE);
1760 return NULL;
1763 char* cKeys = strtok(NULL, "|"); // extract keys and values
1764 char* cKeysTail = strtok(NULL, "");
1766 char* cKey = strtok(cKeys, ":|"); // extract key
1767 if(something1)
1768 *something1 = strtok(NULL, ":|"); // extract something
1770 strtok(cKeysTail, "]"); // restart scan tail and skip name with possible spaces
1771 strtok(NULL, " "); // skip link tail (to allow continue strtok(NULL,s) use after return from function
1772 return cKey;
1775 char* ChatHandler::extractKeyFromLink(char* text, char const* const* linkTypes, int* found_idx, char** something1)
1777 // skip empty
1778 if(!text)
1779 return NULL;
1781 // skip speces
1782 while(*text==' '||*text=='\t'||*text=='\b')
1783 ++text;
1785 if(!*text)
1786 return NULL;
1788 // return non link case
1789 if(text[0]!='|')
1790 return strtok(text, " ");
1792 // [name] Shift-click form |color|linkType:key|h[name]|h|r
1793 // or
1794 // [name] Shift-click form |color|linkType:key:something1:...:somethingN|h[name]|h|r
1795 // or
1796 // [name] Shift-click form |linkType:key|h[name]|h|r
1798 char* tail;
1800 if(text[1]=='c')
1802 char* check = strtok(text, "|"); // skip color
1803 if(!check)
1804 return NULL; // end of data
1806 tail = strtok(NULL, ""); // tail
1808 else
1809 tail = text+1; // skip first |
1811 char* cLinkType = strtok(tail, ":"); // linktype
1812 if(!cLinkType)
1813 return NULL; // end of data
1815 for(int i = 0; linkTypes[i]; ++i)
1817 if(strcmp(cLinkType,linkTypes[i]) == 0)
1819 char* cKeys = strtok(NULL, "|"); // extract keys and values
1820 char* cKeysTail = strtok(NULL, "");
1822 char* cKey = strtok(cKeys, ":|"); // extract key
1823 if(something1)
1824 *something1 = strtok(NULL, ":|"); // extract something
1826 strtok(cKeysTail, "]"); // restart scan tail and skip name with possible spaces
1827 strtok(NULL, " "); // skip link tail (to allow continue strtok(NULL,s) use after return from function
1828 if(found_idx)
1829 *found_idx = i;
1830 return cKey;
1834 strtok(NULL, " "); // skip link tail (to allow continue strtok(NULL,s) use after return from function
1835 SendSysMessage(LANG_WRONG_LINK_TYPE);
1836 return NULL;
1839 char const *fmtstring( char const *format, ... )
1841 va_list argptr;
1842 #define MAX_FMT_STRING 32000
1843 static char temp_buffer[MAX_FMT_STRING];
1844 static char string[MAX_FMT_STRING];
1845 static int index = 0;
1846 char *buf;
1847 int len;
1849 va_start(argptr, format);
1850 vsnprintf(temp_buffer,MAX_FMT_STRING, format, argptr);
1851 va_end(argptr);
1853 len = strlen(temp_buffer);
1855 if( len >= MAX_FMT_STRING )
1856 return "ERROR";
1858 if (len + index >= MAX_FMT_STRING-1)
1860 index = 0;
1863 buf = &string[index];
1864 memcpy( buf, temp_buffer, len+1 );
1866 index += len + 1;
1868 return buf;
1871 GameObject* ChatHandler::GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid,uint32 entry)
1873 if(!m_session)
1874 return NULL;
1876 Player* pl = m_session->GetPlayer();
1878 GameObject* obj = pl->GetMap()->GetGameObject(MAKE_NEW_GUID(lowguid, entry, HIGHGUID_GAMEOBJECT));
1880 if(!obj && objmgr.GetGOData(lowguid)) // guid is DB guid of object
1882 // search near player then
1883 CellPair p(MaNGOS::ComputeCellPair(pl->GetPositionX(), pl->GetPositionY()));
1884 Cell cell(p);
1885 cell.data.Part.reserved = ALL_DISTRICT;
1887 MaNGOS::GameObjectWithDbGUIDCheck go_check(*pl,lowguid);
1888 MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck> checker(pl,obj,go_check);
1890 TypeContainerVisitor<MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > object_checker(checker);
1891 CellLock<GridReadGuard> cell_lock(cell, p);
1892 cell_lock->Visit(cell_lock, object_checker, *pl->GetMap());
1895 return obj;
1898 enum SpellLinkType
1900 SPELL_LINK_SPELL = 0,
1901 SPELL_LINK_TALENT = 1,
1902 SPELL_LINK_ENCHANT = 2,
1903 SPELL_LINK_TRADE = 3,
1904 SPELL_LINK_GLYPH = 4
1907 static char const* const spellKeys[] =
1909 "Hspell", // normal spell
1910 "Htalent", // talent spell
1911 "Henchant", // enchanting recipe spell
1912 "Htrade", // profession/skill spell
1913 "Hglyph", // glyph
1917 uint32 ChatHandler::extractSpellIdFromLink(char* text)
1919 // number or [name] Shift-click form |color|Henchant:recipe_spell_id|h[prof_name: recipe_name]|h|r
1920 // number or [name] Shift-click form |color|Hglyph:glyph_slot_id:glyph_prop_id|h[%s]|h|r
1921 // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
1922 // number or [name] Shift-click form |color|Htalent:talent_id,rank|h[name]|h|r
1923 // number or [name] Shift-click form |color|Htrade:spell_id,skill_id,max_value,cur_value|h[name]|h|r
1924 int type = 0;
1925 char* param1_str = NULL;
1926 char* idS = extractKeyFromLink(text,spellKeys,&type,&param1_str);
1927 if(!idS)
1928 return 0;
1930 uint32 id = (uint32)atol(idS);
1932 switch(type)
1934 case SPELL_LINK_SPELL:
1935 return id;
1936 case SPELL_LINK_TALENT:
1938 // talent
1939 TalentEntry const* talentEntry = sTalentStore.LookupEntry(id);
1940 if(!talentEntry)
1941 return 0;
1943 int32 rank = param1_str ? (uint32)atol(param1_str) : 0;
1944 if(rank >= MAX_TALENT_RANK)
1945 return 0;
1947 if(rank < 0)
1948 rank = 0;
1950 return talentEntry->RankID[rank];
1952 case SPELL_LINK_ENCHANT:
1953 case SPELL_LINK_TRADE:
1954 return id;
1955 case SPELL_LINK_GLYPH:
1957 uint32 glyph_prop_id = param1_str ? (uint32)atol(param1_str) : 0;
1959 GlyphPropertiesEntry const* glyphPropEntry = sGlyphPropertiesStore.LookupEntry(glyph_prop_id);
1960 if(!glyphPropEntry)
1961 return 0;
1963 return glyphPropEntry->SpellId;
1967 // unknown type?
1968 return 0;
1971 GameTele const* ChatHandler::extractGameTeleFromLink(char* text)
1973 // id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r
1974 char* cId = extractKeyFromLink(text,"Htele");
1975 if(!cId)
1976 return false;
1978 // id case (explicit or from shift link)
1979 if(cId[0] >= '0' || cId[0] >= '9')
1980 if(uint32 id = atoi(cId))
1981 return objmgr.GetGameTele(id);
1983 return objmgr.GetGameTele(cId);
1986 enum GuidLinkType
1988 SPELL_LINK_PLAYER = 0, // must be first for selection in not link case
1989 SPELL_LINK_CREATURE = 1,
1990 SPELL_LINK_GAMEOBJECT = 2
1993 static char const* const guidKeys[] =
1995 "Hplayer",
1996 "Hcreature",
1997 "Hgameobject",
2001 uint64 ChatHandler::extractGuidFromLink(char* text)
2003 int type = 0;
2005 // |color|Hcreature:creature_guid|h[name]|h|r
2006 // |color|Hgameobject:go_guid|h[name]|h|r
2007 // |color|Hplayer:name|h[name]|h|r
2008 char* idS = extractKeyFromLink(text,guidKeys,&type);
2009 if(!idS)
2010 return 0;
2012 switch(type)
2014 case SPELL_LINK_PLAYER:
2016 std::string name = idS;
2017 if(!normalizePlayerName(name))
2018 return 0;
2020 if(Player* player = objmgr.GetPlayer(name.c_str()))
2021 return player->GetGUID();
2023 if(uint64 guid = objmgr.GetPlayerGUIDByName(name))
2024 return guid;
2026 return 0;
2028 case SPELL_LINK_CREATURE:
2030 uint32 lowguid = (uint32)atol(idS);
2032 if(CreatureData const* data = objmgr.GetCreatureData(lowguid) )
2033 return MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT);
2034 else
2035 return 0;
2037 case SPELL_LINK_GAMEOBJECT:
2039 uint32 lowguid = (uint32)atol(idS);
2041 if(GameObjectData const* data = objmgr.GetGOData(lowguid) )
2042 return MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_GAMEOBJECT);
2043 else
2044 return 0;
2048 // unknown type?
2049 return 0;
2052 std::string ChatHandler::extractPlayerNameFromLink(char* text)
2054 // |color|Hplayer:name|h[name]|h|r
2055 char* name_str = extractKeyFromLink(text,"Hplayer");
2056 if(!name_str)
2057 return "";
2059 std::string name = name_str;
2060 if(!normalizePlayerName(name))
2061 return "";
2063 return name;
2066 bool ChatHandler::extractPlayerTarget(char* args, Player** player, uint64* player_guid /*=NULL*/,std::string* player_name /*= NULL*/)
2068 if (args && *args)
2070 std::string name = extractPlayerNameFromLink(args);
2071 if (name.empty())
2073 SendSysMessage(LANG_PLAYER_NOT_FOUND);
2074 SetSentErrorMessage(true);
2075 return false;
2078 Player* pl = objmgr.GetPlayer(name.c_str());
2080 // if allowed player pointer
2081 if(player)
2082 *player = pl;
2084 // if need guid value from DB (in name case for check player existence)
2085 uint64 guid = !pl && (player_guid || player_name) ? objmgr.GetPlayerGUIDByName(name) : 0;
2087 // if allowed player guid (if no then only online players allowed)
2088 if(player_guid)
2089 *player_guid = pl ? pl->GetGUID() : guid;
2091 if(player_name)
2092 *player_name = pl || guid ? name : "";
2094 else
2096 Player* pl = getSelectedPlayer();
2097 // if allowed player pointer
2098 if(player)
2099 *player = pl;
2100 // if allowed player guid (if no then only online players allowed)
2101 if(player_guid)
2102 *player_guid = pl ? pl->GetGUID() : 0;
2104 if(player_name)
2105 *player_name = pl ? pl->GetName() : "";
2108 // some from req. data must be provided (note: name is empty if player not exist)
2109 if((!player || !*player) && (!player_guid || !*player_guid) && (!player_name || player_name->empty()))
2111 SendSysMessage(LANG_PLAYER_NOT_FOUND);
2112 SetSentErrorMessage(true);
2113 return false;
2116 return true;
2119 void ChatHandler::extractOptFirstArg(char* args, char** arg1, char** arg2)
2121 char* p1 = strtok(args, " ");
2122 char* p2 = strtok(NULL, " ");
2124 if(!p2)
2126 p2 = p1;
2127 p1 = NULL;
2130 if(arg1)
2131 *arg1 = p1;
2133 if(arg2)
2134 *arg2 = p2;
2137 char* ChatHandler::extractQuotedArg( char* args )
2139 if(!*args)
2140 return NULL;
2142 if(*args=='"')
2143 return strtok(args+1, "\"");
2144 else
2146 char* space = strtok(args, "\"");
2147 if(!space)
2148 return false;
2149 return strtok(NULL, "\"");
2153 bool ChatHandler::needReportToTarget(Player* chr) const
2155 Player* pl = m_session->GetPlayer();
2156 return pl != chr && pl->IsVisibleGloballyFor(chr);
2159 LocaleConstant ChatHandler::GetSessionDbcLocale() const
2161 return m_session->GetSessionDbcLocale();
2164 int ChatHandler::GetSessionDbLocaleIndex() const
2166 return m_session->GetSessionDbLocaleIndex();
2169 const char *CliHandler::GetMangosString(int32 entry) const
2171 return objmgr.GetMangosStringForDBCLocale(entry);
2174 bool CliHandler::isAvailable(ChatCommand const& cmd) const
2176 // skip non-console commands in console case
2177 return cmd.AllowConsole;
2180 void CliHandler::SendSysMessage(const char *str)
2182 m_print(str);
2183 m_print("\r\n");
2186 std::string CliHandler::GetNameLink() const
2188 return GetMangosString(LANG_CONSOLE_COMMAND);
2191 bool CliHandler::needReportToTarget(Player* /*chr*/) const
2193 return true;
2196 LocaleConstant CliHandler::GetSessionDbcLocale() const
2198 return sWorld.GetDefaultDbcLocale();
2201 int CliHandler::GetSessionDbLocaleIndex() const
2203 return objmgr.GetDBCLocaleIndex();